blk_mq_stop_hw_queue() has the following two issues. * BLK_MQ_S_STOPPED should be set before canceling the work items; otherwise, a new instance may proceed beyond STOPPED checking inbetween.
* cancel_delayed_work() doesn't do anything to work instance already executing. Use cancel_delayed_work_sync() to ensure that the currently in-flight one is finished. Signed-off-by: Tejun Heo <[email protected]> Cc: Jens Axboe <[email protected]> Cc: Nicholas A. Bellinger <[email protected]> --- block/blk-mq.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/block/blk-mq.c b/block/blk-mq.c index e11f5f8..4787c3d 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c @@ -862,9 +862,9 @@ EXPORT_SYMBOL(blk_mq_run_queues); void blk_mq_stop_hw_queue(struct blk_mq_hw_ctx *hctx) { - cancel_delayed_work(&hctx->run_work); - cancel_delayed_work(&hctx->delay_work); set_bit(BLK_MQ_S_STOPPED, &hctx->state); + cancel_delayed_work_sync(&hctx->run_work); + cancel_delayed_work_sync(&hctx->delay_work); } EXPORT_SYMBOL(blk_mq_stop_hw_queue); -- 1.9.3 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/

