diff options
Diffstat (limited to 'block/blk-iocost.c')
-rw-r--r-- | block/blk-iocost.c | 11 |
1 files changed, 7 insertions, 4 deletions
diff --git a/block/blk-iocost.c b/block/blk-iocost.c index 328ae805e85f..b82649c1440b 100644 --- a/block/blk-iocost.c +++ b/block/blk-iocost.c @@ -2048,7 +2048,7 @@ 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); @@ -2056,8 +2056,11 @@ static void ioc_forgive_debts(struct ioc *ioc, u64 usage_us_sum, int nr_debtors, 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, @@ -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 */ |