| From aec7c12e99f767f0583d489d3862b25536afedb4 Mon Sep 17 00:00:00 2001 |
| From: Ming Lei <ming.lei@redhat.com> |
| Date: Tue, 30 Apr 2019 09:52:24 +0800 |
| Subject: [PATCH] blk-mq: move cancel of requeue_work into blk_mq_release |
| |
| commit fbc2a15e3433058582e5635aabe48a3011a644a8 upstream. |
| |
| With holding queue's kobject refcount, it is safe for driver |
| to schedule requeue. However, blk_mq_kick_requeue_list() may |
| be called after blk_sync_queue() is done because of concurrent |
| requeue activities, then requeue work may not be completed when |
| freeing queue, and kernel oops is triggered. |
| |
| So moving the cancel of requeue_work into blk_mq_release() for |
| avoiding race between requeue and freeing queue. |
| |
| Cc: Dongli Zhang <dongli.zhang@oracle.com> |
| Cc: James Smart <james.smart@broadcom.com> |
| Cc: Bart Van Assche <bart.vanassche@wdc.com> |
| Cc: linux-scsi@vger.kernel.org, |
| Cc: Martin K . Petersen <martin.petersen@oracle.com>, |
| Cc: Christoph Hellwig <hch@lst.de>, |
| Cc: James E . J . Bottomley <jejb@linux.vnet.ibm.com>, |
| Reviewed-by: Bart Van Assche <bvanassche@acm.org> |
| Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de> |
| Reviewed-by: Hannes Reinecke <hare@suse.com> |
| Reviewed-by: Christoph Hellwig <hch@lst.de> |
| Tested-by: James Smart <james.smart@broadcom.com> |
| Signed-off-by: Ming Lei <ming.lei@redhat.com> |
| Signed-off-by: Jens Axboe <axboe@kernel.dk> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/block/blk-core.c b/block/blk-core.c |
| index 7d4bf916546c..fc41adedf2eb 100644 |
| --- a/block/blk-core.c |
| +++ b/block/blk-core.c |
| @@ -411,7 +411,6 @@ void blk_sync_queue(struct request_queue *q) |
| struct blk_mq_hw_ctx *hctx; |
| int i; |
| |
| - cancel_delayed_work_sync(&q->requeue_work); |
| queue_for_each_hw_ctx(q, hctx, i) |
| cancel_delayed_work_sync(&hctx->run_work); |
| } else { |
| diff --git a/block/blk-mq.c b/block/blk-mq.c |
| index 5f1493fc9c7f..01f5660aae64 100644 |
| --- a/block/blk-mq.c |
| +++ b/block/blk-mq.c |
| @@ -2420,6 +2420,8 @@ void blk_mq_release(struct request_queue *q) |
| struct blk_mq_hw_ctx *hctx; |
| unsigned int i; |
| |
| + cancel_delayed_work_sync(&q->requeue_work); |
| + |
| /* hctx kobj stays in hctx */ |
| queue_for_each_hw_ctx(q, hctx, i) { |
| if (!hctx) |
| -- |
| 2.7.4 |
| |