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 commit 5d726c4dbe, 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:
Josef Bacik 2026-10-28 10:41:37 -06:00 committed by Jens Axboe
parent ac81a07a0b
commit 045cbfc369
4 changed files with 16 additions and 8 deletions

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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;