Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

blk-iolatency: keep track of previous windows stats

We apply a smoothing to the scale changes in order to keep sawtoothy
behavior from occurring. However our window for checking if we've
missed our target can sometimes be lower than the smoothing interval
(500ms), especially on faster drives like ssd's. In order to deal with
this keep track of the running tally of the previous intervals that we
threw away because we had already done a scale event recently.

This is needed for the ssd case as these low latency drives will have
bursts of latency, and if it happens to be ok for the window that
directly follows the opening of the scale window we could unthrottle
when previous windows we were missing our target.

Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>

authored by

Josef Bacik and committed by
Jens Axboe
451bb7c3 1fa2840e

+13 -7
+13 -7
block/blk-iolatency.c
··· 130 130 struct iolatency_grp { 131 131 struct blkg_policy_data pd; 132 132 struct latency_stat __percpu *stats; 133 + struct latency_stat cur_stat; 133 134 struct blk_iolatency *blkiolat; 134 135 struct rq_depth rq_depth; 135 136 struct rq_wait rq_wait; ··· 571 570 572 571 /* Somebody beat us to the punch, just bail. */ 573 572 spin_lock_irqsave(&lat_info->lock, flags); 573 + 574 + latency_stat_sum(iolat, &iolat->cur_stat, &stat); 574 575 lat_info->nr_samples -= iolat->nr_samples; 575 - lat_info->nr_samples += latency_stat_samples(iolat, &stat); 576 - iolat->nr_samples = latency_stat_samples(iolat, &stat); 576 + lat_info->nr_samples += latency_stat_samples(iolat, &iolat->cur_stat); 577 + iolat->nr_samples = latency_stat_samples(iolat, &iolat->cur_stat); 577 578 578 579 if ((lat_info->last_scale_event >= now || 579 - now - lat_info->last_scale_event < BLKIOLATENCY_MIN_ADJUST_TIME) && 580 - lat_info->scale_lat <= iolat->min_lat_nsec) 580 + now - lat_info->last_scale_event < BLKIOLATENCY_MIN_ADJUST_TIME)) 581 581 goto out; 582 582 583 - if (latency_sum_ok(iolat, &stat)) { 584 - if (latency_stat_samples(iolat, &stat) < 583 + if (latency_sum_ok(iolat, &iolat->cur_stat) && 584 + latency_sum_ok(iolat, &stat)) { 585 + if (latency_stat_samples(iolat, &iolat->cur_stat) < 585 586 BLKIOLATENCY_MIN_GOOD_SAMPLES) 586 587 goto out; 587 588 if (lat_info->scale_grp == iolat) { 588 589 lat_info->last_scale_event = now; 589 590 scale_cookie_change(iolat->blkiolat, lat_info, true); 590 591 } 591 - } else { 592 + } else if (lat_info->scale_lat == 0 || 593 + lat_info->scale_lat >= iolat->min_lat_nsec) { 592 594 lat_info->last_scale_event = now; 593 595 if (!lat_info->scale_grp || 594 596 lat_info->scale_lat > iolat->min_lat_nsec) { ··· 600 596 } 601 597 scale_cookie_change(iolat->blkiolat, lat_info, false); 602 598 } 599 + latency_stat_init(iolat, &iolat->cur_stat); 603 600 out: 604 601 spin_unlock_irqrestore(&lat_info->lock, flags); 605 602 } ··· 971 966 latency_stat_init(iolat, stat); 972 967 } 973 968 969 + latency_stat_init(iolat, &iolat->cur_stat); 974 970 rq_wait_init(&iolat->rq_wait); 975 971 spin_lock_init(&iolat->child_lat.lock); 976 972 iolat->rq_depth.queue_depth = blkg->q->nr_requests;