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@xxxxxxxxxxxxx> --- block/blk-mq.c | 6 ++++++ include/linux/blk-mq.h | 1 + 2 files changed, 7 insertions(+) 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); -- 2.33.0