Thread (47 messages) 47 messages, 5 authors, 2020-05-22
STALE2245d

[PATCH 7/9] blk-mq: disable preemption during allocating request tag

From: Christoph Hellwig <hch@lst.de>
Date: 2020-05-18 06:40:01
Subsystem: block layer, the rest · Maintainers: Jens Axboe, Linus Torvalds

From: Ming Lei <redacted>

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 <redacted>
[hch: keep the preempt disable confined inside blk_mq_get_tag]
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 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
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help