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. Cc: Bart Van Assche <bvanassche@xxxxxxx> Cc: Hannes Reinecke <hare@xxxxxxxx> Cc: Christoph Hellwig <hch@xxxxxx> Cc: Thomas Gleixner <tglx@xxxxxxxxxxxxx> Cc: John Garry <john.garry@xxxxxxxxxx> Signed-off-by: Ming Lei <ming.lei@xxxxxxxxxx> --- block/blk-mq-tag.c | 4 ++++ block/blk-mq.c | 4 ++++ block/blk-mq.h | 1 + 3 files changed, 9 insertions(+) diff --git a/block/blk-mq-tag.c b/block/blk-mq-tag.c index c27c6dfc7d36..0ae79ca6e2da 100644 --- a/block/blk-mq-tag.c +++ b/block/blk-mq-tag.c @@ -152,11 +152,15 @@ unsigned int blk_mq_get_tag(struct blk_mq_alloc_data *data) if (tag != -1) break; + if (data->preempt_disabled) + preempt_enable(); bt_prev = bt; io_schedule(); sbitmap_finish_wait(bt, ws, &wait); + if (data->preempt_disabled) + preempt_disable(); data->ctx = blk_mq_get_ctx(data->q); data->hctx = blk_mq_map_queue(data->q, data->cmd_flags, data->ctx); diff --git a/block/blk-mq.c b/block/blk-mq.c index 151b63b1f88b..18999198a37f 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c @@ -365,6 +365,9 @@ static struct request *blk_mq_get_request(struct request_queue *q, data->q = q; WARN_ON_ONCE(data->ctx || data->hctx); + + preempt_disable(); + data->preempt_disabled = true; data->ctx = blk_mq_get_ctx(q); data->hctx = blk_mq_map_queue(q, data->cmd_flags, data->ctx); if (data->cmd_flags & REQ_NOWAIT) @@ -387,6 +390,7 @@ static struct request *blk_mq_get_request(struct request_queue *q, } tag = blk_mq_get_tag(data); + preempt_enable(); if (tag == BLK_MQ_TAG_FAIL) { data->ctx = NULL; data->hctx = NULL; diff --git a/block/blk-mq.h b/block/blk-mq.h index 10bfdfb494fa..5ebc8d8d5a54 100644 --- a/block/blk-mq.h +++ b/block/blk-mq.h @@ -152,6 +152,7 @@ struct blk_mq_alloc_data { blk_mq_req_flags_t flags; unsigned int shallow_depth; unsigned int cmd_flags; + bool preempt_disabled; /* input & output parameter */ struct blk_mq_ctx *ctx; -- 2.25.2