On Thu, 2018-12-20 at 15:50 -0700, Jens Axboe wrote:
> +static void blk_fq_rcu_free(struct work_struct *work)
> +{
> +     struct blk_flush_queue *fq = container_of(to_rcu_work(work),
> +                                                     struct blk_flush_queue,
> +                                                     rcu_work);
> +
> +     kfree(fq->flush_rq);
> +     kfree(fq);
> +}
> +
>  void blk_free_flush_queue(struct blk_flush_queue *fq)
>  {
>       /* bio based request queue hasn't flush queue */
>       if (!fq)
>               return;
>  
> -     kfree(fq->flush_rq);
> -     kfree(fq);
> +     INIT_RCU_WORK(&fq->rcu_work, blk_fq_rcu_free);
> +     queue_rcu_work(system_wq, &fq->rcu_work);
>  }

Can INIT_RCU_WORK() + queue_rcu_work() be changed into call_rcu()? The latter
namely uses a smaller data structure.

> diff --git a/block/blk-mq-tag.c b/block/blk-mq-tag.c
> index 2089c6c62f44..c39b58391ae8 100644
> --- a/block/blk-mq-tag.c
> +++ b/block/blk-mq-tag.c
> @@ -228,13 +228,15 @@ static bool bt_iter(struct sbitmap *bitmap, unsigned 
> int bitnr, void *data)
>  
>       if (!reserved)
>               bitnr += tags->nr_reserved_tags;
> -     rq = tags->rqs[bitnr];
> +     if (tags->rqs[bitnr].queue != hctx->queue)
> +             return true;

Since blk_mq_tag_set_rq() is not serialized against this function I doubt that
the tags->rqs[bitnr].queue != hctx->queue check helps. Can it be left out?

> +struct rq_tag_entry {
> +       struct request_queue *queue;
> +       struct request *rq;

If the new test can be left out from bt_iter(), can this new data structure be
left out too? In other words, keep the existing approach of only storing the
request pointer and not the queue pointer.

Thanks,

Bart.

Reply via email to