block, bfq: update inject limit only after injection occurred
[linux-2.6-block.git] / block / bfq-iosched.c
index b33be928d164fef34f5d2f00863d9034e38ef1a2..5a2bbd8613a86def2dbbd0889fa382674087a7d2 100644 (file)
@@ -2025,7 +2025,21 @@ static void bfq_add_request(struct request *rq)
                         * be set when rq will be dispatched.
                         */
                        bfqd->wait_dispatch = true;
-                       bfqd->rqs_injected = false;
+                       /*
+                        * If there is no I/O in service in the drive,
+                        * then possible injection occurred before the
+                        * arrival of rq will not affect the total
+                        * service time of rq. So the injection limit
+                        * must not be updated as a function of such
+                        * total service time, unless new injection
+                        * occurs before rq is completed. To have the
+                        * injection limit updated only in the latter
+                        * case, reset rqs_injected here (rqs_injected
+                        * will be set in case injection is performed
+                        * on bfqq before rq is completed).
+                        */
+                       if (bfqd->rq_in_driver == 0)
+                               bfqd->rqs_injected = false;
                }
        }
 
@@ -5784,7 +5798,7 @@ static void bfq_update_inject_limit(struct bfq_data *bfqd,
        u64 tot_time_ns = ktime_get_ns() - bfqd->last_empty_occupied_ns;
        unsigned int old_limit = bfqq->inject_limit;
 
-       if (bfqq->last_serv_time_ns > 0) {
+       if (bfqq->last_serv_time_ns > 0 && bfqd->rqs_injected) {
                u64 threshold = (bfqq->last_serv_time_ns * 3)>>1;
 
                if (tot_time_ns >= threshold && old_limit > 0) {
@@ -5830,6 +5844,7 @@ static void bfq_update_inject_limit(struct bfq_data *bfqd,
 
        /* update complete, not waiting for any request completion any longer */
        bfqd->waited_rq = NULL;
+       bfqd->rqs_injected = false;
 }
 
 /*