From: Yu Kuai <yukuai3@xxxxxxxxxx> ioc_lookup_icq() is used by bfq to lookup bfqq from IO path, the helper have to be protected by queue_lock, which is too heavy. Hence add a new helper that is lookless, this is safe because both request_queue and ioc can be pinged by IO that is still issuing. Signed-off-by: Yu Kuai <yukuai3@xxxxxxxxxx> --- block/blk-ioc.c | 34 ++++++++++++++++++++++++++++++++++ block/blk.h | 1 + 2 files changed, 35 insertions(+) diff --git a/block/blk-ioc.c b/block/blk-ioc.c index ce82770c72ab..4945b48dfdb6 100644 --- a/block/blk-ioc.c +++ b/block/blk-ioc.c @@ -343,6 +343,40 @@ struct io_cq *ioc_lookup_icq(struct request_queue *q) } EXPORT_SYMBOL(ioc_lookup_icq); +/** + * ioc_lookup_icq_rcu - lookup io_cq from ioc in io path + * @q: the associated request_queue + * + * Look up io_cq associated with @ioc - @q pair from @ioc. Must be called from + * io issue path, either return NULL if current issue io to @q for the first + * time, or return a valid icq. + */ +struct io_cq *ioc_lookup_icq_rcu(struct request_queue *q) +{ + struct io_context *ioc = current->io_context; + struct io_cq *icq; + + WARN_ON_ONCE(percpu_ref_is_zero(&q->q_usage_counter)); + + if (!ioc) + return NULL; + + icq = rcu_dereference(ioc->icq_hint); + if (icq && icq->q == q) + return icq; + + icq = radix_tree_lookup(&ioc->icq_tree, q->id); + if (!icq) + return NULL; + + if (WARN_ON_ONCE(icq->q != q)) + return NULL; + + rcu_assign_pointer(ioc->icq_hint, icq); + return icq; +} +EXPORT_SYMBOL(ioc_lookup_icq_rcu); + /** * ioc_create_icq - create and link io_cq * @q: request_queue of interest diff --git a/block/blk.h b/block/blk.h index 468aa83c5a22..ef31b3ec1c69 100644 --- a/block/blk.h +++ b/block/blk.h @@ -461,6 +461,7 @@ static inline void req_set_nomerge(struct request_queue *q, struct request *req) */ struct io_cq *ioc_find_get_icq(struct request_queue *q); struct io_cq *ioc_lookup_icq(struct request_queue *q); +struct io_cq *ioc_lookup_icq_rcu(struct request_queue *q); #ifdef CONFIG_BLK_ICQ void ioc_clear_queue(struct request_queue *q); #else -- 2.39.2