summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHou Tao <houtao1@huawei.com>2017-07-11 21:58:15 +0800
committerJens Axboe <axboe@kernel.dk>2017-07-12 08:32:04 -0600
commit3f7cb4f4130ca5693f0698211bf1e42945efbb8c (patch)
tree7aecf67d6851b4213a89bb1e632b42878ee3b2c8
parent38c9140740eb0993924b676a111c164903163b1e (diff)
downloadlinux-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.c3
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)