diff --git a/block/blk-iocost.c b/block/blk-iocost.c index a4c99ae1e076d4c99570f34603efb433397bc42f..cc620c532c2ef1a6e7b7d558936a948364eb4d1d 100644 --- a/block/blk-iocost.c +++ b/block/blk-iocost.c @@ -1306,6 +1306,13 @@ static bool iocg_kick_delay(struct ioc_gq *iocg, struct ioc_now *now) lockdep_assert_held(&iocg->waitq.lock); + /* + * If the delay is set by another CPU, we may be in the past. No need to + * change anything if so. This avoids decay calculation underflow. + */ + if (time_before64(now->now, iocg->delay_at)) + return false; + /* calculate the current delay in effect - 1/2 every second */ tdelta = now->now - iocg->delay_at; if (iocg->delay)