]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blobdiff - block/bfq-iosched.c
block, bfq: check and switch back to interactive wr also on queue split
[mirror_ubuntu-bionic-kernel.git] / block / bfq-iosched.c
index c25955c25e033204293c479b0fbe738ef9129faf..33b63bc4a64b625da02b758a78d96ede306e46f8 100644 (file)
@@ -724,6 +724,44 @@ static void bfq_updated_next_req(struct bfq_data *bfqd,
        }
 }
 
+static unsigned int bfq_wr_duration(struct bfq_data *bfqd)
+{
+       u64 dur;
+
+       if (bfqd->bfq_wr_max_time > 0)
+               return bfqd->bfq_wr_max_time;
+
+       dur = bfqd->RT_prod;
+       do_div(dur, bfqd->peak_rate);
+
+       /*
+        * Limit duration between 3 and 13 seconds. Tests show that
+        * higher values than 13 seconds often yield the opposite of
+        * the desired result, i.e., worsen responsiveness by letting
+        * non-interactive and non-soft-real-time applications
+        * preserve weight raising for a too long time interval.
+        *
+        * On the other end, lower values than 3 seconds make it
+        * difficult for most interactive tasks to complete their jobs
+        * before weight-raising finishes.
+        */
+       if (dur > msecs_to_jiffies(13000))
+               dur = msecs_to_jiffies(13000);
+       else if (dur < msecs_to_jiffies(3000))
+               dur = msecs_to_jiffies(3000);
+
+       return dur;
+}
+
+/* switch back from soft real-time to interactive weight raising */
+static void switch_back_to_interactive_wr(struct bfq_queue *bfqq,
+                                         struct bfq_data *bfqd)
+{
+       bfqq->wr_coeff = bfqd->bfq_wr_coeff;
+       bfqq->wr_cur_max_time = bfq_wr_duration(bfqd);
+       bfqq->last_wr_start_finish = bfqq->wr_start_at_switch_to_srt;
+}
+
 static void
 bfq_bfqq_resume_state(struct bfq_queue *bfqq, struct bfq_data *bfqd,
                      struct bfq_io_cq *bic, bool bfq_already_existing)
@@ -750,10 +788,16 @@ bfq_bfqq_resume_state(struct bfq_queue *bfqq, struct bfq_data *bfqd,
        if (bfqq->wr_coeff > 1 && (bfq_bfqq_in_large_burst(bfqq) ||
            time_is_before_jiffies(bfqq->last_wr_start_finish +
                                   bfqq->wr_cur_max_time))) {
-               bfq_log_bfqq(bfqq->bfqd, bfqq,
-                   "resume state: switching off wr");
-
-               bfqq->wr_coeff = 1;
+               if (bfqq->wr_cur_max_time == bfqd->bfq_wr_rt_max_time &&
+                   !bfq_bfqq_in_large_burst(bfqq) &&
+                   time_is_after_eq_jiffies(bfqq->wr_start_at_switch_to_srt +
+                                            bfq_wr_duration(bfqd))) {
+                       switch_back_to_interactive_wr(bfqq, bfqd);
+               } else {
+                       bfqq->wr_coeff = 1;
+                       bfq_log_bfqq(bfqq->bfqd, bfqq,
+                                    "resume state: switching off wr");
+               }
        }
 
        /* make sure weight will be updated, however we got here */
@@ -1173,35 +1217,6 @@ static bool bfq_bfqq_update_budg_for_activation(struct bfq_data *bfqd,
        return wr_or_deserves_wr;
 }
 
-static unsigned int bfq_wr_duration(struct bfq_data *bfqd)
-{
-       u64 dur;
-
-       if (bfqd->bfq_wr_max_time > 0)
-               return bfqd->bfq_wr_max_time;
-
-       dur = bfqd->RT_prod;
-       do_div(dur, bfqd->peak_rate);
-
-       /*
-        * Limit duration between 3 and 13 seconds. Tests show that
-        * higher values than 13 seconds often yield the opposite of
-        * the desired result, i.e., worsen responsiveness by letting
-        * non-interactive and non-soft-real-time applications
-        * preserve weight raising for a too long time interval.
-        *
-        * On the other end, lower values than 3 seconds make it
-        * difficult for most interactive tasks to complete their jobs
-        * before weight-raising finishes.
-        */
-       if (dur > msecs_to_jiffies(13000))
-               dur = msecs_to_jiffies(13000);
-       else if (dur < msecs_to_jiffies(3000))
-               dur = msecs_to_jiffies(3000);
-
-       return dur;
-}
-
 /*
  * Return the farthest future time instant according to jiffies
  * macros.
@@ -3501,11 +3516,7 @@ static void bfq_update_wr_data(struct bfq_data *bfqd, struct bfq_queue *bfqq)
                                               bfq_wr_duration(bfqd)))
                                bfq_bfqq_end_wr(bfqq);
                        else {
-                               /* switch back to interactive wr */
-                               bfqq->wr_coeff = bfqd->bfq_wr_coeff;
-                               bfqq->wr_cur_max_time = bfq_wr_duration(bfqd);
-                               bfqq->last_wr_start_finish =
-                                       bfqq->wr_start_at_switch_to_srt;
+                               switch_back_to_interactive_wr(bfqq, bfqd);
                                bfqq->entity.prio_changed = 1;
                        }
                }