]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - queue-4.19/blk-mq-move-cancel-of-requeue_work-into-blk_mq_relea.patch
004bce08f45b52e1095c5670dd03be5cd3f28580
[thirdparty/kernel/stable-queue.git] / queue-4.19 / blk-mq-move-cancel-of-requeue_work-into-blk_mq_relea.patch
1 From 1586c239b0d7a3b9458e474b0fd7bd75fb84f996 Mon Sep 17 00:00:00 2001
2 From: Ming Lei <ming.lei@redhat.com>
3 Date: Tue, 30 Apr 2019 09:52:24 +0800
4 Subject: blk-mq: move cancel of requeue_work into blk_mq_release
5
6 [ Upstream commit fbc2a15e3433058582e5635aabe48a3011a644a8 ]
7
8 With holding queue's kobject refcount, it is safe for driver
9 to schedule requeue. However, blk_mq_kick_requeue_list() may
10 be called after blk_sync_queue() is done because of concurrent
11 requeue activities, then requeue work may not be completed when
12 freeing queue, and kernel oops is triggered.
13
14 So moving the cancel of requeue_work into blk_mq_release() for
15 avoiding race between requeue and freeing queue.
16
17 Cc: Dongli Zhang <dongli.zhang@oracle.com>
18 Cc: James Smart <james.smart@broadcom.com>
19 Cc: Bart Van Assche <bart.vanassche@wdc.com>
20 Cc: linux-scsi@vger.kernel.org,
21 Cc: Martin K . Petersen <martin.petersen@oracle.com>,
22 Cc: Christoph Hellwig <hch@lst.de>,
23 Cc: James E . J . Bottomley <jejb@linux.vnet.ibm.com>,
24 Reviewed-by: Bart Van Assche <bvanassche@acm.org>
25 Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de>
26 Reviewed-by: Hannes Reinecke <hare@suse.com>
27 Reviewed-by: Christoph Hellwig <hch@lst.de>
28 Tested-by: James Smart <james.smart@broadcom.com>
29 Signed-off-by: Ming Lei <ming.lei@redhat.com>
30 Signed-off-by: Jens Axboe <axboe@kernel.dk>
31 Signed-off-by: Sasha Levin <sashal@kernel.org>
32 ---
33 block/blk-core.c | 1 -
34 block/blk-mq.c | 2 ++
35 2 files changed, 2 insertions(+), 1 deletion(-)
36
37 diff --git a/block/blk-core.c b/block/blk-core.c
38 index 33488b1426b7..6eed5d84c2ef 100644
39 --- a/block/blk-core.c
40 +++ b/block/blk-core.c
41 @@ -411,7 +411,6 @@ void blk_sync_queue(struct request_queue *q)
42 struct blk_mq_hw_ctx *hctx;
43 int i;
44
45 - cancel_delayed_work_sync(&q->requeue_work);
46 queue_for_each_hw_ctx(q, hctx, i)
47 cancel_delayed_work_sync(&hctx->run_work);
48 } else {
49 diff --git a/block/blk-mq.c b/block/blk-mq.c
50 index 4e563ee462cb..70d839b9c3b0 100644
51 --- a/block/blk-mq.c
52 +++ b/block/blk-mq.c
53 @@ -2465,6 +2465,8 @@ void blk_mq_release(struct request_queue *q)
54 struct blk_mq_hw_ctx *hctx;
55 unsigned int i;
56
57 + cancel_delayed_work_sync(&q->requeue_work);
58 +
59 /* hctx kobj stays in hctx */
60 queue_for_each_hw_ctx(q, hctx, i) {
61 if (!hctx)
62 --
63 2.20.1
64