iocost: factor out ioc_forgive_debts()
authorTejun Heo <tj@kernel.org>
Fri, 18 Sep 2020 00:44:52 +0000 (20:44 -0400)
committerJens Axboe <axboe@kernel.dk>
Fri, 25 Sep 2020 14:35:02 +0000 (08:35 -0600)
Debt reduction logic is going to be improved and expanded. Factor it out
into ioc_forgive_debts() and generalize the comment a bit. No functional
change.

Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
block/blk-iocost.c

index ef9476f..bbf30bb 100644 (file)
@@ -1979,6 +1979,40 @@ static void transfer_surpluses(struct list_head *surpluses, struct ioc_now *now)
                list_del_init(&iocg->walk_list);
 }
 
+/*
+ * A low weight iocg can amass a large amount of debt, for example, when
+ * anonymous memory gets reclaimed aggressively. If the system has a lot of
+ * memory paired with a slow IO device, the debt can span multiple seconds or
+ * more. If there are no other subsequent IO issuers, the in-debt iocg may end
+ * up blocked paying its debt while the IO device is idle.
+ *
+ * The following protects against such cases. If the device has been
+ * 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)
+{
+       if (nr_shortages ||
+           div64_u64(100 * usage_us_sum, now->now - ioc->period_at) >=
+           DEBT_BUSY_USAGE_PCT)
+               ioc->debt_busy_at = now->now;
+
+       if (nr_debtors &&
+           now->now - ioc->debt_busy_at >= DEBT_REDUCTION_IDLE_DUR) {
+               struct ioc_gq *iocg;
+
+               list_for_each_entry(iocg, &ioc->active_iocgs, active_list) {
+                       if (iocg->abs_vdebt) {
+                               spin_lock(&iocg->waitq.lock);
+                               iocg->abs_vdebt /= 2;
+                               iocg_kick_waitq(iocg, true, now);
+                               spin_unlock(&iocg->waitq.lock);
+                       }
+               }
+               ioc->debt_busy_at = now->now;
+       }
+}
+
 static void ioc_timer_fn(struct timer_list *timer)
 {
        struct ioc *ioc = container_of(timer, struct ioc, timer);
@@ -2171,37 +2205,7 @@ 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);
 
-       /*
-        * A low weight iocg can amass a large amount of debt, for example, when
-        * anonymous memory gets reclaimed aggressively. If the system has a lot
-        * of memory paired with a slow IO device, the debt can span multiple
-        * seconds or more. If there are no other subsequent IO issuers, the
-        * in-debt iocg may end up blocked paying its debt while the IO device
-        * is idle.
-        *
-        * The following protects against such pathological cases. If the device
-        * has been sufficiently idle for a substantial amount of time, the
-        * debts are halved. The criteria are on the conservative side as we
-        * want to resolve the rare extreme cases without impacting regular
-        * operation by forgiving debts too readily.
-        */
-       if (nr_shortages ||
-           div64_u64(100 * usage_us_sum, now.now - ioc->period_at) >=
-           DEBT_BUSY_USAGE_PCT)
-               ioc->debt_busy_at = now.now;
-
-       if (nr_debtors &&
-           now.now - ioc->debt_busy_at >= DEBT_REDUCTION_IDLE_DUR) {
-               list_for_each_entry(iocg, &ioc->active_iocgs, active_list) {
-                       if (iocg->abs_vdebt) {
-                               spin_lock(&iocg->waitq.lock);
-                               iocg->abs_vdebt /= 2;
-                               iocg_kick_waitq(iocg, true, &now);
-                               spin_unlock(&iocg->waitq.lock);
-                       }
-               }
-               ioc->debt_busy_at = now.now;
-       }
+       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