From: Christoph Hellwig <hch@lst.de>
To: Jens Axboe <axboe@kernel.dk>
Cc: Damien Le Moal <dlemoal@kernel.org>,
Ming Lei <ming.lei@redhat.com>,
Nilay Shroff <nilay@linux.ibm.com>,
linux-block@vger.kernel.org, linux-nvme@lists.infradead.org,
nbd@other.debian.org, linux-scsi@vger.kernel.org,
usb-storage@lists.one-eyed-alien.net
Subject: [PATCH 3/8] block: don't update BLK_FEAT_POLL in __blk_mq_update_nr_hw_queues
Date: Tue, 7 Jan 2025 07:30:35 +0100 [thread overview]
Message-ID: <20250107063120.1011593-4-hch@lst.de> (raw)
In-Reply-To: <20250107063120.1011593-1-hch@lst.de>
When __blk_mq_update_nr_hw_queues changes the number of tag sets, it
might have to disable poll queues. Currently it does so by adjusting
the BLK_FEAT_POLL, which is a bit against the intent of features that
describe hardware / driver capabilities, but more importantly causes
nasty lock order problems with the broadly held freeze when updating the
number of hardware queues and the limits lock. Fix this by leaving
BLK_FEAT_POLL alone, and instead check for the number of poll queues in
the bio submission and poll handlers. While this adds extra work to the
fast path, the variables are in cache lines used by these operations
anyway, so it should be cheap enough.
Fixes: 8023e144f9d6 ("block: move the poll flag to queue_limits")
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
block/blk-core.c | 17 ++++++++++++++---
block/blk-mq.c | 17 +----------------
2 files changed, 15 insertions(+), 19 deletions(-)
diff --git a/block/blk-core.c b/block/blk-core.c
index 666efe8fa202..bd5bec843d37 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -753,6 +753,18 @@ static blk_status_t blk_validate_atomic_write_op_size(struct request_queue *q,
return BLK_STS_OK;
}
+static bool bdev_can_poll(struct block_device *bdev)
+{
+ struct request_queue *q = bdev_get_queue(bdev);
+
+ if (!(q->limits.features & BLK_FEAT_POLL))
+ return false;
+
+ if (queue_is_mq(q))
+ return q->tag_set->map[HCTX_TYPE_POLL].nr_queues;
+ return true;
+}
+
/**
* submit_bio_noacct - re-submit a bio to the block device layer for I/O
* @bio: The bio describing the location in memory and on the device.
@@ -805,8 +817,7 @@ void submit_bio_noacct(struct bio *bio)
}
}
- if (!(q->limits.features & BLK_FEAT_POLL) &&
- (bio->bi_opf & REQ_POLLED)) {
+ if ((bio->bi_opf & REQ_POLLED) && !bdev_can_poll(bdev)) {
bio_clear_polled(bio);
goto not_supported;
}
@@ -935,7 +946,7 @@ int bio_poll(struct bio *bio, struct io_comp_batch *iob, unsigned int flags)
return 0;
q = bdev_get_queue(bdev);
- if (cookie == BLK_QC_T_NONE || !(q->limits.features & BLK_FEAT_POLL))
+ if (cookie == BLK_QC_T_NONE || !bdev_can_poll(bdev))
return 0;
blk_flush_plug(current->plug, false);
diff --git a/block/blk-mq.c b/block/blk-mq.c
index 2e6132f778fd..f795d81b6b38 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -4320,12 +4320,6 @@ void blk_mq_release(struct request_queue *q)
blk_mq_sysfs_deinit(q);
}
-static bool blk_mq_can_poll(struct blk_mq_tag_set *set)
-{
- return set->nr_maps > HCTX_TYPE_POLL &&
- set->map[HCTX_TYPE_POLL].nr_queues;
-}
-
struct request_queue *blk_mq_alloc_queue(struct blk_mq_tag_set *set,
struct queue_limits *lim, void *queuedata)
{
@@ -4336,7 +4330,7 @@ struct request_queue *blk_mq_alloc_queue(struct blk_mq_tag_set *set,
if (!lim)
lim = &default_lim;
lim->features |= BLK_FEAT_IO_STAT | BLK_FEAT_NOWAIT;
- if (blk_mq_can_poll(set))
+ if (set->nr_maps > HCTX_TYPE_POLL)
lim->features |= BLK_FEAT_POLL;
q = blk_alloc_queue(lim, set->numa_node);
@@ -5024,8 +5018,6 @@ static void __blk_mq_update_nr_hw_queues(struct blk_mq_tag_set *set,
fallback:
blk_mq_update_queue_map(set);
list_for_each_entry(q, &set->tag_list, tag_set_list) {
- struct queue_limits lim;
-
blk_mq_realloc_hw_ctxs(set, q);
if (q->nr_hw_queues != set->nr_hw_queues) {
@@ -5039,13 +5031,6 @@ static void __blk_mq_update_nr_hw_queues(struct blk_mq_tag_set *set,
set->nr_hw_queues = prev_nr_hw_queues;
goto fallback;
}
- lim = queue_limits_start_update(q);
- if (blk_mq_can_poll(set))
- lim.features |= BLK_FEAT_POLL;
- else
- lim.features &= ~BLK_FEAT_POLL;
- if (queue_limits_commit_update(q, &lim) < 0)
- pr_warn("updating the poll flag failed\n");
blk_mq_map_swqueue(q);
}
--
2.45.2
next prev parent reply other threads:[~2025-01-07 6:31 UTC|newest]
Thread overview: 43+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-01-07 6:30 fix queue freeze and limit locking order Christoph Hellwig
2025-01-07 6:30 ` [PATCH 1/8] block: fix docs for freezing of queue limits updates Christoph Hellwig
2025-01-07 7:01 ` Nilay Shroff
2025-01-07 18:05 ` Nilay Shroff
2025-01-07 10:03 ` Damien Le Moal
2025-01-09 11:19 ` John Garry
2025-01-09 11:24 ` Nilay Shroff
2025-01-09 11:26 ` John Garry
2025-01-07 6:30 ` [PATCH 2/8] block: add a queue_limits_commit_update_frozen helper Christoph Hellwig
2025-01-07 10:05 ` Damien Le Moal
2025-01-07 17:58 ` Nilay Shroff
2025-01-07 6:30 ` Christoph Hellwig [this message]
2025-01-07 6:57 ` [PATCH 3/8] block: don't update BLK_FEAT_POLL in __blk_mq_update_nr_hw_queues Nilay Shroff
2025-01-07 8:21 ` Christoph Hellwig
2025-01-07 9:23 ` Nilay Shroff
2025-01-07 13:51 ` Christoph Hellwig
2025-01-07 17:55 ` Nilay Shroff
2025-01-07 6:30 ` [PATCH 4/8] block: add a store_limit operations for sysfs entries Christoph Hellwig
2025-01-07 7:25 ` Ming Lei
2025-01-07 7:51 ` Nilay Shroff
2025-01-07 8:26 ` Christoph Hellwig
2025-01-07 10:25 ` Ming Lei
2025-01-07 13:49 ` Christoph Hellwig
2025-01-07 8:23 ` Christoph Hellwig
2025-01-07 10:05 ` Damien Le Moal
2025-01-07 17:58 ` Nilay Shroff
2025-01-07 6:30 ` [PATCH 5/8] block: fix queue freeze vs limits lock order in sysfs store methods Christoph Hellwig
2025-01-07 17:59 ` Nilay Shroff
2025-01-07 6:30 ` [PATCH 6/8] nvme: fix queue freeze vs limits lock order Christoph Hellwig
2025-01-07 6:58 ` Nilay Shroff
2025-01-07 8:22 ` Christoph Hellwig
2025-01-07 8:45 ` Nilay Shroff
2025-01-07 8:58 ` Christoph Hellwig
2025-01-07 9:29 ` Nilay Shroff
2025-01-07 9:58 ` Damien Le Moal
2025-01-07 18:00 ` Nilay Shroff
2025-01-07 6:30 ` [PATCH 7/8] nbd: " Christoph Hellwig
2025-01-07 10:00 ` Damien Le Moal
2025-01-07 18:01 ` Nilay Shroff
2025-01-07 6:30 ` [PATCH 8/8] usb-storage:fix " Christoph Hellwig
2025-01-07 10:00 ` Damien Le Moal
2025-01-07 18:01 ` Nilay Shroff
2025-01-08 2:21 ` fix queue freeze and limit locking order Ming Lei
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250107063120.1011593-4-hch@lst.de \
--to=hch@lst.de \
--cc=axboe@kernel.dk \
--cc=dlemoal@kernel.org \
--cc=linux-block@vger.kernel.org \
--cc=linux-nvme@lists.infradead.org \
--cc=linux-scsi@vger.kernel.org \
--cc=ming.lei@redhat.com \
--cc=nbd@other.debian.org \
--cc=nilay@linux.ibm.com \
--cc=usb-storage@lists.one-eyed-alien.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox