Skip to content

Commit

Permalink
iocost: consider iocgs with active delays for debt forgiveness
Browse files Browse the repository at this point in the history
An iocg may have 0 debt but non-zero delay. The current debt forgiveness
logic doesn't act on such iocgs. This can lead to unexpected behaviors - an
iocg with a little bit of debt will have its delay canceled through debt
forgiveness but one w/o any debt but active delay will have to wait out
until its delay decays out.

This patch updates the debt handling logic so that it treats delays the same
as debts. If either debt or delay is active, debt forgiveness logic kicks in
and acts on both the same way.

Also, avoid turning the debt and delay directly to zero as that can confuse
state transitions.

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 c5a6561 commit bec02db
Showing 1 changed file with 7 additions and 4 deletions.
11 changes: 7 additions & 4 deletions block/blk-iocost.c
Original file line number Diff line number Diff line change
Expand Up @@ -2048,16 +2048,19 @@ static void ioc_forgive_debts(struct ioc *ioc, u64 usage_us_sum, int nr_debtors,
list_for_each_entry(iocg, &ioc->active_iocgs, active_list) {
u64 __maybe_unused old_debt, __maybe_unused old_delay;

if (!iocg->abs_vdebt)
if (!iocg->abs_vdebt && !iocg->delay)
continue;

spin_lock(&iocg->waitq.lock);

old_debt = iocg->abs_vdebt;
old_delay = iocg->delay;

iocg->abs_vdebt >>= nr_cycles;
iocg->delay = 0; /* kick_waitq will recalc */
if (iocg->abs_vdebt)
iocg->abs_vdebt = iocg->abs_vdebt >> nr_cycles ?: 1;
if (iocg->delay)
iocg->delay = iocg->delay >> nr_cycles ?: 1;

iocg_kick_waitq(iocg, true, now);

TRACE_IOCG_PATH(iocg_forgive_debt, iocg, now, usage_pct,
Expand Down Expand Up @@ -2129,7 +2132,7 @@ static void ioc_timer_fn(struct timer_list *timer)
iocg->delay) {
/* might be oversleeping vtime / hweight changes, kick */
iocg_kick_waitq(iocg, true, &now);
if (iocg->abs_vdebt)
if (iocg->abs_vdebt || iocg->delay)
nr_debtors++;
} else if (iocg_is_idle(iocg)) {
/* no waiter and idle, deactivate */
Expand Down

0 comments on commit bec02db

Please sign in to comment.