summaryrefslogtreecommitdiffstats
path: root/block/bfq-iosched.c
diff options
context:
space:
mode:
authorPaolo Valente <paolo.valente@linaro.org>2017-08-04 01:35:11 -0400
committerJens Axboe <axboe@kernel.dk>2017-08-11 10:58:03 -0400
commitedaf94285bf98375d45cc95bbfd4b9d57796c864 (patch)
tree1a3a79ccc855190bef281b3c12031ecf950ae485 /block/bfq-iosched.c
parentd5be3fefc9e2db68eacfc7cfe265e2e860e4213f (diff)
block, bfq: boost throughput with flash-based non-queueing devices
When a queue associated with a process remains empty, there are cases where throughput gets boosted if the device is idled to await the arrival of a new I/O request for that queue. Currently, BFQ assumes that one of these cases is when the device has no internal queueing (regardless of the properties of the I/O being served). Unfortunately, this condition has proved to be too general. So, this commit refines it as "the device has no internal queueing and is rotational". This refinement provides a significant throughput boost with random I/O, on flash-based storage without internal queueing. For example, on a HiKey board, throughput increases by up to 125%, growing, e.g., from 6.9MB/s to 15.6MB/s with two or three random readers in parallel. Signed-off-by: Paolo Valente <paolo.valente@linaro.org> Signed-off-by: Luca Miccio <lucmiccio@gmail.com> Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'block/bfq-iosched.c')
-rw-r--r--block/bfq-iosched.c29
1 files changed, 19 insertions, 10 deletions
diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c
index ccdc9e6b5df1..509f39998011 100644
--- a/block/bfq-iosched.c
+++ b/block/bfq-iosched.c
@@ -3114,7 +3114,10 @@ static bool bfq_may_expire_for_budg_timeout(struct bfq_queue *bfqq)
3114static bool bfq_bfqq_may_idle(struct bfq_queue *bfqq) 3114static bool bfq_bfqq_may_idle(struct bfq_queue *bfqq)
3115{ 3115{
3116 struct bfq_data *bfqd = bfqq->bfqd; 3116 struct bfq_data *bfqd = bfqq->bfqd;
3117 bool idling_boosts_thr, idling_boosts_thr_without_issues, 3117 bool rot_without_queueing =
3118 !blk_queue_nonrot(bfqd->queue) && !bfqd->hw_tag,
3119 bfqq_sequential_and_IO_bound,
3120 idling_boosts_thr, idling_boosts_thr_without_issues,
3118 idling_needed_for_service_guarantees, 3121 idling_needed_for_service_guarantees,
3119 asymmetric_scenario; 3122 asymmetric_scenario;
3120 3123
@@ -3133,28 +3136,34 @@ static bool bfq_bfqq_may_idle(struct bfq_queue *bfqq)
3133 bfq_class_idle(bfqq)) 3136 bfq_class_idle(bfqq))
3134 return false; 3137 return false;
3135 3138
3139 bfqq_sequential_and_IO_bound = !BFQQ_SEEKY(bfqq) &&
3140 bfq_bfqq_IO_bound(bfqq) && bfq_bfqq_has_short_ttime(bfqq);
3141
3136 /* 3142 /*
3137 * The next variable takes into account the cases where idling 3143 * The next variable takes into account the cases where idling
3138 * boosts the throughput. 3144 * boosts the throughput.
3139 * 3145 *
3140 * The value of the variable is computed considering, first, that 3146 * The value of the variable is computed considering, first, that
3141 * idling is virtually always beneficial for the throughput if: 3147 * idling is virtually always beneficial for the throughput if:
3142 * (a) the device is not NCQ-capable, or 3148 * (a) the device is not NCQ-capable and rotational, or
3143 * (b) regardless of the presence of NCQ, the device is rotational 3149 * (b) regardless of the presence of NCQ, the device is rotational and
3144 * and the request pattern for bfqq is I/O-bound and sequential. 3150 * the request pattern for bfqq is I/O-bound and sequential, or
3151 * (c) regardless of whether it is rotational, the device is
3152 * not NCQ-capable and the request pattern for bfqq is
3153 * I/O-bound and sequential.
3145 * 3154 *
3146 * Secondly, and in contrast to the above item (b), idling an 3155 * Secondly, and in contrast to the above item (b), idling an
3147 * NCQ-capable flash-based device would not boost the 3156 * NCQ-capable flash-based device would not boost the
3148 * throughput even with sequential I/O; rather it would lower 3157 * throughput even with sequential I/O; rather it would lower
3149 * the throughput in proportion to how fast the device 3158 * the throughput in proportion to how fast the device
3150 * is. Accordingly, the next variable is true if any of the 3159 * is. Accordingly, the next variable is true if any of the
3151 * above conditions (a) and (b) is true, and, in particular, 3160 * above conditions (a), (b) or (c) is true, and, in
3152 * happens to be false if bfqd is an NCQ-capable flash-based 3161 * particular, happens to be false if bfqd is an NCQ-capable
3153 * device. 3162 * flash-based device.
3154 */ 3163 */
3155 idling_boosts_thr = !bfqd->hw_tag || 3164 idling_boosts_thr = rot_without_queueing ||
3156 (!blk_queue_nonrot(bfqd->queue) && bfq_bfqq_IO_bound(bfqq) && 3165 ((!blk_queue_nonrot(bfqd->queue) || !bfqd->hw_tag) &&
3157 bfq_bfqq_has_short_ttime(bfqq)); 3166 bfqq_sequential_and_IO_bound);
3158 3167
3159 /* 3168 /*
3160 * The value of the next variable, 3169 * The value of the next variable,