block, bfq: fix switch back from soft-rt weitgh-raising
authorPaolo Valente <paolo.valente@linaro.org>
Mon, 25 Jan 2021 19:02:45 +0000 (20:02 +0100)
committerJens Axboe <axboe@kernel.dk>
Mon, 25 Jan 2021 21:18:32 +0000 (14:18 -0700)
A bfq_queue may happen to be deemed as soft real-time while it is
still enjoying interactive weight-raising. If this happens because of
a false positive, then the bfq_queue is likely to loose its soft
real-time status soon. Upon losing such a status, the bfq_queue must
get back its interactive weight-raising, if its interactive period is
not over yet. But this case is not handled. This commit corrects this
error.

Tested-by: Jan Kara <jack@suse.cz>
Signed-off-by: Paolo Valente <paolo.valente@linaro.org>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
block/bfq-iosched.c

index 44c6433..170aa0c 100644 (file)
@@ -5290,8 +5290,26 @@ bfq_update_io_seektime(struct bfq_data *bfqd, struct bfq_queue *bfqq,
 
        if (bfqq->wr_coeff > 1 &&
            bfqq->wr_cur_max_time == bfqd->bfq_wr_rt_max_time &&
-           BFQQ_TOTALLY_SEEKY(bfqq))
-               bfq_bfqq_end_wr(bfqq);
+           BFQQ_TOTALLY_SEEKY(bfqq)) {
+               if (time_is_before_jiffies(bfqq->wr_start_at_switch_to_srt +
+                                          bfq_wr_duration(bfqd))) {
+                       /*
+                        * In soft_rt weight raising with the
+                        * interactive-weight-raising period
+                        * elapsed (so no switch back to
+                        * interactive weight raising).
+                        */
+                       bfq_bfqq_end_wr(bfqq);
+               } else { /*
+                         * stopping soft_rt weight raising
+                         * while still in interactive period,
+                         * switch back to interactive weight
+                         * raising
+                         */
+                       switch_back_to_interactive_wr(bfqq, bfqd);
+                       bfqq->entity.prio_changed = 1;
+               }
+       }
 }
 
 static void bfq_update_has_short_ttime(struct bfq_data *bfqd,