Skip to content

Commit 6d25099

Browse files
krisman-at-collaboragregkh
authored andcommitted
blk-cgroup: Pre-allocate tree node on blkg_conf_prep
[ Upstream commit f255c19 ] Similarly to commit 457e490 ("blkcg: allocate struct blkcg_gq outside request queue spinlock"), blkg_create can also trigger occasional -ENOMEM failures at the radix insertion because any allocation inside blkg_create has to be non-blocking, making it more likely to fail. This causes trouble for userspace tools trying to configure io weights who need to deal with this condition. This patch reduces the occurrence of -ENOMEMs on this path by preloading the radix tree element on a GFP_KERNEL context, such that we guarantee the later non-blocking insertion won't fail. A similar solution exists in blkcg_init_queue for the same situation. Acked-by: Tejun Heo <[email protected]> Signed-off-by: Gabriel Krisman Bertazi <[email protected]> Signed-off-by: Jens Axboe <[email protected]> Signed-off-by: Sasha Levin <[email protected]>
1 parent 89c94a3 commit 6d25099

File tree

1 file changed

+12
-2
lines changed

1 file changed

+12
-2
lines changed

block/blk-cgroup.c

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -648,14 +648,20 @@ int blkg_conf_prep(struct blkcg *blkcg, const struct blkcg_policy *pol,
648648
goto fail;
649649
}
650650

651+
if (radix_tree_preload(GFP_KERNEL)) {
652+
blkg_free(new_blkg);
653+
ret = -ENOMEM;
654+
goto fail;
655+
}
656+
651657
rcu_read_lock();
652658
spin_lock_irq(&q->queue_lock);
653659

654660
blkg = blkg_lookup_check(pos, pol, q);
655661
if (IS_ERR(blkg)) {
656662
ret = PTR_ERR(blkg);
657663
blkg_free(new_blkg);
658-
goto fail_unlock;
664+
goto fail_preloaded;
659665
}
660666

661667
if (blkg) {
@@ -664,10 +670,12 @@ int blkg_conf_prep(struct blkcg *blkcg, const struct blkcg_policy *pol,
664670
blkg = blkg_create(pos, q, new_blkg);
665671
if (IS_ERR(blkg)) {
666672
ret = PTR_ERR(blkg);
667-
goto fail_unlock;
673+
goto fail_preloaded;
668674
}
669675
}
670676

677+
radix_tree_preload_end();
678+
671679
if (pos == blkcg)
672680
goto success;
673681
}
@@ -677,6 +685,8 @@ int blkg_conf_prep(struct blkcg *blkcg, const struct blkcg_policy *pol,
677685
ctx->body = input;
678686
return 0;
679687

688+
fail_preloaded:
689+
radix_tree_preload_end();
680690
fail_unlock:
681691
spin_unlock_irq(&q->queue_lock);
682692
rcu_read_unlock();

0 commit comments

Comments
 (0)