diff options
author | Jens Axboe <axboe@kernel.dk> | 2017-11-09 10:32:43 -0500 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2017-11-10 21:53:25 -0500 |
commit | eb619fdb2d4cb8b3d3419e9113921e87e7daf557 (patch) | |
tree | 491c0230e3ce0cead62bf59b090bf6c8b2bbd6e0 /include/linux/blk-mq.h | |
parent | e454d122e22826589cfa08788a802ab09d4fae24 (diff) |
blk-mq: fix issue with shared tag queue re-running
This patch attempts to make the case of hctx re-running on driver tag
failure more robust. Without this patch, it's pretty easy to trigger a
stall condition with shared tags. An example is using null_blk like
this:
modprobe null_blk queue_mode=2 nr_devices=4 shared_tags=1 submit_queues=1 hw_queue_depth=1
which sets up 4 devices, sharing the same tag set with a depth of 1.
Running a fio job ala:
[global]
bs=4k
rw=randread
norandommap
direct=1
ioengine=libaio
iodepth=4
[nullb0]
filename=/dev/nullb0
[nullb1]
filename=/dev/nullb1
[nullb2]
filename=/dev/nullb2
[nullb3]
filename=/dev/nullb3
will inevitably end with one or more threads being stuck waiting for a
scheduler tag. That IO is then stuck forever, until someone else
triggers a run of the queue.
Ensure that we always re-run the hardware queue, if the driver tag we
were waiting for got freed before we added our leftover request entries
back on the dispatch list.
Reviewed-by: Bart Van Assche <bart.vanassche@wdc.com>
Tested-by: Bart Van Assche <bart.vanassche@wdc.com>
Reviewed-by: Ming Lei <ming.lei@redhat.com>
Reviewed-by: Omar Sandoval <osandov@fb.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'include/linux/blk-mq.h')
-rw-r--r-- | include/linux/blk-mq.h | 5 |
1 files changed, 2 insertions, 3 deletions
diff --git a/include/linux/blk-mq.h b/include/linux/blk-mq.h index 674641527da7..4ae987c2352c 100644 --- a/include/linux/blk-mq.h +++ b/include/linux/blk-mq.h | |||
@@ -35,7 +35,7 @@ struct blk_mq_hw_ctx { | |||
35 | struct blk_mq_ctx **ctxs; | 35 | struct blk_mq_ctx **ctxs; |
36 | unsigned int nr_ctx; | 36 | unsigned int nr_ctx; |
37 | 37 | ||
38 | wait_queue_entry_t dispatch_wait; | 38 | wait_queue_entry_t dispatch_wait; |
39 | atomic_t wait_index; | 39 | atomic_t wait_index; |
40 | 40 | ||
41 | struct blk_mq_tags *tags; | 41 | struct blk_mq_tags *tags; |
@@ -181,8 +181,7 @@ enum { | |||
181 | BLK_MQ_S_STOPPED = 0, | 181 | BLK_MQ_S_STOPPED = 0, |
182 | BLK_MQ_S_TAG_ACTIVE = 1, | 182 | BLK_MQ_S_TAG_ACTIVE = 1, |
183 | BLK_MQ_S_SCHED_RESTART = 2, | 183 | BLK_MQ_S_SCHED_RESTART = 2, |
184 | BLK_MQ_S_TAG_WAITING = 3, | 184 | BLK_MQ_S_START_ON_RUN = 3, |
185 | BLK_MQ_S_START_ON_RUN = 4, | ||
186 | 185 | ||
187 | BLK_MQ_MAX_DEPTH = 10240, | 186 | BLK_MQ_MAX_DEPTH = 10240, |
188 | 187 | ||