mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
block: don't enter reclaim under rq_qos_mutex
ioc_qos_write() and the wbt_lat_usec writers take rq_qos_mutex with the queue frozen, blkcg_deactivate_policy() does the same with blkcg_mutex, so nothing holding either may wait for IO. blkg_conf_prep() got GFP_NOIO for the blkg in commit5d726c4dbe, but the radix_tree_preload() right after it, the policy init functions and the GFP_KERNEL fallback in blkcg_activate_policy() can still enter reclaim there. lockdep reports the cycle on the first write to io.max. Use GFP_NOIO for all of them. Fixes:9730763f47("block: correct locking order for protecting blk-wbt parameters") Fixes:5d726c4dbe("blk-cgroup: fix possible deadlock while configuring policy") Cc: Tejun Heo <tj@kernel.org> Signed-off-by: Josef Bacik <josef@toxicpanda.com> Acked-by: Tejun Heo <tj@kernel.org> Link: https://patch.msgid.link/20261028164415.1262013-35-axboe@kernel.dk Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
parent
ac81a07a0b
commit
045cbfc369
|
|
@ -884,7 +884,11 @@ int blkg_conf_prep(struct blkcg *blkcg, const struct blkcg_policy *pol,
|
|||
parent = blkcg_parent(parent);
|
||||
}
|
||||
|
||||
/* Drop locks to do new blkg allocation with GFP_KERNEL. */
|
||||
/*
|
||||
* Drop the spinlock to allocate the new blkg. rq_qos_mutex and
|
||||
* blkcg_mutex stay held, and both are taken with the queue
|
||||
* frozen elsewhere: GFP_NOIO.
|
||||
*/
|
||||
spin_unlock_irq(&q->queue_lock);
|
||||
|
||||
new_blkg = blkg_alloc(pos, disk, GFP_NOIO);
|
||||
|
|
@ -893,7 +897,7 @@ int blkg_conf_prep(struct blkcg *blkcg, const struct blkcg_policy *pol,
|
|||
goto fail_exit;
|
||||
}
|
||||
|
||||
if (radix_tree_preload(GFP_KERNEL)) {
|
||||
if (radix_tree_preload(GFP_NOIO)) {
|
||||
blkg_free(new_blkg);
|
||||
ret = -ENOMEM;
|
||||
goto fail_exit;
|
||||
|
|
@ -1648,7 +1652,8 @@ int blkcg_activate_policy(struct gendisk *disk, const struct blkcg_policy *pol)
|
|||
if (!pd) {
|
||||
/*
|
||||
* GFP_NOWAIT failed. Free the existing one and
|
||||
* prealloc for @blkg w/ GFP_KERNEL.
|
||||
* prealloc for @blkg w/ GFP_NOIO: blkcg_mutex is held,
|
||||
* and a bio based queue has not been frozen above.
|
||||
*/
|
||||
if (pinned_blkg)
|
||||
blkg_put(pinned_blkg);
|
||||
|
|
@ -1660,7 +1665,7 @@ int blkcg_activate_policy(struct gendisk *disk, const struct blkcg_policy *pol)
|
|||
if (pd_prealloc)
|
||||
pol->pd_free_fn(pd_prealloc);
|
||||
pd_prealloc = pol->pd_alloc_fn(disk, blkg->blkcg,
|
||||
GFP_KERNEL);
|
||||
GFP_NOIO);
|
||||
if (pd_prealloc)
|
||||
goto retry;
|
||||
else
|
||||
|
|
|
|||
|
|
@ -2938,11 +2938,12 @@ static int blk_iocost_init(struct gendisk *disk)
|
|||
struct ioc *ioc;
|
||||
int i, cpu, ret;
|
||||
|
||||
ioc = kzalloc_obj(*ioc);
|
||||
/* The caller holds rq_qos_mutex, which is taken with the queue frozen */
|
||||
ioc = kzalloc_obj(*ioc, GFP_NOIO);
|
||||
if (!ioc)
|
||||
return -ENOMEM;
|
||||
|
||||
ioc->pcpu_stat = alloc_percpu(struct ioc_pcpu_stat);
|
||||
ioc->pcpu_stat = alloc_percpu_gfp(struct ioc_pcpu_stat, GFP_NOIO);
|
||||
if (!ioc->pcpu_stat) {
|
||||
kfree(ioc);
|
||||
return -ENOMEM;
|
||||
|
|
|
|||
|
|
@ -761,7 +761,8 @@ static int blk_iolatency_init(struct gendisk *disk)
|
|||
struct blk_iolatency *blkiolat;
|
||||
int ret;
|
||||
|
||||
blkiolat = kzalloc_obj(*blkiolat);
|
||||
/* The caller holds rq_qos_mutex, which is taken with the queue frozen */
|
||||
blkiolat = kzalloc_obj(*blkiolat, GFP_NOIO);
|
||||
if (!blkiolat)
|
||||
return -ENOMEM;
|
||||
|
||||
|
|
|
|||
|
|
@ -1322,7 +1322,8 @@ static int blk_throtl_init(struct gendisk *disk)
|
|||
unsigned int memflags;
|
||||
int ret;
|
||||
|
||||
td = kzalloc_node(sizeof(*td), GFP_KERNEL, q->node);
|
||||
/* The caller holds rq_qos_mutex, which is taken with the queue frozen */
|
||||
td = kzalloc_node(sizeof(*td), GFP_NOIO, q->node);
|
||||
if (!td)
|
||||
return -ENOMEM;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user