From dcb52201435197c56154ff7c8cb139284d254bda Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Thu, 9 Feb 2023 06:35:23 +0100 Subject: Revert "blk-cgroup: simplify blkg freeing from initialization failure paths" It turns out this was too soon. blkg_conf_prep does to funky locking games with the queue lock for this to work properly. This reverts commit 27b642b07a4a5eb44dffa94a5171ce468bdc46f9. Reported-by: Dan Carpenter Signed-off-by: Christoph Hellwig Link: https://lore.kernel.org/r/20230209053523.437927-1-hch@lst.de Signed-off-by: Jens Axboe --- block/blk-cgroup.c | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) (limited to 'block/blk-cgroup.c') diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c index d8fe607138b9..935028912e7a 100644 --- a/block/blk-cgroup.c +++ b/block/blk-cgroup.c @@ -114,8 +114,10 @@ static bool blkcg_policy_enabled(struct gendisk *disk, return pol && test_bit(pol->plid, disk->blkcg_pols); } -static void blkg_free(struct blkcg_gq *blkg) +static void blkg_free_workfn(struct work_struct *work) { + struct blkcg_gq *blkg = container_of(work, struct blkcg_gq, + free_work); int i; /* @@ -140,9 +142,23 @@ static void blkg_free(struct blkcg_gq *blkg) kfree(blkg); } -static void blkg_free_workfn(struct work_struct *work) +/** + * blkg_free - free a blkg + * @blkg: blkg to free + * + * Free @blkg which may be partially allocated. + */ +static void blkg_free(struct blkcg_gq *blkg) { - blkg_free(container_of(work, struct blkcg_gq, free_work)); + if (!blkg) + return; + + /* + * Both ->pd_free_fn() and request queue's release handler may + * sleep, so free us by scheduling one work func + */ + INIT_WORK(&blkg->free_work, blkg_free_workfn); + schedule_work(&blkg->free_work); } static void __blkg_release(struct rcu_head *rcu) @@ -153,10 +169,7 @@ static void __blkg_release(struct rcu_head *rcu) /* release the blkcg and parent blkg refs this blkg has been holding */ css_put(&blkg->blkcg->css); - - /* ->pd_free_fn() may sleep, so free from a work queue */ - INIT_WORK(&blkg->free_work, blkg_free_workfn); - schedule_work(&blkg->free_work); + blkg_free(blkg); } /* -- cgit v1.2.3