* [PATCH v2 1/6] block: Avoid that blk_exit_rl() triggers a use-after-free
[not found] <20170531214350.31157-1-bart.vanassche@sandisk.com>
@ 2017-05-31 21:43 ` Bart Van Assche
2017-06-01 19:09 ` Jens Axboe
2017-06-13 17:54 ` Ross Zwisler
0 siblings, 2 replies; 7+ messages in thread
From: Bart Van Assche @ 2017-05-31 21:43 UTC (permalink / raw)
To: Jens Axboe
Cc: linux-block, Christoph Hellwig, Bart Van Assche, Jan Kara, stable
Since the introduction of .init_rq_fn() and .exit_rq_fn() it is
essential that the memory allocated for struct request_queue
stays around until all blk_exit_rl() calls have finished. Hence
make blk_init_rl() take a reference on struct request_queue.
This patch fixes the following crash:
general protection fault: 0000 [#2] SMP
CPU: 3 PID: 28 Comm: ksoftirqd/3 Tainted: G D 4.12.0-rc2-dbg+ #2
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.0.0-prebuilt.qemu-project.org 04/01/2014
task: ffff88013a108040 task.stack: ffffc9000071c000
RIP: 0010:free_request_size+0x1a/0x30
RSP: 0018:ffffc9000071fd38 EFLAGS: 00010202
RAX: 6b6b6b6b6b6b6b6b RBX: ffff880067362a88 RCX: 0000000000000003
RDX: ffff880067464178 RSI: ffff880067362a88 RDI: ffff880135ea4418
RBP: ffffc9000071fd40 R08: 0000000000000000 R09: 0000000100180009
R10: ffffc9000071fd38 R11: ffffffff81110800 R12: ffff88006752d3d8
R13: ffff88006752d3d8 R14: ffff88013a108040 R15: 000000000000000a
FS: 0000000000000000(0000) GS:ffff88013fd80000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007fa8ec1edb00 CR3: 0000000138ee8000 CR4: 00000000001406e0
Call Trace:
mempool_destroy.part.10+0x21/0x40
mempool_destroy+0xe/0x10
blk_exit_rl+0x12/0x20
blkg_free+0x4d/0xa0
__blkg_release_rcu+0x59/0x170
rcu_process_callbacks+0x260/0x4e0
__do_softirq+0x116/0x250
smpboot_thread_fn+0x123/0x1e0
kthread+0x109/0x140
ret_from_fork+0x31/0x40
Fixes: commit e9c787e65c0c ("scsi: allocate scsi_cmnd structures as part of struct request")
Signed-off-by: Bart Van Assche <bart.vanassche@sandisk.com>
Acked-by: Tejun Heo <tj@kernel.org>
Reviewed-by: Hannes Reinecke <hare@suse.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Cc: Jan Kara <jack@suse.cz>
Cc: <stable@vger.kernel.org> # v4.11+
---
block/blk-cgroup.c | 2 +-
block/blk-core.c | 10 ++++++++--
block/blk-sysfs.c | 2 +-
block/blk.h | 2 +-
4 files changed, 11 insertions(+), 5 deletions(-)
diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c
index 7c2947128f58..0480892e97e5 100644
--- a/block/blk-cgroup.c
+++ b/block/blk-cgroup.c
@@ -74,7 +74,7 @@ static void blkg_free(struct blkcg_gq *blkg)
blkcg_policy[i]->pd_free_fn(blkg->pd[i]);
if (blkg->blkcg != &blkcg_root)
- blk_exit_rl(&blkg->rl);
+ blk_exit_rl(blkg->q, &blkg->rl);
blkg_rwstat_exit(&blkg->stat_ios);
blkg_rwstat_exit(&blkg->stat_bytes);
diff --git a/block/blk-core.c b/block/blk-core.c
index c7068520794b..a7421b772d0e 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -648,13 +648,19 @@ int blk_init_rl(struct request_list *rl, struct request_queue *q,
if (!rl->rq_pool)
return -ENOMEM;
+ if (rl != &q->root_rl)
+ WARN_ON_ONCE(!blk_get_queue(q));
+
return 0;
}
-void blk_exit_rl(struct request_list *rl)
+void blk_exit_rl(struct request_queue *q, struct request_list *rl)
{
- if (rl->rq_pool)
+ if (rl->rq_pool) {
mempool_destroy(rl->rq_pool);
+ if (rl != &q->root_rl)
+ blk_put_queue(q);
+ }
}
struct request_queue *blk_alloc_queue(gfp_t gfp_mask)
diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c
index 712b018e9f54..283da7fbe034 100644
--- a/block/blk-sysfs.c
+++ b/block/blk-sysfs.c
@@ -809,7 +809,7 @@ static void blk_release_queue(struct kobject *kobj)
blk_free_queue_stats(q->stats);
- blk_exit_rl(&q->root_rl);
+ blk_exit_rl(q, &q->root_rl);
if (q->queue_tags)
__blk_queue_free_tags(q);
diff --git a/block/blk.h b/block/blk.h
index 2ed70228e44f..83c8e1100525 100644
--- a/block/blk.h
+++ b/block/blk.h
@@ -59,7 +59,7 @@ void blk_free_flush_queue(struct blk_flush_queue *q);
int blk_init_rl(struct request_list *rl, struct request_queue *q,
gfp_t gfp_mask);
-void blk_exit_rl(struct request_list *rl);
+void blk_exit_rl(struct request_queue *q, struct request_list *rl);
void blk_rq_bio_prep(struct request_queue *q, struct request *rq,
struct bio *bio);
void blk_queue_bypass_start(struct request_queue *q);
--
2.12.2
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH v2 1/6] block: Avoid that blk_exit_rl() triggers a use-after-free
2017-05-31 21:43 ` [PATCH v2 1/6] block: Avoid that blk_exit_rl() triggers a use-after-free Bart Van Assche
@ 2017-06-01 19:09 ` Jens Axboe
2017-06-13 17:54 ` Ross Zwisler
1 sibling, 0 replies; 7+ messages in thread
From: Jens Axboe @ 2017-06-01 19:09 UTC (permalink / raw)
To: Bart Van Assche; +Cc: linux-block, Christoph Hellwig, Jan Kara, stable
On 05/31/2017 02:43 PM, Bart Van Assche wrote:
> Since the introduction of .init_rq_fn() and .exit_rq_fn() it is
> essential that the memory allocated for struct request_queue
> stays around until all blk_exit_rl() calls have finished. Hence
> make blk_init_rl() take a reference on struct request_queue.
>
> This patch fixes the following crash:
>
> general protection fault: 0000 [#2] SMP
> CPU: 3 PID: 28 Comm: ksoftirqd/3 Tainted: G D 4.12.0-rc2-dbg+ #2
> Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.0.0-prebuilt.qemu-project.org 04/01/2014
> task: ffff88013a108040 task.stack: ffffc9000071c000
> RIP: 0010:free_request_size+0x1a/0x30
> RSP: 0018:ffffc9000071fd38 EFLAGS: 00010202
> RAX: 6b6b6b6b6b6b6b6b RBX: ffff880067362a88 RCX: 0000000000000003
> RDX: ffff880067464178 RSI: ffff880067362a88 RDI: ffff880135ea4418
> RBP: ffffc9000071fd40 R08: 0000000000000000 R09: 0000000100180009
> R10: ffffc9000071fd38 R11: ffffffff81110800 R12: ffff88006752d3d8
> R13: ffff88006752d3d8 R14: ffff88013a108040 R15: 000000000000000a
> FS: 0000000000000000(0000) GS:ffff88013fd80000(0000) knlGS:0000000000000000
> CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> CR2: 00007fa8ec1edb00 CR3: 0000000138ee8000 CR4: 00000000001406e0
> Call Trace:
> mempool_destroy.part.10+0x21/0x40
> mempool_destroy+0xe/0x10
> blk_exit_rl+0x12/0x20
> blkg_free+0x4d/0xa0
> __blkg_release_rcu+0x59/0x170
> rcu_process_callbacks+0x260/0x4e0
> __do_softirq+0x116/0x250
> smpboot_thread_fn+0x123/0x1e0
> kthread+0x109/0x140
> ret_from_fork+0x31/0x40
>
> Fixes: commit e9c787e65c0c ("scsi: allocate scsi_cmnd structures as part of struct request")
> Signed-off-by: Bart Van Assche <bart.vanassche@sandisk.com>
> Acked-by: Tejun Heo <tj@kernel.org>
> Reviewed-by: Hannes Reinecke <hare@suse.com>
> Reviewed-by: Christoph Hellwig <hch@lst.de>
> Cc: Jan Kara <jack@suse.cz>
> Cc: <stable@vger.kernel.org> # v4.11+
Added this one for 4.12.
--
Jens Axboe
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v2 1/6] block: Avoid that blk_exit_rl() triggers a use-after-free
2017-05-31 21:43 ` [PATCH v2 1/6] block: Avoid that blk_exit_rl() triggers a use-after-free Bart Van Assche
2017-06-01 19:09 ` Jens Axboe
@ 2017-06-13 17:54 ` Ross Zwisler
2017-06-14 15:19 ` Bart Van Assche
1 sibling, 1 reply; 7+ messages in thread
From: Ross Zwisler @ 2017-06-13 17:54 UTC (permalink / raw)
To: Bart Van Assche
Cc: Jens Axboe, linux-block, Christoph Hellwig, Jan Kara, stable
On Wed, May 31, 2017 at 3:43 PM, Bart Van Assche
<bart.vanassche@sandisk.com> wrote:
> Since the introduction of .init_rq_fn() and .exit_rq_fn() it is
> essential that the memory allocated for struct request_queue
> stays around until all blk_exit_rl() calls have finished. Hence
> make blk_init_rl() take a reference on struct request_queue.
>
> This patch fixes the following crash:
>
> general protection fault: 0000 [#2] SMP
> CPU: 3 PID: 28 Comm: ksoftirqd/3 Tainted: G D 4.12.0-rc2-dbg+ #2
> Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.0.0-prebuilt.qemu-project.org 04/01/2014
> task: ffff88013a108040 task.stack: ffffc9000071c000
> RIP: 0010:free_request_size+0x1a/0x30
> RSP: 0018:ffffc9000071fd38 EFLAGS: 00010202
> RAX: 6b6b6b6b6b6b6b6b RBX: ffff880067362a88 RCX: 0000000000000003
> RDX: ffff880067464178 RSI: ffff880067362a88 RDI: ffff880135ea4418
> RBP: ffffc9000071fd40 R08: 0000000000000000 R09: 0000000100180009
> R10: ffffc9000071fd38 R11: ffffffff81110800 R12: ffff88006752d3d8
> R13: ffff88006752d3d8 R14: ffff88013a108040 R15: 000000000000000a
> FS: 0000000000000000(0000) GS:ffff88013fd80000(0000) knlGS:0000000000000000
> CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> CR2: 00007fa8ec1edb00 CR3: 0000000138ee8000 CR4: 00000000001406e0
> Call Trace:
> mempool_destroy.part.10+0x21/0x40
> mempool_destroy+0xe/0x10
> blk_exit_rl+0x12/0x20
> blkg_free+0x4d/0xa0
> __blkg_release_rcu+0x59/0x170
> rcu_process_callbacks+0x260/0x4e0
> __do_softirq+0x116/0x250
> smpboot_thread_fn+0x123/0x1e0
> kthread+0x109/0x140
> ret_from_fork+0x31/0x40
>
> Fixes: commit e9c787e65c0c ("scsi: allocate scsi_cmnd structures as part of struct request")
> Signed-off-by: Bart Van Assche <bart.vanassche@sandisk.com>
> Acked-by: Tejun Heo <tj@kernel.org>
> Reviewed-by: Hannes Reinecke <hare@suse.com>
> Reviewed-by: Christoph Hellwig <hch@lst.de>
> Cc: Jan Kara <jack@suse.cz>
> Cc: <stable@vger.kernel.org> # v4.11+
> ---
> block/blk-cgroup.c | 2 +-
> block/blk-core.c | 10 ++++++++--
> block/blk-sysfs.c | 2 +-
> block/blk.h | 2 +-
> 4 files changed, 11 insertions(+), 5 deletions(-)
>
> diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c
> index 7c2947128f58..0480892e97e5 100644
> --- a/block/blk-cgroup.c
> +++ b/block/blk-cgroup.c
> @@ -74,7 +74,7 @@ static void blkg_free(struct blkcg_gq *blkg)
> blkcg_policy[i]->pd_free_fn(blkg->pd[i]);
>
> if (blkg->blkcg != &blkcg_root)
> - blk_exit_rl(&blkg->rl);
> + blk_exit_rl(blkg->q, &blkg->rl);
>
> blkg_rwstat_exit(&blkg->stat_ios);
> blkg_rwstat_exit(&blkg->stat_bytes);
> diff --git a/block/blk-core.c b/block/blk-core.c
> index c7068520794b..a7421b772d0e 100644
> --- a/block/blk-core.c
> +++ b/block/blk-core.c
> @@ -648,13 +648,19 @@ int blk_init_rl(struct request_list *rl, struct request_queue *q,
> if (!rl->rq_pool)
> return -ENOMEM;
>
> + if (rl != &q->root_rl)
> + WARN_ON_ONCE(!blk_get_queue(q));
> +
> return 0;
> }
>
> -void blk_exit_rl(struct request_list *rl)
> +void blk_exit_rl(struct request_queue *q, struct request_list *rl)
> {
> - if (rl->rq_pool)
> + if (rl->rq_pool) {
> mempool_destroy(rl->rq_pool);
> + if (rl != &q->root_rl)
> + blk_put_queue(q);
> + }
> }
This commit is causing the following kernel BUG for me when I shut
down my systems:
BUG: sleeping function called from invalid context at kernel/workqueue.c:2790
in_atomic(): 1, irqs_disabled(): 0, pid: 41, name: rcuop/3
1 lock held by rcuop/3/41:
#0: (rcu_callback){......}, at: [<ffffffff8111f9a2>]
rcu_nocb_kthread+0x282/0x500
Preemption disabled at:
[<ffffffff8111f9b3>] rcu_nocb_kthread+0x293/0x500
CPU: 2 PID: 41 Comm: rcuop/3 Not tainted 4.12.0-rc5 #1
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS
1.9.3-1.fc25 04/01/2014
Call Trace:
dump_stack+0x86/0xcf
___might_sleep+0x174/0x260
__might_sleep+0x4a/0x80
flush_work+0x7e/0x2e0
? blk_throtl_update_limit_valid.isra.14+0x192/0x240
? blkg_destroy_all+0x63/0xc0
? __cancel_work_timer+0x123/0x1c0
__cancel_work_timer+0x143/0x1c0
? blkcg_exit_queue+0x2d/0x40
? _raw_spin_unlock_irq+0x2c/0x60
cancel_work_sync+0x10/0x20
blk_throtl_exit+0x25/0x60
blkcg_exit_queue+0x35/0x40
blk_release_queue+0x42/0x130
kobject_put+0xa9/0x190
kauditd_printk_skb: 60 callbacks suppressed
audit: type=1131 audit(1497375715.762:263): pid=1 uid=0
auid=4294967295 ses=4294967295 subj=system_u:system_r:init_t:s0
msg='unit=auditd comm="systemd" exe="/usr/lib/systemd/systemd"
hostname=? addr=? terminal=? res=success'
audit: type=1131 audit(1497375715.765:264): pid=1 uid=0
auid=4294967295 ses=4294967295 subj=system_u:system_r:init_t:s0
msg='unit=systemd-tmpfiles-setup comm="systemd"
exe="/usr/lib/systemd/systemd" hostname=? addr=? terminal=?
res=success'
audit: type=1131 audit(1497375715.767:265): pid=1 uid=0
auid=4294967295 ses=4294967295 subj=system_u:system_r:init_t:s0
msg='unit=fedora-import-state comm="systemd"
exe="/usr/lib/systemd/systemd" hostname=? addr=? terminal=?
res=success'
blk_exit_rl+0x35/0x40
blkg_free+0x56/0xb0
__blkg_release_rcu+0x5e/0x190
? blkcg_css_offline+0xa0/0xa0
rcu_nocb_kthread+0x33d/0x500
kthread+0x117/0x150
? rcu_all_qs+0xe0/0xe0
? kthread_create_on_node+0x70/0x70
ret_from_fork+0x2a/0x40
BUG: scheduling while atomic: rcuop/3/41/0x00000201
1 lock held by rcuop/3/41:
#0: (rcu_callback){......}, at: [<ffffffff8111f9a2>]
rcu_nocb_kthread+0x282/0x500
Modules linked in: nd_pmem nd_btt dax_pmem device_dax nfit libnvdimm
Preemption disabled at:
[<ffffffff8111f9b3>] rcu_nocb_kthread+0x293/0x500
CPU: 2 PID: 41 Comm: rcuop/3 Tainted: G W 4.12.0-rc5 #1
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS
1.9.3-1.fc25 04/01/2014
Call Trace:
dump_stack+0x86/0xcf
? rcu_nocb_kthread+0x293/0x500
__schedule_bug+0x88/0xe0
__schedule+0x77a/0xb10
? wait_for_completion+0x10b/0x1a0
schedule+0x40/0x90
schedule_timeout+0x2ac/0x510
? wait_for_completion+0x122/0x1a0
? wait_for_completion+0x122/0x1a0
? _raw_spin_unlock_irq+0x2c/0x60
? wait_for_completion+0x10b/0x1a0
? wait_for_completion+0x10b/0x1a0
wait_for_completion+0x12a/0x1a0
? wait_for_completion+0x12a/0x1a0
? wake_up_q+0x80/0x80
__wait_rcu_gp+0xca/0x100
synchronize_rcu.part.67+0x41/0x60
? rcu_barrier+0x20/0x20
? trace_raw_output_rcu_utilization+0x50/0x50
? wait_for_completion+0x47/0x1a0
synchronize_rcu+0x2c/0xa0
blk_queue_bypass_start+0x7f/0xa0
blkcg_deactivate_policy+0x110/0x120
blk_throtl_exit+0x34/0x60
blkcg_exit_queue+0x35/0x40
blk_release_queue+0x42/0x130
kobject_put+0xa9/0x190
blk_exit_rl+0x35/0x40
blkg_free+0x56/0xb0
__blkg_release_rcu+0x5e/0x190
? blkcg_css_offline+0xa0/0xa0
rcu_nocb_kthread+0x33d/0x500
kthread+0x117/0x150
? rcu_all_qs+0xe0/0xe0
? kthread_create_on_node+0x70/0x70
ret_from_fork+0x2a/0x40
NOHZ: local_softirq_pending 202
DEBUG_LOCKS_WARN_ON(val > preempt_count())
------------[ cut here ]------------
WARNING: CPU: 2 PID: 41 at kernel/sched/core.c:3202
preempt_count_sub+0x5f/0xa0
Modules linked in: nd_pmem nd_btt dax_pmem device_dax nfit libnvdimm
CPU: 2 PID: 41 Comm: rcuop/3 Tainted: G W 4.12.0-rc5 #1
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS
1.9.3-1.fc25 04/01/2014
task: ffff880210790000 task.stack: ffffc90000dbc000
RIP: 0010:preempt_count_sub+0x5f/0xa0
RSP: 0000:ffffc90000dbfe58 EFLAGS: 00010082
RAX: 000000000000002a RBX: 0000000000000200 RCX: 0000000000000001
RDX: 0000000000000000 RSI: 0000000000000001 RDI: ffffffff8110dad7
RBP: ffffc90000dbfe58 R08: 0000000000000000 R09: 0000000000000001
R10: 0000000000000000 R11: 0000000000000000 R12: ffffffff8111fa08
R13: 0000000000000026 R14: ffff880210790000 R15: ffff88020880c4c0
FS: 0000000000000000(0000) GS:ffff880211400000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 000055c7110f4148 CR3: 000000020c1bc000 CR4: 00000000000006e0
Call Trace:
__local_bh_enable_ip+0x52/0xb0
rcu_nocb_kthread+0x2fe/0x500
kthread+0x117/0x150
? rcu_all_qs+0xe0/0xe0
? kthread_create_on_node+0x70/0x70
ret_from_fork+0x2a/0x40
Code: 37 f4 7e 5d c3 e8 52 d2 56 00 85 c0 74 f5 8b 15 b8 2b 51 02 85
d2 75 eb 48 c7 c6 9a f9 ef 81 48 c7 c7 c2 87 ee 81 e8 e8 34 12 00 <0f>
ff 5d c3 84 d2 75 c7 e8 24 d2 56 00 85 c0 74 c7 8b 05 8a 2b
---[ end trace f7877221a24ce5d5 ]---
I think essentially the problem is that blk_exit_rl() is called from
atomic context, and the work done by the newly added blk_put_queue()
call can sleep.
This is reproducible 100% of the time by running a single xfstest
(generic/085 is what I've been using) against a pair simulated of PMEM
block devices (without DAX), and by shutting down or rebooting the
system.
Sometimes it is relatively harmless, and you just get a splat during shutdown.
Sometimes the shutdown stops making forward progress and the machine
fails to reboot.
I am able to reproduce this consistently with v4.12-rc5, and reverting
this one commit removes the behavior.
- Ross
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v2 1/6] block: Avoid that blk_exit_rl() triggers a use-after-free
2017-06-13 17:54 ` Ross Zwisler
@ 2017-06-14 15:19 ` Bart Van Assche
2017-06-14 18:04 ` Ross Zwisler
2017-06-14 19:28 ` Jens Axboe
0 siblings, 2 replies; 7+ messages in thread
From: Bart Van Assche @ 2017-06-14 15:19 UTC (permalink / raw)
To: Ross Zwisler; +Cc: Jens Axboe, linux-block, Christoph Hellwig, Jan Kara, stable
On 06/13/17 10:54, Ross Zwisler wrote:
> This commit is causing the following kernel BUG for me when I shut
> down my systems:
>
> BUG: sleeping function called from invalid context at kernel/workqueue.c:2790
> in_atomic(): 1, irqs_disabled(): 0, pid: 41, name: rcuop/3
Thanks Ross for the testing and for the report. Can you check whether
the patch below is sufficient to fix this?
Subject: [PATCH] block: Fix a blk_exit_rl() regression
Avoid that the following complaint is reported:
BUG: sleeping function called from invalid context at kernel/workqueue.c:2790
in_atomic(): 1, irqs_disabled(): 0, pid: 41, name: rcuop/3
1 lock held by rcuop/3/41:
#0: (rcu_callback){......}, at: [<ffffffff8111f9a2>] rcu_nocb_kthread+0x282/0x500
Call Trace:
dump_stack+0x86/0xcf
___might_sleep+0x174/0x260
__might_sleep+0x4a/0x80
flush_work+0x7e/0x2e0
__cancel_work_timer+0x143/0x1c0
cancel_work_sync+0x10/0x20
blk_throtl_exit+0x25/0x60
blkcg_exit_queue+0x35/0x40
blk_release_queue+0x42/0x130
kobject_put+0xa9/0x190
Reported-by: Ross Zwisler <zwisler@gmail.com>
Fixes: commit b425e5049258 ("block: Avoid that blk_exit_rl() triggers a use-after-free")
Signed-off-by: Bart Van Assche <bart.vanassche@sandisk.com>
Cc: Ross Zwisler <zwisler@gmail.com>
---
block/blk-sysfs.c | 34 ++++++++++++++++++++++------------
include/linux/blkdev.h | 2 ++
2 files changed, 24 insertions(+), 12 deletions(-)
diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c
index 283da7fbe034..27aceab1cc31 100644
--- a/block/blk-sysfs.c
+++ b/block/blk-sysfs.c
@@ -777,24 +777,25 @@ static void blk_free_queue_rcu(struct rcu_head *rcu_head)
}
/**
- * blk_release_queue: - release a &struct request_queue when it is no longer needed
- * @kobj: the kobj belonging to the request queue to be released
+ * __blk_release_queue - release a request queue when it is no longer needed
+ * @work: pointer to the release_work member of the request queue to be released
*
* Description:
- * blk_release_queue is the pair to blk_init_queue() or
- * blk_queue_make_request(). It should be called when a request queue is
- * being released; typically when a block device is being de-registered.
- * Currently, its primary task it to free all the &struct request
- * structures that were allocated to the queue and the queue itself.
+ * blk_release_queue is the counterpart of blk_init_queue(). It should be
+ * called when a request queue is being released; typically when a block
+ * device is being de-registered. Its primary task it to free the queue
+ * itself.
*
- * Note:
+ * Notes:
* The low level driver must have finished any outstanding requests first
* via blk_cleanup_queue().
- **/
-static void blk_release_queue(struct kobject *kobj)
+ *
+ * Although blk_release_queue() may be called with preemption disabled,
+ * __blk_release_queue() may sleep.
+ */
+static void __blk_release_queue(struct work_struct *work)
{
- struct request_queue *q =
- container_of(kobj, struct request_queue, kobj);
+ struct request_queue *q = container_of(work, typeof(*q), release_work);
if (test_bit(QUEUE_FLAG_POLL_STATS, &q->queue_flags))
blk_stat_remove_callback(q, q->poll_cb);
@@ -834,6 +835,15 @@ static void blk_release_queue(struct kobject *kobj)
call_rcu(&q->rcu_head, blk_free_queue_rcu);
}
+static void blk_release_queue(struct kobject *kobj)
+{
+ struct request_queue *q =
+ container_of(kobj, struct request_queue, kobj);
+
+ INIT_WORK(&q->release_work, __blk_release_queue);
+ schedule_work(&q->release_work);
+}
+
static const struct sysfs_ops queue_sysfs_ops = {
.show = queue_attr_show,
.store = queue_attr_store,
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index cc75407881e4..07a26414fdfc 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -590,6 +590,8 @@ struct request_queue {
size_t cmd_size;
void *rq_alloc_data;
+
+ struct work_struct release_work;
};
#define QUEUE_FLAG_QUEUED 1 /* uses generic tag queueing */
--
2.12.2
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH v2 1/6] block: Avoid that blk_exit_rl() triggers a use-after-free
2017-06-14 15:19 ` Bart Van Assche
@ 2017-06-14 18:04 ` Ross Zwisler
2017-06-14 19:28 ` Jens Axboe
1 sibling, 0 replies; 7+ messages in thread
From: Ross Zwisler @ 2017-06-14 18:04 UTC (permalink / raw)
To: Bart Van Assche
Cc: Jens Axboe, linux-block, Christoph Hellwig, Jan Kara, stable
On Wed, Jun 14, 2017 at 9:19 AM, Bart Van Assche
<bart.vanassche@sandisk.com> wrote:
> On 06/13/17 10:54, Ross Zwisler wrote:
>> This commit is causing the following kernel BUG for me when I shut
>> down my systems:
>>
>> BUG: sleeping function called from invalid context at kernel/workqueue.c:2790
>> in_atomic(): 1, irqs_disabled(): 0, pid: 41, name: rcuop/3
>
> Thanks Ross for the testing and for the report. Can you check whether
> the patch below is sufficient to fix this?
>
>
> Subject: [PATCH] block: Fix a blk_exit_rl() regression
>
> Avoid that the following complaint is reported:
>
> BUG: sleeping function called from invalid context at kernel/workqueue.c:2790
> in_atomic(): 1, irqs_disabled(): 0, pid: 41, name: rcuop/3
> 1 lock held by rcuop/3/41:
> #0: (rcu_callback){......}, at: [<ffffffff8111f9a2>] rcu_nocb_kthread+0x282/0x500
> Call Trace:
> dump_stack+0x86/0xcf
> ___might_sleep+0x174/0x260
> __might_sleep+0x4a/0x80
> flush_work+0x7e/0x2e0
> __cancel_work_timer+0x143/0x1c0
> cancel_work_sync+0x10/0x20
> blk_throtl_exit+0x25/0x60
> blkcg_exit_queue+0x35/0x40
> blk_release_queue+0x42/0x130
> kobject_put+0xa9/0x190
>
> Reported-by: Ross Zwisler <zwisler@gmail.com>
> Fixes: commit b425e5049258 ("block: Avoid that blk_exit_rl() triggers a use-after-free")
> Signed-off-by: Bart Van Assche <bart.vanassche@sandisk.com>
> Cc: Ross Zwisler <zwisler@gmail.com>
Yep, this solves the issue for me, thanks!
Tested-by: Ross Zwisler <ross.zwisler@linux.intel.com>
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v2 1/6] block: Avoid that blk_exit_rl() triggers a use-after-free
2017-06-14 15:19 ` Bart Van Assche
2017-06-14 18:04 ` Ross Zwisler
@ 2017-06-14 19:28 ` Jens Axboe
2017-06-14 19:32 ` Bart Van Assche
1 sibling, 1 reply; 7+ messages in thread
From: Jens Axboe @ 2017-06-14 19:28 UTC (permalink / raw)
To: Bart Van Assche, Ross Zwisler
Cc: linux-block, Christoph Hellwig, Jan Kara, stable
On 06/14/2017 09:19 AM, Bart Van Assche wrote:
> Subject: [PATCH] block: Fix a blk_exit_rl() regression
>
> Avoid that the following complaint is reported:
>
> BUG: sleeping function called from invalid context at kernel/workqueue.c:2790
> in_atomic(): 1, irqs_disabled(): 0, pid: 41, name: rcuop/3
> 1 lock held by rcuop/3/41:
> #0: (rcu_callback){......}, at: [<ffffffff8111f9a2>] rcu_nocb_kthread+0x282/0x500
> Call Trace:
> dump_stack+0x86/0xcf
> ___might_sleep+0x174/0x260
> __might_sleep+0x4a/0x80
> flush_work+0x7e/0x2e0
> __cancel_work_timer+0x143/0x1c0
> cancel_work_sync+0x10/0x20
> blk_throtl_exit+0x25/0x60
> blkcg_exit_queue+0x35/0x40
> blk_release_queue+0x42/0x130
> kobject_put+0xa9/0x190
I added this, but the above is really a horrible changelog. It doesn't
say how the problem is fixed. I added some verbiage to that effect.
--
Jens Axboe
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v2 1/6] block: Avoid that blk_exit_rl() triggers a use-after-free
2017-06-14 19:28 ` Jens Axboe
@ 2017-06-14 19:32 ` Bart Van Assche
0 siblings, 0 replies; 7+ messages in thread
From: Bart Van Assche @ 2017-06-14 19:32 UTC (permalink / raw)
To: Jens Axboe, Ross Zwisler; +Cc: linux-block, Christoph Hellwig, Jan Kara, stable
On 06/14/17 12:28, Jens Axboe wrote:
> I added this, but the above is really a horrible changelog. It doesn't
> say how the problem is fixed. I added some verbiage to that effect.
Hello Jens,
Thanks for having fixed up the changelog and for already having picked
up this patch. I was going to repost the patch and write a proper
changelog but apparently you were faster than I :-)
BTW, since last night I can finally receive and send e-mails with a
@wdc.com suffix (thirteen months after the acquisition closed).
Bart.
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2017-06-14 19:33 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <20170531214350.31157-1-bart.vanassche@sandisk.com>
2017-05-31 21:43 ` [PATCH v2 1/6] block: Avoid that blk_exit_rl() triggers a use-after-free Bart Van Assche
2017-06-01 19:09 ` Jens Axboe
2017-06-13 17:54 ` Ross Zwisler
2017-06-14 15:19 ` Bart Van Assche
2017-06-14 18:04 ` Ross Zwisler
2017-06-14 19:28 ` Jens Axboe
2017-06-14 19:32 ` Bart Van Assche
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox