diff options
author | Paolo Valente <paolo.valente@linaro.org> | 2017-08-04 01:35:11 -0400 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2017-08-11 10:58:03 -0400 |
commit | edaf94285bf98375d45cc95bbfd4b9d57796c864 (patch) | |
tree | 1a3a79ccc855190bef281b3c12031ecf950ae485 /block/bfq-iosched.c | |
parent | d5be3fefc9e2db68eacfc7cfe265e2e860e4213f (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.c | 29 |
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) | |||
3114 | static bool bfq_bfqq_may_idle(struct bfq_queue *bfqq) | 3114 | static 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, |