diff mbox series

[RFC,1/3] blk-mq: Add blk_mq_complete_request_direct()

Message ID 20211015151412.3229037-2-bigeasy@linutronix.de (mailing list archive)
State New, archived
Headers show
Series blk-mq: Allow to complete requests directly | expand

Commit Message

Sebastian Andrzej Siewior Oct. 15, 2021, 3:14 p.m. UTC
Add blk_mq_complete_request_direct() which completes the block request
directly instead deferring it to softirq for single queue devices.

This is useful for devices which complete the requests in preemptible
context and raising softirq from means scheduling ksoftirqd.

Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
---
 block/blk-mq.c         | 6 ++++++
 include/linux/blk-mq.h | 1 +
 2 files changed, 7 insertions(+)

Comments

Christoph Hellwig Oct. 15, 2021, 4:03 p.m. UTC | #1
On Fri, Oct 15, 2021 at 05:14:10PM +0200, Sebastian Andrzej Siewior wrote:
> +void blk_mq_complete_request_direct(struct request *rq)
> +{
> +	WRITE_ONCE(rq->state, MQ_RQ_COMPLETE);
> +	rq->q->mq_ops->complete(rq);
> +}

As this is called by the driver we known what ->complete this helper
would call.  So instead of doing this we could just call
blk_mq_set_request_complete and the actual completion helper.
The comment above it will need some updates of course.
Sebastian Andrzej Siewior Oct. 15, 2021, 4:15 p.m. UTC | #2
On 2021-10-15 09:03:28 [-0700], Christoph Hellwig wrote:
> On Fri, Oct 15, 2021 at 05:14:10PM +0200, Sebastian Andrzej Siewior wrote:
> > +void blk_mq_complete_request_direct(struct request *rq)
> > +{
> > +	WRITE_ONCE(rq->state, MQ_RQ_COMPLETE);
> > +	rq->q->mq_ops->complete(rq);
> > +}
> 
> As this is called by the driver we known what ->complete this helper
> would call.  So instead of doing this we could just call
> blk_mq_set_request_complete and the actual completion helper.
> The comment above it will need some updates of course.

So
	blk_mq_set_request_complete();
	mmc_blk_mq_complete();

for the mmc driver and no fiddling in the blk-mq then.

Sebastian
Jens Axboe Oct. 17, 2021, 4:19 p.m. UTC | #3
On 10/15/21 10:15 AM, Sebastian Andrzej Siewior wrote:
> On 2021-10-15 09:03:28 [-0700], Christoph Hellwig wrote:
>> On Fri, Oct 15, 2021 at 05:14:10PM +0200, Sebastian Andrzej Siewior wrote:
>>> +void blk_mq_complete_request_direct(struct request *rq)
>>> +{
>>> +	WRITE_ONCE(rq->state, MQ_RQ_COMPLETE);
>>> +	rq->q->mq_ops->complete(rq);
>>> +}
>>
>> As this is called by the driver we known what ->complete this helper
>> would call.  So instead of doing this we could just call
>> blk_mq_set_request_complete and the actual completion helper.
>> The comment above it will need some updates of course.
> 
> So
> 	blk_mq_set_request_complete();
> 	mmc_blk_mq_complete();
> 
> for the mmc driver and no fiddling in the blk-mq then.

Just pass in the handler:

void blk_mq_complete_request_direct(struct request *rq,
				    void (*complete)(struct request *rq))
{
	WRITE_ONCE(rq->state, MQ_RQ_COMPLETE);
	complete(rq);
}

And we should probably put it in blk-mq.h so it inlines nicely, and
that'll be faster than the indirect call.
diff mbox series

Patch

diff --git a/block/blk-mq.c b/block/blk-mq.c
index 108a352051be5..44582aef3c32c 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -667,6 +667,12 @@  bool blk_mq_complete_request_remote(struct request *rq)
 }
 EXPORT_SYMBOL_GPL(blk_mq_complete_request_remote);
 
+void blk_mq_complete_request_direct(struct request *rq)
+{
+	WRITE_ONCE(rq->state, MQ_RQ_COMPLETE);
+	rq->q->mq_ops->complete(rq);
+}
+
 /**
  * blk_mq_complete_request - end I/O on a request
  * @rq:		the request being processed
diff --git a/include/linux/blk-mq.h b/include/linux/blk-mq.h
index 13ba1861e688f..df9ea4c5d91c9 100644
--- a/include/linux/blk-mq.h
+++ b/include/linux/blk-mq.h
@@ -528,6 +528,7 @@  void __blk_mq_end_request(struct request *rq, blk_status_t error);
 void blk_mq_requeue_request(struct request *rq, bool kick_requeue_list);
 void blk_mq_kick_requeue_list(struct request_queue *q);
 void blk_mq_delay_kick_requeue_list(struct request_queue *q, unsigned long msecs);
+void blk_mq_complete_request_direct(struct request *rq);
 void blk_mq_complete_request(struct request *rq);
 bool blk_mq_complete_request_remote(struct request *rq);
 bool blk_mq_queue_stopped(struct request_queue *q);