diff options
author | Hou Tao <houtao1@huawei.com> | 2017-07-11 21:58:15 +0800 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2017-07-12 08:32:04 -0600 |
commit | 3f7cb4f4130ca5693f0698211bf1e42945efbb8c (patch) | |
tree | 7aecf67d6851b4213a89bb1e632b42878ee3b2c8 | |
parent | 38c9140740eb0993924b676a111c164903163b1e (diff) | |
download | linux-3f7cb4f4130ca5693f0698211bf1e42945efbb8c.tar.gz linux-3f7cb4f4130ca5693f0698211bf1e42945efbb8c.tar.bz2 linux-3f7cb4f4130ca5693f0698211bf1e42945efbb8c.zip |
bfq: dispatch request to prevent queue stalling after the request completion
There are mq devices (eg., virtio-blk, nbd and loopback) which don't
invoke blk_mq_run_hw_queues() after the completion of a request.
If bfq is enabled on these devices and the slice_idle attribute or
strict_guarantees attribute is set as zero, it is possible that
after a request completion the remaining requests of busy bfq queue
will stalled in the bfq schedule until a new request arrives.
To fix the scheduler latency problem, we need to check whether or not
all issued requests have completed and dispatch more requests to driver
if there is no request in driver.
The problem can be reproduced by running the following script
on a virtio-blk device with nr_hw_queues as 1:
#!/bin/sh
dev=vdb
# mount point for dev
mp=/tmp/mnt
cd $mp
job=strict.job
cat <<EOF > $job
[global]
direct=1
bs=4k
size=256M
rw=write
ioengine=libaio
iodepth=128
runtime=5
time_based
[1]
filename=1.data
[2]
new_group
filename=2.data
EOF
echo bfq > /sys/block/$dev/queue/scheduler
echo 1 > /sys/block/$dev/queue/iosched/strict_guarantees
fio $job
Signed-off-by: Hou Tao <houtao1@huawei.com>
Reviewed-by: Paolo Valente <paolo.valente@linaro.org>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
-rw-r--r-- | block/bfq-iosched.c | 3 |
1 files changed, 3 insertions, 0 deletions
diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c index 60a6835265fc..436b6ca6b175 100644 --- a/block/bfq-iosched.c +++ b/block/bfq-iosched.c @@ -4299,6 +4299,9 @@ static void bfq_completed_request(struct bfq_queue *bfqq, struct bfq_data *bfqd) bfq_bfqq_expire(bfqd, bfqq, false, BFQQE_NO_MORE_REQUESTS); } + + if (!bfqd->rq_in_driver) + bfq_schedule_dispatch(bfqd); } static void bfq_put_rq_priv_body(struct bfq_queue *bfqq) |