All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH V2] block: avoid to call blkg_free() in atomic context
@ 2022-03-23  1:13 Ming Lei
  2022-03-23  1:53 ` Jens Axboe
  0 siblings, 1 reply; 2+ messages in thread
From: Ming Lei @ 2022-03-23  1:13 UTC (permalink / raw)
  To: Jens Axboe; +Cc: linux-block, Ming Lei, Tejun Heo, Christoph Hellwig

blkg_free() may be called in atomic context, either spin lock is held,
or run in rcu callback. Meantime either request queue's release handler
or ->pd_free_fn can sleep.

Fix the issue by scheduling work function for freeing blkcg_gq instance.

[  148.553894] BUG: sleeping function called from invalid context at block/blk-sysfs.c:767
[  148.557381] in_atomic(): 1, irqs_disabled(): 0, non_block: 0, pid: 0, name: swapper/13
[  148.560741] preempt_count: 101, expected: 0
[  148.562577] RCU nest depth: 0, expected: 0
[  148.564379] 1 lock held by swapper/13/0:
[  148.566127]  #0: ffffffff82615f80 (rcu_callback){....}-{0:0}, at: rcu_lock_acquire+0x0/0x1b
[  148.569640] Preemption disabled at:
[  148.569642] [<ffffffff8123f9c3>] ___slab_alloc+0x554/0x661
[  148.573559] CPU: 13 PID: 0 Comm: swapper/13 Kdump: loaded Not tainted 5.17.0_up+ #110
[  148.576834] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.14.0-1.fc33 04/01/2014
[  148.579768] Call Trace:
[  148.580567]  <IRQ>
[  148.581262]  dump_stack_lvl+0x56/0x7c
[  148.582367]  ? ___slab_alloc+0x554/0x661
[  148.583526]  __might_resched+0x1af/0x1c8
[  148.584678]  blk_release_queue+0x24/0x109
[  148.585861]  kobject_cleanup+0xc9/0xfe
[  148.586979]  blkg_free+0x46/0x63
[  148.587962]  rcu_do_batch+0x1c5/0x3db
[  148.589057]  rcu_core+0x14a/0x184
[  148.590065]  __do_softirq+0x14d/0x2c7
[  148.591167]  __irq_exit_rcu+0x7a/0xd4
[  148.592264]  sysvec_apic_timer_interrupt+0x82/0xa5
[  148.593649]  </IRQ>
[  148.594354]  <TASK>
[  148.595058]  asm_sysvec_apic_timer_interrupt+0x12/0x20

Cc: Tejun Heo <tj@kernel.org>
Fixes: 0a9a25ca7843 ("block: let blkcg_gq grab request queue's refcnt")
Reported-by: Christoph Hellwig <hch@lst.de>
Link: https://lore.kernel.org/linux-block/20220322093322.GA27283@lst.de/
Signed-off-by: Ming Lei <ming.lei@redhat.com>
---
V2:
	- fix document
	- move 'blkg' check into blkg_free()
	- make sure no warning in clang build
	- add call trace in commit log as suggested by Tejun

 block/blk-cgroup.c         | 32 ++++++++++++++++++++++----------
 include/linux/blk-cgroup.h |  5 ++++-
 2 files changed, 26 insertions(+), 11 deletions(-)

diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c
index d53b0d69dd73..6ed43fc0e6ab 100644
--- a/block/blk-cgroup.c
+++ b/block/blk-cgroup.c
@@ -65,19 +65,12 @@ static bool blkcg_policy_enabled(struct request_queue *q,
 	return pol && test_bit(pol->plid, q->blkcg_pols);
 }
 
-/**
- * blkg_free - free a blkg
- * @blkg: blkg to free
- *
- * Free @blkg which may be partially allocated.
- */
-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;
 
-	if (!blkg)
-		return;
-
 	for (i = 0; i < BLKCG_MAX_POLS; i++)
 		if (blkg->pd[i])
 			blkcg_policy[i]->pd_free_fn(blkg->pd[i]);
@@ -89,6 +82,25 @@ static void blkg_free(struct blkcg_gq *blkg)
 	kfree(blkg);
 }
 
+/**
+ * blkg_free - free a blkg
+ * @blkg: blkg to free
+ *
+ * Free @blkg which may be partially allocated.
+ */
+static void blkg_free(struct blkcg_gq *blkg)
+{
+	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)
 {
 	struct blkcg_gq *blkg = container_of(rcu, struct blkcg_gq, rcu_head);
diff --git a/include/linux/blk-cgroup.h b/include/linux/blk-cgroup.h
index f2ad8ed8f777..652cd05b0924 100644
--- a/include/linux/blk-cgroup.h
+++ b/include/linux/blk-cgroup.h
@@ -95,7 +95,10 @@ struct blkcg_gq {
 
 	spinlock_t			async_bio_lock;
 	struct bio_list			async_bios;
-	struct work_struct		async_bio_work;
+	union {
+		struct work_struct	async_bio_work;
+		struct work_struct	free_work;
+	};
 
 	atomic_t			use_delay;
 	atomic64_t			delay_nsec;
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH V2] block: avoid to call blkg_free() in atomic context
  2022-03-23  1:13 [PATCH V2] block: avoid to call blkg_free() in atomic context Ming Lei
@ 2022-03-23  1:53 ` Jens Axboe
  0 siblings, 0 replies; 2+ messages in thread
From: Jens Axboe @ 2022-03-23  1:53 UTC (permalink / raw)
  To: Ming Lei; +Cc: linux-block, Tejun Heo, Christoph Hellwig

On Wed, 23 Mar 2022 09:13:08 +0800, Ming Lei wrote:
> blkg_free() may be called in atomic context, either spin lock is held,
> or run in rcu callback. Meantime either request queue's release handler
> or ->pd_free_fn can sleep.
> 
> Fix the issue by scheduling work function for freeing blkcg_gq instance.
> 
> [  148.553894] BUG: sleeping function called from invalid context at block/blk-sysfs.c:767
> [  148.557381] in_atomic(): 1, irqs_disabled(): 0, non_block: 0, pid: 0, name: swapper/13
> [  148.560741] preempt_count: 101, expected: 0
> [  148.562577] RCU nest depth: 0, expected: 0
> [  148.564379] 1 lock held by swapper/13/0:
> [  148.566127]  #0: ffffffff82615f80 (rcu_callback){....}-{0:0}, at: rcu_lock_acquire+0x0/0x1b
> [  148.569640] Preemption disabled at:
> [  148.569642] [<ffffffff8123f9c3>] ___slab_alloc+0x554/0x661
> [  148.573559] CPU: 13 PID: 0 Comm: swapper/13 Kdump: loaded Not tainted 5.17.0_up+ #110
> [  148.576834] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.14.0-1.fc33 04/01/2014
> [  148.579768] Call Trace:
> [  148.580567]  <IRQ>
> [  148.581262]  dump_stack_lvl+0x56/0x7c
> [  148.582367]  ? ___slab_alloc+0x554/0x661
> [  148.583526]  __might_resched+0x1af/0x1c8
> [  148.584678]  blk_release_queue+0x24/0x109
> [  148.585861]  kobject_cleanup+0xc9/0xfe
> [  148.586979]  blkg_free+0x46/0x63
> [  148.587962]  rcu_do_batch+0x1c5/0x3db
> [  148.589057]  rcu_core+0x14a/0x184
> [  148.590065]  __do_softirq+0x14d/0x2c7
> [  148.591167]  __irq_exit_rcu+0x7a/0xd4
> [  148.592264]  sysvec_apic_timer_interrupt+0x82/0xa5
> [  148.593649]  </IRQ>
> [  148.594354]  <TASK>
> [  148.595058]  asm_sysvec_apic_timer_interrupt+0x12/0x20
> 
> [...]

Applied, thanks!

[1/1] block: avoid to call blkg_free() in atomic context
      commit: d578c770c85233af592e54537f93f3831bde7e9a

Best regards,
-- 
Jens Axboe



^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2022-03-23  1:53 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-03-23  1:13 [PATCH V2] block: avoid to call blkg_free() in atomic context Ming Lei
2022-03-23  1:53 ` Jens Axboe

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.