linux/block
Damien Le Moal cb8acabbe3 block: mq-deadline: Fix queue restart handling
Commit 7211aef86f ("block: mq-deadline: Fix write completion
handling") added a call to blk_mq_sched_mark_restart_hctx() in
dd_dispatch_request() to make sure that write request dispatching does
not stall when all target zones are locked. This fix left a subtle race
when a write completion happens during a dispatch execution on another
CPU:

CPU 0: Dispatch			CPU1: write completion

dd_dispatch_request()
    lock(&dd->lock);
    ...
    lock(&dd->zone_lock);	dd_finish_request()
    rq = find request		lock(&dd->zone_lock);
    unlock(&dd->zone_lock);
    				zone write unlock
				unlock(&dd->zone_lock);
				...
				__blk_mq_free_request
                                      check restart flag (not set)
				      -> queue not run
    ...
    if (!rq && have writes)
        blk_mq_sched_mark_restart_hctx()
    unlock(&dd->lock)

Since the dispatch context finishes after the write request completion
handling, marking the queue as needing a restart is not seen from
__blk_mq_free_request() and blk_mq_sched_restart() not executed leading
to the dispatch stall under 100% write workloads.

Fix this by moving the call to blk_mq_sched_mark_restart_hctx() from
dd_dispatch_request() into dd_finish_request() under the zone lock to
ensure full mutual exclusion between write request dispatch selection
and zone unlock on write request completion.

Fixes: 7211aef86f ("block: mq-deadline: Fix write completion handling")
Cc: stable@vger.kernel.org
Reported-by: Hans Holmberg <Hans.Holmberg@wdc.com>
Reviewed-by: Hans Holmberg <hans.holmberg@wdc.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
2019-09-03 07:59:51 -06:00
..
partitions docs: admin-guide: add a series of orphaned documents 2019-07-15 11:03:02 -03:00
badblocks.c block: switch all files cleared marked as GPLv2 to SPDX tags 2019-04-30 16:11:57 -06:00
bfq-cgroup.c blkcg: pass @q and @blkcg into blkcg_pol_alloc_pd_fn() 2019-08-28 21:17:01 -06:00
bfq-iosched.c for-linus-20190726 2019-07-26 10:32:12 -07:00
bfq-iosched.h block, bfq: detect wakers and unconditionally inject their I/O 2019-06-25 09:07:34 -06:00
bfq-wf2q.c block: switch all files cleared marked as GPLv2 or later to SPDX tags 2019-04-30 16:11:59 -06:00
bio-integrity.c block/bio-integrity: fix a memory leak bug 2019-07-11 20:01:21 -06:00
bio.c block: move same page handling from __bio_add_pc_page to the callers 2019-08-22 07:14:39 -06:00
blk-cgroup.c blkcg: separate blkcg_conf_get_disk() out of blkg_conf_prep() 2019-08-28 21:17:04 -06:00
blk-core.c block/rq_qos: add rq_qos_merge() 2019-08-28 21:17:05 -06:00
blk-exec.c block: add SPDX tags to block layer files missing licensing information 2019-04-30 16:12:03 -06:00
blk-flush.c block: switch all files cleared marked as GPLv2 to SPDX tags 2019-04-30 16:11:57 -06:00
blk-integrity.c docs: block: convert to ReST 2019-07-15 09:20:27 -03:00
blk-ioc.c block: remove the queue_lock indirection 2018-11-15 12:17:28 -07:00
blk-iocost.c blkcg: add missing NULL check in ioc_cpd_alloc() 2019-08-30 07:16:19 -06:00
blk-iolatency.c blkcg: s/RQ_QOS_CGROUP/RQ_QOS_LATENCY/ 2019-08-28 21:17:08 -06:00
blk-lib.c block: fix 32 bit overflow in __blkdev_issue_discard() 2018-11-14 08:17:18 -07:00
blk-map.c block: remove the bi_phys_segments field in struct bio 2019-06-20 10:29:22 -06:00
blk-merge.c block: Improve physical block alignment of split bios 2019-08-04 21:41:29 -06:00
blk-mq-cpumap.c blk-mq: balance mapping between present CPUs and queues 2019-08-04 21:43:12 -06:00
blk-mq-debugfs-zoned.c block: Cleanup license notice 2019-01-17 21:21:40 -07:00
blk-mq-debugfs.c for-5.3/block-20190708 2019-07-09 10:45:06 -07:00
blk-mq-debugfs.h blk-mq: no need to check return value of debugfs_create functions 2019-06-13 03:00:30 -06:00
blk-mq-pci.c block: Fix blk_mq_*_map_queues() kernel-doc headers 2019-05-31 15:12:34 -06:00
blk-mq-rdma.c block: Fix blk_mq_*_map_queues() kernel-doc headers 2019-05-31 15:12:34 -06:00
blk-mq-sched.c blk-mq: remove blk_mq_put_ctx() 2019-07-02 21:03:27 -06:00
blk-mq-sched.h block: blk-mq: Remove blk_mq_sched_started_request and started_request 2019-07-23 07:25:09 -06:00
blk-mq-sysfs.c block: split .sysfs_lock into two locks 2019-08-27 10:40:20 -06:00
blk-mq-tag.c blk-mq: introduce blk_mq_tagset_wait_completed_request() 2019-08-04 21:41:29 -06:00
blk-mq-tag.h Merge branch 'for-4.15/block' of git://git.kernel.dk/linux-block 2017-11-14 15:32:19 -08:00
blk-mq-virtio.c block: Fix blk_mq_*_map_queues() kernel-doc headers 2019-05-31 15:12:34 -06:00
blk-mq.c blk-mq: add optional request->alloc_time_ns 2019-08-28 21:17:10 -06:00
blk-mq.h block: Disable write plugging for zoned block devices 2019-07-10 14:18:01 -06:00
blk-pm.c block: remove the queue_lock indirection 2018-11-15 12:17:28 -07:00
blk-pm.h block: remove the queue_lock indirection 2018-11-15 12:17:28 -07:00
blk-rq-qos.c block/rq_qos: implement rq_qos_ops->queue_depth_changed() 2019-08-28 21:17:07 -06:00
blk-rq-qos.h blkcg: implement blk-iocost 2019-08-28 21:17:12 -06:00
blk-settings.c block/rq_qos: implement rq_qos_ops->queue_depth_changed() 2019-08-28 21:17:07 -06:00
blk-softirq.c block: remove a few unused exports 2018-11-15 12:13:25 -07:00
blk-stat.c block: add SPDX tags to block layer files missing licensing information 2019-04-30 16:12:03 -06:00
blk-stat.h block: deactivate blk_stat timer in wbt_disable_default() 2018-12-12 06:47:51 -07:00
blk-sysfs.c block: split .sysfs_lock into two locks 2019-08-27 10:40:20 -06:00
blk-throttle.c blkcg: pass @q and @blkcg into blkcg_pol_alloc_pd_fn() 2019-08-28 21:17:01 -06:00
blk-timeout.c block: add SPDX tags to block layer files missing licensing information 2019-04-30 16:12:03 -06:00
blk-wbt.c block/rq_qos: implement rq_qos_ops->queue_depth_changed() 2019-08-28 21:17:07 -06:00
blk-wbt.h block/rq_qos: implement rq_qos_ops->queue_depth_changed() 2019-08-28 21:17:07 -06:00
blk-zoned.c blk-zoned: implement REQ_OP_ZONE_RESET_ALL 2019-08-04 21:41:29 -06:00
blk.h block: split .sysfs_lock into two locks 2019-08-27 10:40:20 -06:00
bounce.c block: remove the i argument to bio_for_each_segment_all 2019-04-30 09:26:13 -06:00
bsg-lib.c block: Fix bsg_setup_queue() kernel-doc header 2019-05-31 15:12:34 -06:00
bsg.c block: switch all files cleared marked as GPLv2 to SPDX tags 2019-04-30 16:11:57 -06:00
cmdline-parser.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
compat_ioctl.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
elevator.c block: split .sysfs_lock into two locks 2019-08-27 10:40:20 -06:00
genhd.c block: fix sysfs module parameters directory path in comment 2019-07-16 10:16:33 -06:00
ioctl.c block: add SPDX tags to block layer files missing licensing information 2019-04-30 16:12:03 -06:00
ioprio.c docs: block: convert to ReST 2019-07-15 09:20:27 -03:00
Kconfig blkcg: implement blk-iocost 2019-08-28 21:17:12 -06:00
Kconfig.iosched docs: block: convert to ReST 2019-07-15 09:20:27 -03:00
kyber-iosched.c blk-mq: remove blk_mq_put_ctx() 2019-07-02 21:03:27 -06:00
Makefile blkcg: implement blk-iocost 2019-08-28 21:17:12 -06:00
mq-deadline.c block: mq-deadline: Fix queue restart handling 2019-09-03 07:59:51 -06:00
opal_proto.h block: sed-opal: Removed duplicate OPAL_METHOD_LENGTH definition 2019-08-20 09:34:49 -06:00
partition-generic.c block: fix use-after-free on gendisk 2019-04-22 09:48:12 -06:00
scsi_ioctl.c block: switch all files cleared marked as GPLv2 to SPDX tags 2019-04-30 16:11:57 -06:00
sed-opal.c block: sed-opal: Remove always false conditional statement 2019-08-20 09:33:21 -06:00
t10-pi.c block: switch all files cleared marked as GPLv2 to SPDX tags 2019-04-30 16:11:57 -06:00