From: Chunguang Xu <brookxu@xxxxxxxxxxx> 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 <brookxu@xxxxxxxxxxx> --- 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