diff mbox series

Revert "blk-cgroup: simplify blkg freeing from initialization failure paths"

Message ID 20230209053523.437927-1-hch@lst.de (mailing list archive)
State New, archived
Headers show
Series Revert "blk-cgroup: simplify blkg freeing from initialization failure paths" | expand

Commit Message

Christoph Hellwig Feb. 9, 2023, 5:35 a.m. UTC
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 <error27@gmail.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 block/blk-cgroup.c | 27 ++++++++++++++++++++-------
 1 file changed, 20 insertions(+), 7 deletions(-)

Comments

Jens Axboe Feb. 9, 2023, 3:12 p.m. UTC | #1
On Thu, 09 Feb 2023 06:35:23 +0100, Christoph Hellwig wrote:
> 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.
> 
> 

Applied, thanks!

[1/1] Revert "blk-cgroup: simplify blkg freeing from initialization failure paths"
      commit: dcb52201435197c56154ff7c8cb139284d254bda

Best regards,
diff mbox series

Patch

diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c
index d8fe607138b96d..935028912e7abf 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);
 }
 
 /*