diff options
author | Shaohua Li <shli@fb.com> | 2017-06-06 15:40:43 -0400 |
---|---|---|
committer | Jens Axboe <axboe@fb.com> | 2017-06-07 11:09:32 -0400 |
commit | 6679a90c4b0dc2563383df1fe0eb170736952a2e (patch) | |
tree | e700714df531b4c6aeaacdde3b59b1c8a28b6ff5 | |
parent | a41b816c174409417d91b4ceef0145c9f0bef67c (diff) |
blk-throttle: set default latency baseline for harddisk
hard disk IO latency varies a lot depending on spindle move. The latency
range could be from several microseconds to several milliseconds. It's
pretty hard to get the baseline latency used by io.low.
We will use a different stragety here. The idea is only using IO with
spindle move to determine if cgroup IO is in good state. For HD, if io
latency is small (< 1ms), we ignore the IO. Such IO is likely from
sequential IO, and is helpless to help determine if a cgroup's IO is
impacted by other cgroups. With this, we only account IO with big
latency. Then we can choose a hardcoded baseline latency for HD (4ms,
which is typical IO latency with seek). With all these settings, the
io.low latency works for both HD and SSD.
Signed-off-by: Shaohua Li <shli@fb.com>
Signed-off-by: Jens Axboe <axboe@fb.com>
-rw-r--r-- | block/blk-throttle.c | 20 |
1 files changed, 17 insertions, 3 deletions
diff --git a/block/blk-throttle.c b/block/blk-throttle.c index 3b751f706c61..a7285bf2831c 100644 --- a/block/blk-throttle.c +++ b/block/blk-throttle.c | |||
@@ -27,6 +27,13 @@ static int throtl_quantum = 32; | |||
27 | #define MIN_THROTL_IOPS (10) | 27 | #define MIN_THROTL_IOPS (10) |
28 | #define DFL_LATENCY_TARGET (-1L) | 28 | #define DFL_LATENCY_TARGET (-1L) |
29 | #define DFL_IDLE_THRESHOLD (0) | 29 | #define DFL_IDLE_THRESHOLD (0) |
30 | #define DFL_HD_BASELINE_LATENCY (4000L) /* 4ms */ | ||
31 | #define LATENCY_FILTERED_SSD (0) | ||
32 | /* | ||
33 | * For HD, very small latency comes from sequential IO. Such IO is helpless to | ||
34 | * help determine if its IO is impacted by others, hence we ignore the IO | ||
35 | */ | ||
36 | #define LATENCY_FILTERED_HD (1000L) /* 1ms */ | ||
30 | 37 | ||
31 | #define SKIP_LATENCY (((u64)1) << BLK_STAT_RES_SHIFT) | 38 | #define SKIP_LATENCY (((u64)1) << BLK_STAT_RES_SHIFT) |
32 | 39 | ||
@@ -212,6 +219,7 @@ struct throtl_data | |||
212 | struct avg_latency_bucket avg_buckets[LATENCY_BUCKET_SIZE]; | 219 | struct avg_latency_bucket avg_buckets[LATENCY_BUCKET_SIZE]; |
213 | struct latency_bucket __percpu *latency_buckets; | 220 | struct latency_bucket __percpu *latency_buckets; |
214 | unsigned long last_calculate_time; | 221 | unsigned long last_calculate_time; |
222 | unsigned long filtered_latency; | ||
215 | 223 | ||
216 | bool track_bio_latency; | 224 | bool track_bio_latency; |
217 | }; | 225 | }; |
@@ -2281,7 +2289,7 @@ void blk_throtl_bio_endio(struct bio *bio) | |||
2281 | throtl_track_latency(tg->td, blk_stat_size(&bio->bi_issue_stat), | 2289 | throtl_track_latency(tg->td, blk_stat_size(&bio->bi_issue_stat), |
2282 | bio_op(bio), lat); | 2290 | bio_op(bio), lat); |
2283 | 2291 | ||
2284 | if (tg->latency_target) { | 2292 | if (tg->latency_target && lat >= tg->td->filtered_latency) { |
2285 | int bucket; | 2293 | int bucket; |
2286 | unsigned int threshold; | 2294 | unsigned int threshold; |
2287 | 2295 | ||
@@ -2417,14 +2425,20 @@ void blk_throtl_exit(struct request_queue *q) | |||
2417 | void blk_throtl_register_queue(struct request_queue *q) | 2425 | void blk_throtl_register_queue(struct request_queue *q) |
2418 | { | 2426 | { |
2419 | struct throtl_data *td; | 2427 | struct throtl_data *td; |
2428 | int i; | ||
2420 | 2429 | ||
2421 | td = q->td; | 2430 | td = q->td; |
2422 | BUG_ON(!td); | 2431 | BUG_ON(!td); |
2423 | 2432 | ||
2424 | if (blk_queue_nonrot(q)) | 2433 | if (blk_queue_nonrot(q)) { |
2425 | td->throtl_slice = DFL_THROTL_SLICE_SSD; | 2434 | td->throtl_slice = DFL_THROTL_SLICE_SSD; |
2426 | else | 2435 | td->filtered_latency = LATENCY_FILTERED_SSD; |
2436 | } else { | ||
2427 | td->throtl_slice = DFL_THROTL_SLICE_HD; | 2437 | td->throtl_slice = DFL_THROTL_SLICE_HD; |
2438 | td->filtered_latency = LATENCY_FILTERED_HD; | ||
2439 | for (i = 0; i < LATENCY_BUCKET_SIZE; i++) | ||
2440 | td->avg_buckets[i].latency = DFL_HD_BASELINE_LATENCY; | ||
2441 | } | ||
2428 | #ifndef CONFIG_BLK_DEV_THROTTLING_LOW | 2442 | #ifndef CONFIG_BLK_DEV_THROTTLING_LOW |
2429 | /* if no low limit, use previous default */ | 2443 | /* if no low limit, use previous default */ |
2430 | td->throtl_slice = DFL_THROTL_SLICE_HD; | 2444 | td->throtl_slice = DFL_THROTL_SLICE_HD; |