mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-01-03 19:53:32 +00:00
blk-iocost: fix lockdep warning on blkcg->lock
blkcg->lock depends on q->queue_lock which may depend on another driver lock required in irq context, one example is dm-thin: Chain exists of: &pool->lock#3 --> &q->queue_lock --> &blkcg->lock Possible interrupt unsafe locking scenario: CPU0 CPU1 ---- ---- lock(&blkcg->lock); local_irq_disable(); lock(&pool->lock#3); lock(&q->queue_lock); <Interrupt> lock(&pool->lock#3); Fix the issue by using spin_lock_irq(&blkcg->lock) in ioc_weight_write(). Cc: Tejun Heo <tj@kernel.org> Reported-by: Bruno Goncalves <bgoncalv@redhat.com> Link: https://lore.kernel.org/linux-block/CA+QYu4rzz6079ighEanS3Qq_Dmnczcf45ZoJoHKVLVATTo1e4Q@mail.gmail.com/T/#u Signed-off-by: Ming Lei <ming.lei@redhat.com> Acked-by: Tejun Heo <tj@kernel.org> Link: https://lore.kernel.org/r/20210803070608.1766400-1-ming.lei@redhat.com Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
parent
fb7b9b0231
commit
11431e26c9
@ -3061,19 +3061,19 @@ static ssize_t ioc_weight_write(struct kernfs_open_file *of, char *buf,
|
||||
if (v < CGROUP_WEIGHT_MIN || v > CGROUP_WEIGHT_MAX)
|
||||
return -EINVAL;
|
||||
|
||||
spin_lock(&blkcg->lock);
|
||||
spin_lock_irq(&blkcg->lock);
|
||||
iocc->dfl_weight = v * WEIGHT_ONE;
|
||||
hlist_for_each_entry(blkg, &blkcg->blkg_list, blkcg_node) {
|
||||
struct ioc_gq *iocg = blkg_to_iocg(blkg);
|
||||
|
||||
if (iocg) {
|
||||
spin_lock_irq(&iocg->ioc->lock);
|
||||
spin_lock(&iocg->ioc->lock);
|
||||
ioc_now(iocg->ioc, &now);
|
||||
weight_updated(iocg, &now);
|
||||
spin_unlock_irq(&iocg->ioc->lock);
|
||||
spin_unlock(&iocg->ioc->lock);
|
||||
}
|
||||
}
|
||||
spin_unlock(&blkcg->lock);
|
||||
spin_unlock_irq(&blkcg->lock);
|
||||
|
||||
return nbytes;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user