From: Chunguang Xu <[email protected]>

Expire bfqq not belong to CLASS_RT and CLASS_RT is waiting for
service, we can further guarantee the latency for CLASS_RT.

Signed-off-by: Chunguang Xu <[email protected]>
---
 block/bfq-iosched.c | 15 ++++++++++-----
 block/bfq-iosched.h |  8 ++++++++
 block/bfq-wf2q.c    | 12 ++++++++++++
 3 files changed, 30 insertions(+), 5 deletions(-)

diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c
index ab00b664348c..8af73473c45c 100644
--- a/block/bfq-iosched.c
+++ b/block/bfq-iosched.c
@@ -428,6 +428,7 @@ void bfq_schedule_dispatch(struct bfq_data *bfqd)
        }
 }
 
+#define bfq_class_rt(bfqq)     ((bfqq)->ioprio_class == IOPRIO_CLASS_RT)
 #define bfq_class_idle(bfqq)   ((bfqq)->ioprio_class == IOPRIO_CLASS_IDLE)
 
 #define bfq_sample_valid(samples)      ((samples) > 80)
@@ -4709,12 +4710,16 @@ static struct request *bfq_dispatch_rq_from_bfqq(struct 
bfq_data *bfqd,
        /*
         * Expire bfqq, pretending that its budget expired, if bfqq
         * belongs to CLASS_IDLE and other queues are waiting for
-        * service.
+        * service, or if bfqq not belongs to CLASS_RT and CLASS_RT
+        * is waiting for service.
         */
-       if (!(bfq_tot_busy_queues(bfqd) > 1 && bfq_class_idle(bfqq)))
-               goto return_rq;
-
-       bfq_bfqq_expire(bfqd, bfqq, false, BFQQE_BUDGET_EXHAUSTED);
+#ifdef CONFIG_BFQ_GROUP_IOSCHED
+       if ((bfq_tot_busy_queues(bfqd) > 1 && bfq_class_idle(bfqq)) ||
+           (!bfq_class_rt(bfqq) && bfqd->busy_groups[0]))
+#else
+       if (bfq_tot_busy_queues(bfqd) > 1 && bfq_class_idle(bfqq))
+#endif
+               bfq_bfqq_expire(bfqd, bfqq, false, BFQQE_BUDGET_EXHAUSTED);
 
 return_rq:
        return rq;
diff --git a/block/bfq-iosched.h b/block/bfq-iosched.h
index de7301664ad3..6b87ba53db94 100644
--- a/block/bfq-iosched.h
+++ b/block/bfq-iosched.h
@@ -531,6 +531,14 @@ struct bfq_data {
         */
        unsigned int num_groups_with_pending_reqs;
 
+#ifdef CONFIG_BFQ_GROUP_IOSCHED
+       /*
+        * Per-class (RT, BE, IDLE) number of bfq_groups waiting for
+        * service.
+        */
+       unsigned int busy_groups[3];
+#endif
+
        /*
         * Per-class (RT, BE, IDLE) number of bfq_queues containing
         * requests (including the queue in service, even if it is
diff --git a/block/bfq-wf2q.c b/block/bfq-wf2q.c
index 0ac35fd4f2ab..f6c67a80e454 100644
--- a/block/bfq-wf2q.c
+++ b/block/bfq-wf2q.c
@@ -1032,11 +1032,14 @@ static void __bfq_activate_entity(struct bfq_entity 
*entity,
        if (!bfq_entity_to_bfqq(entity)) { /* bfq_group */
                struct bfq_group *bfqg = bfq_entity_to_bfqg(entity);
                struct bfq_data *bfqd = bfqg->bfqd;
+               int idx = bfq_class_idx(entity);
 
                if (!entity->in_groups_with_pending_reqs) {
                        entity->in_groups_with_pending_reqs = true;
                        bfqd->num_groups_with_pending_reqs++;
                }
+
+               bfqd->busy_groups[idx]++;
        }
 #endif
 
@@ -1188,6 +1191,9 @@ bool __bfq_deactivate_entity(struct bfq_entity *entity, 
bool ins_into_idle_tree)
 {
        struct bfq_sched_data *sd = entity->sched_data;
        struct bfq_service_tree *st;
+#ifdef CONFIG_BFQ_GROUP_IOSCHED
+       struct bfq_group *bfqg;
+#endif
        int idx = bfq_class_idx(entity);
        bool is_in_service;
 
@@ -1229,6 +1235,12 @@ bool __bfq_deactivate_entity(struct bfq_entity *entity, 
bool ins_into_idle_tree)
                bfq_idle_insert(st, entity);
 
        sd->bfq_class_last_service[idx] = jiffies;
+#ifdef CONFIG_BFQ_GROUP_IOSCHED
+       bfqg = bfq_entity_to_bfqg(entity);
+       if (bfqg)
+               bfqg->bfqd->busy_groups[idx]--;
+#endif
+
        return true;
 }
 
-- 
2.30.0

Reply via email to