Re: [RFC PATCH 1/8] block: Change the dispatch_request() API to support batch requests

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Jens and Paolo,

On Fri, Jan 17, 2020 at 1:25 PM Baolin Wang <baolin.wang7@xxxxxxxxx> wrote:
>
> Now some SD/MMC host controllers can support packed command or packed request,
> that means we can package several requests to host controller at one time
> to improve performence.
>
> But the blk-mq always takes one request from the scheduler and dispatch it to
> the device, regardless of the driver or the scheduler, so there should only
> ever be one request in the local list in blk_mq_dispatch_rq_list(), that means
> the bd.last is always true and the driver can not use bd.last to decide if
> there are requests are pending now in hardware queue to help to package
> requests.
>
> Thus this is a preparation patch, which tries to change the dispatch_request()
> API to allow dispatching more than one request from the scheduler.

Do you have any comments for patch 1 and patch 2 in this patch set? Thanks.

> Suggested-by: Arnd Bergmann <arnd@xxxxxxxx>
> Signed-off-by: Baolin Wang <baolin.wang7@xxxxxxxxx>
> ---
>  block/bfq-iosched.c      |   12 +++++++++---
>  block/blk-mq-sched.c     |   15 ++++-----------
>  block/kyber-iosched.c    |   20 +++++++++++++-------
>  block/mq-deadline.c      |   12 +++++++++---
>  include/linux/elevator.h |    2 +-
>  5 files changed, 36 insertions(+), 25 deletions(-)
>
> diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c
> index ad4af4a..decabc4 100644
> --- a/block/bfq-iosched.c
> +++ b/block/bfq-iosched.c
> @@ -4774,7 +4774,8 @@ static inline void bfq_update_dispatch_stats(struct request_queue *q,
>                                              bool idle_timer_disabled) {}
>  #endif /* CONFIG_BFQ_CGROUP_DEBUG */
>
> -static struct request *bfq_dispatch_request(struct blk_mq_hw_ctx *hctx)
> +static int bfq_dispatch_requests(struct blk_mq_hw_ctx *hctx,
> +                                struct list_head *list)
>  {
>         struct bfq_data *bfqd = hctx->queue->elevator->elevator_data;
>         struct request *rq;
> @@ -4796,7 +4797,12 @@ static struct request *bfq_dispatch_request(struct blk_mq_hw_ctx *hctx)
>         bfq_update_dispatch_stats(hctx->queue, rq, in_serv_queue,
>                                   idle_timer_disabled);
>
> -       return rq;
> +       if (!rq)
> +               return 0;
> +
> +       list_add(&rq->queuelist, list);
> +
> +       return 1;
>  }
>
>  /*
> @@ -6772,7 +6778,7 @@ static ssize_t bfq_low_latency_store(struct elevator_queue *e,
>                 .finish_request         = bfq_finish_requeue_request,
>                 .exit_icq               = bfq_exit_icq,
>                 .insert_requests        = bfq_insert_requests,
> -               .dispatch_request       = bfq_dispatch_request,
> +               .dispatch_requests      = bfq_dispatch_requests,
>                 .next_request           = elv_rb_latter_request,
>                 .former_request         = elv_rb_former_request,
>                 .allow_merge            = bfq_allow_bio_merge,
> diff --git a/block/blk-mq-sched.c b/block/blk-mq-sched.c
> index ca22afd..f49f9d9 100644
> --- a/block/blk-mq-sched.c
> +++ b/block/blk-mq-sched.c
> @@ -90,28 +90,21 @@ static void blk_mq_do_dispatch_sched(struct blk_mq_hw_ctx *hctx)
>         struct request_queue *q = hctx->queue;
>         struct elevator_queue *e = q->elevator;
>         LIST_HEAD(rq_list);
> +       int ret;
>
>         do {
> -               struct request *rq;
> -
>                 if (e->type->ops.has_work && !e->type->ops.has_work(hctx))
>                         break;
>
>                 if (!blk_mq_get_dispatch_budget(hctx))
>                         break;
>
> -               rq = e->type->ops.dispatch_request(hctx);
> -               if (!rq) {
> +               ret = e->type->ops.dispatch_requests(hctx, &rq_list);
> +               if (ret == 0) {
>                         blk_mq_put_dispatch_budget(hctx);
>                         break;
>                 }
>
> -               /*
> -                * Now this rq owns the budget which has to be released
> -                * if this rq won't be queued to driver via .queue_rq()
> -                * in blk_mq_dispatch_rq_list().
> -                */
> -               list_add(&rq->queuelist, &rq_list);
>         } while (blk_mq_dispatch_rq_list(q, &rq_list, true));
>  }
>
> @@ -171,7 +164,7 @@ void blk_mq_sched_dispatch_requests(struct blk_mq_hw_ctx *hctx)
>  {
>         struct request_queue *q = hctx->queue;
>         struct elevator_queue *e = q->elevator;
> -       const bool has_sched_dispatch = e && e->type->ops.dispatch_request;
> +       const bool has_sched_dispatch = e && e->type->ops.dispatch_requests;
>         LIST_HEAD(rq_list);
>
>         /* RCU or SRCU read lock is needed before checking quiesced flag */
> diff --git a/block/kyber-iosched.c b/block/kyber-iosched.c
> index 34dcea0..8f58434 100644
> --- a/block/kyber-iosched.c
> +++ b/block/kyber-iosched.c
> @@ -796,12 +796,13 @@ static int kyber_get_domain_token(struct kyber_queue_data *kqd,
>         return NULL;
>  }
>
> -static struct request *kyber_dispatch_request(struct blk_mq_hw_ctx *hctx)
> +static int kyber_dispatch_requests(struct blk_mq_hw_ctx *hctx,
> +                                  struct list_head *list)
>  {
>         struct kyber_queue_data *kqd = hctx->queue->elevator->elevator_data;
>         struct kyber_hctx_data *khd = hctx->sched_data;
>         struct request *rq;
> -       int i;
> +       int i, ret = 0;
>
>         spin_lock(&khd->lock);
>
> @@ -811,8 +812,11 @@ static struct request *kyber_dispatch_request(struct blk_mq_hw_ctx *hctx)
>          */
>         if (khd->batching < kyber_batch_size[khd->cur_domain]) {
>                 rq = kyber_dispatch_cur_domain(kqd, khd, hctx);
> -               if (rq)
> +               if (rq) {
> +                       list_add(&rq->queuelist, list);
> +                       ret = 1;
>                         goto out;
> +               }
>         }
>
>         /*
> @@ -832,14 +836,16 @@ static struct request *kyber_dispatch_request(struct blk_mq_hw_ctx *hctx)
>                         khd->cur_domain++;
>
>                 rq = kyber_dispatch_cur_domain(kqd, khd, hctx);
> -               if (rq)
> +               if (rq) {
> +                       list_add(&rq->queuelist, list);
> +                       ret = 1;
>                         goto out;
> +               }
>         }
>
> -       rq = NULL;
>  out:
>         spin_unlock(&khd->lock);
> -       return rq;
> +       return ret;
>  }
>
>  static bool kyber_has_work(struct blk_mq_hw_ctx *hctx)
> @@ -1020,7 +1026,7 @@ static int kyber_batching_show(void *data, struct seq_file *m)
>                 .finish_request = kyber_finish_request,
>                 .requeue_request = kyber_finish_request,
>                 .completed_request = kyber_completed_request,
> -               .dispatch_request = kyber_dispatch_request,
> +               .dispatch_requests = kyber_dispatch_requests,
>                 .has_work = kyber_has_work,
>         },
>  #ifdef CONFIG_BLK_DEBUG_FS
> diff --git a/block/mq-deadline.c b/block/mq-deadline.c
> index b490f47..9fbffba 100644
> --- a/block/mq-deadline.c
> +++ b/block/mq-deadline.c
> @@ -378,7 +378,8 @@ static struct request *__dd_dispatch_request(struct deadline_data *dd)
>   * different hardware queue. This is because mq-deadline has shared
>   * state for all hardware queues, in terms of sorting, FIFOs, etc.
>   */
> -static struct request *dd_dispatch_request(struct blk_mq_hw_ctx *hctx)
> +static int dd_dispatch_requests(struct blk_mq_hw_ctx *hctx,
> +                               struct list_head *list)
>  {
>         struct deadline_data *dd = hctx->queue->elevator->elevator_data;
>         struct request *rq;
> @@ -387,7 +388,12 @@ static struct request *dd_dispatch_request(struct blk_mq_hw_ctx *hctx)
>         rq = __dd_dispatch_request(dd);
>         spin_unlock(&dd->lock);
>
> -       return rq;
> +       if (!rq)
> +               return 0;
> +
> +       list_add(&rq->queuelist, list);
> +
> +       return 1;
>  }
>
>  static void dd_exit_queue(struct elevator_queue *e)
> @@ -774,7 +780,7 @@ static void deadline_dispatch_stop(struct seq_file *m, void *v)
>  static struct elevator_type mq_deadline = {
>         .ops = {
>                 .insert_requests        = dd_insert_requests,
> -               .dispatch_request       = dd_dispatch_request,
> +               .dispatch_requests      = dd_dispatch_requests,
>                 .prepare_request        = dd_prepare_request,
>                 .finish_request         = dd_finish_request,
>                 .next_request           = elv_rb_latter_request,
> diff --git a/include/linux/elevator.h b/include/linux/elevator.h
> index 901bda3..a65bf5d 100644
> --- a/include/linux/elevator.h
> +++ b/include/linux/elevator.h
> @@ -42,7 +42,7 @@ struct elevator_mq_ops {
>         void (*prepare_request)(struct request *, struct bio *bio);
>         void (*finish_request)(struct request *);
>         void (*insert_requests)(struct blk_mq_hw_ctx *, struct list_head *, bool);
> -       struct request *(*dispatch_request)(struct blk_mq_hw_ctx *);
> +       int (*dispatch_requests)(struct blk_mq_hw_ctx *, struct list_head *);
>         bool (*has_work)(struct blk_mq_hw_ctx *);
>         void (*completed_request)(struct request *, u64);
>         void (*requeue_request)(struct request *);
> --
> 1.7.9.5
>



[Index of Archives]     [Linux Memonry Technology]     [Linux USB Devel]     [Linux Media]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux