From: Ming Lei <ming.lei@xxxxxxxxxx> Disable preempt for a little while during allocating request tag, so request's tag(internal tag) is always allocated on the cpu of data->ctx, prepare for improving to handle cpu hotplug during allocating request. In the following patch, hctx->state will be checked to see if it becomes inactive which is always set on the last CPU of hctx->cpumask. Signed-off-by: Ming Lei <ming.lei@xxxxxxxxxx> [hch: keep the preempt disable confined inside blk_mq_get_tag] Signed-off-by: Christoph Hellwig <hch@xxxxxx> --- block/blk-mq-tag.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/block/blk-mq-tag.c b/block/blk-mq-tag.c index b526f1f5a3bf3..0cc38883618b9 100644 --- a/block/blk-mq-tag.c +++ b/block/blk-mq-tag.c @@ -108,6 +108,7 @@ unsigned int blk_mq_get_tag(struct blk_mq_alloc_data *data) unsigned int tag_offset; int tag; + preempt_disable(); data->ctx = blk_mq_get_ctx(data->q); data->hctx = blk_mq_map_queue(data->q, data->cmd_flags, data->ctx); tags = blk_mq_tags_from_data(data); @@ -115,10 +116,8 @@ unsigned int blk_mq_get_tag(struct blk_mq_alloc_data *data) blk_mq_tag_busy(data->hctx); if (data->flags & BLK_MQ_REQ_RESERVED) { - if (unlikely(!tags->nr_reserved_tags)) { - WARN_ON_ONCE(1); - return BLK_MQ_TAG_FAIL; - } + if (WARN_ON_ONCE(!tags->nr_reserved_tags)) + goto fail; bt = &tags->breserved_tags; tag_offset = 0; } else { @@ -131,7 +130,7 @@ unsigned int blk_mq_get_tag(struct blk_mq_alloc_data *data) goto found_tag; if (data->flags & BLK_MQ_REQ_NOWAIT) - return BLK_MQ_TAG_FAIL; + goto fail; ws = bt_wait_ptr(bt, data->hctx); do { @@ -158,11 +157,13 @@ unsigned int blk_mq_get_tag(struct blk_mq_alloc_data *data) if (tag != -1) break; + preempt_enable(); + bt_prev = bt; io_schedule(); - sbitmap_finish_wait(bt, ws, &wait); + preempt_disable(); data->ctx = blk_mq_get_ctx(data->q); data->hctx = blk_mq_map_queue(data->q, data->cmd_flags, data->ctx); @@ -186,7 +187,11 @@ unsigned int blk_mq_get_tag(struct blk_mq_alloc_data *data) sbitmap_finish_wait(bt, ws, &wait); found_tag: + preempt_enable(); return tag + tag_offset; +fail: + preempt_enable(); + return BLK_MQ_TAG_FAIL; } bool __blk_mq_get_driver_tag(struct request *rq) -- 2.26.2