Re: [PATCH 1/1] block: Use RCU in blk_mq_[un]quiesce_tagset() instead of set->tag_list_lock

Bart Van Assche
2025-12-08T19:22:47Z

On 12/4/25 6:32 PM, Keith Busch wrote:
> static void blk_mq_del_queue_tag_set(struct request_queue *q)
> {
> struct blk_mq_tag_set *set = q->tag_set;
> + struct request_queue *shared = NULL;
>
> mutex_lock(&set->tag_list_lock);
> list_del(&q->tag_set_list);
> @@ -4302,15 +4305,25 @@ static void blk_mq_del_queue_tag_set(struct request_queue *q)
> /* just transitioned to unshared */
> set->flags &= ~BLK_MQ_F_TAG_QUEUE_SHARED;
> /* update existing queue */
> - blk_mq_update_tag_set_shared(set, false);
> + shared = list_first_entry(&set->tag_list, struct request_queue,
> + tag_set_list);
> + if (!blk_get_queue(shared))
> + shared = NULL;
> }
> mutex_unlock(&set->tag_list_lock);
> INIT_LIST_HEAD(&q->tag_set_list);
> +
> + if (shared) {
> + queue_set_hctx_shared(shared);
> + blk_put_queue(shared);
> + }
> }

Although harmless, with this approach the queue_set_hctx_shared() calls
by blk_mq_del_queue_tag_set() and blk_mq_add_queue_tag_set() can be
reordered. I like Mohamed's approach better because it results in code
that is easier to review and to reason about.

Thanks,

Bart.