Skip to content

Commit

Permalink
iocost: replace nr_shortages cond in ioc_forgive_debts() with busy_le…
Browse files Browse the repository at this point in the history
…vel one

Debt reduction was blocked if any iocg was short on budget in the past
period to avoid reducing debts while some iocgs are saturated. However, this
ends up unnecessarily blocking debt reduction due to temporary local
imbalances when the device is generally being underutilized, while also
failing to block when the underlying device is overwhelmed and the usage
becomes low from high latency.

Given that debt accumulation mostly happens with swapout bursts which can
significantly deteriorate the underlying device's latency response, the
current logic is not great.

Let's replace it with ioc->busy_level based condition so that we block debt
reduction when the underlying device is being saturated. ioc_forgive_debts()
call is moved after busy_level determination.

Signed-off-by: Tejun Heo <[email protected]>
Signed-off-by: Jens Axboe <[email protected]>
  • Loading branch information
htejun authored and axboe committed Sep 25, 2020
1 parent ab8df82 commit 33a1fe6
Showing 1 changed file with 5 additions and 8 deletions.
13 changes: 5 additions & 8 deletions block/blk-iocost.c
Original file line number Diff line number Diff line change
Expand Up @@ -287,10 +287,7 @@ enum {
MIN_DELAY = 250,
MAX_DELAY = 250 * USEC_PER_MSEC,

/*
* Halve debts if total usage keeps staying under 25% w/o any shortages
* for over 100ms.
*/
/* halve debts if total usage keeps staying under 25% for over 100ms */
DEBT_BUSY_USAGE_PCT = 25,
DEBT_REDUCTION_IDLE_DUR = 100 * USEC_PER_MSEC,

Expand Down Expand Up @@ -1990,9 +1987,9 @@ static void transfer_surpluses(struct list_head *surpluses, struct ioc_now *now)
* sufficiently idle for a while, the debts are halved.
*/
static void ioc_forgive_debts(struct ioc *ioc, u64 usage_us_sum, int nr_debtors,
int nr_shortages, struct ioc_now *now)
struct ioc_now *now)
{
if (nr_shortages ||
if (ioc->busy_level < 0 ||
div64_u64(100 * usage_us_sum, now->now - ioc->period_at) >=
DEBT_BUSY_USAGE_PCT)
ioc->debt_busy_at = now->now;
Expand Down Expand Up @@ -2205,8 +2202,6 @@ static void ioc_timer_fn(struct timer_list *timer)
list_for_each_entry_safe(iocg, tiocg, &surpluses, surplus_list)
list_del_init(&iocg->surplus_list);

ioc_forgive_debts(ioc, usage_us_sum, nr_debtors, nr_shortages, &now);

/*
* If q is getting clogged or we're missing too much, we're issuing
* too much IO and should lower vtime rate. If we're not missing
Expand Down Expand Up @@ -2301,6 +2296,8 @@ static void ioc_timer_fn(struct timer_list *timer)

ioc_refresh_params(ioc, false);

ioc_forgive_debts(ioc, usage_us_sum, nr_debtors, &now);

/*
* This period is done. Move onto the next one. If nothing's
* going on with the device, stop the timer.
Expand Down

0 comments on commit 33a1fe6

Please sign in to comment.