[PATCH rfc v2 1/4] blk-mq: add async quiesce interface for blocking hw queues

Sagi Grimberg sagi at grimberg.me
Sat Jul 25 13:35:01 EDT 2020


> Looks great. One suggest: srcu provide the batch sync mechanism,
> it may be more generic. Weakness: for the same srcu, concurrent batch
> waiting is not supported. The code just for TINY_SRCU:

Doesn't make sense to me...

But what I was thinking is not to do this only for blocking queues, we
can easily use call_rcu for non-blocking queues as well..

i.e.
--
void blk_mq_quiesce_queue_async(struct request_queue *q)
{
         struct blk_mq_hw_ctx *hctx;
         unsigned int i;

         blk_mq_quiesce_queue_nowait(q);

         queue_for_each_hw_ctx(q, hctx, i) {
                 init_completion(&hctx->rcu_sync.completion);
                 init_rcu_head(&hctx->rcu_sync.head);
                 if (hctx->flags & BLK_MQ_F_BLOCKING)
                         call_srcu(hctx->srcu, &hctx->rcu_sync.head,
                                 wakeme_after_rcu);
                 else
                         call_rcu(hctx->srcu, &hctx->rcu_sync.head,
                                 wakeme_after_rcu);
         }
}
EXPORT_SYMBOL_GPL(blk_mq_quiesce_blocking_queue_async);

void blk_mq_quiesce_queue_async_wait(struct request_queue *q)
{
         struct blk_mq_hw_ctx *hctx;
         unsigned int i;

         queue_for_each_hw_ctx(q, hctx, i) {
                 wait_for_completion(&hctx->rcu_sync.completion);
                 destroy_rcu_head(&hctx->rcu_sync.head);
         }
}
EXPORT_SYMBOL_GPL(blk_mq_quiesce_blocking_queue_async_wait);
--

And then in nvme we always use that...

Thoughts?



More information about the Linux-nvme mailing list