A regression of cmd dev -d/-D noticed on some vmcores as:
dev: invalid structure member offset: blk_mq_tag_set_shared_tags
FILE: dev.c LINE: 4468 FUNCTION: blk_mq_queue_tag_busy_iter()
MAJOR GENDISK NAME REQUEST_QUEUE TOTAL ASYNC SYNC
[crash] error trace: 91aa85 => 91a552 => 94d6ba => 94d647
94d647: OFFSET_verify.part.0+55
94d6ba: OFFSET_verify+42
91a552: get_diskio_1+2194
91aa85: display_all_diskio+1253
The root cause is, though upstream kernel have defined BLK_MQ_F_TAG_HCTX_SHARED
as (1 << 3), the value might be set different, e.g. [1]. So a single
blk_mq_is_shared_tags() check is not sufficient. This patch will resolve
BLK_MQ_F_TAG_HCTX_SHARED at runtime and add shared_tags member check within
blk_mq_tag_set struct as an enhancment.
[1]:
https://gitlab.com/redhat/centos-stream/src/kernel/centos-stream-8/-/blob...
Fixes: 62486400d35b ("Add blk_mq shared tags support for dev -d/-D")
Signed-off-by: Tao Liu <ltao(a)redhat.com>
---
v2 -> v3: replace arg_to_datatype() to enumerator_value().
---
dev.c | 20 +++++++++++++++++---
1 file changed, 17 insertions(+), 3 deletions(-)
diff --git a/dev.c b/dev.c
index 8391d71..5ab6855 100644
--- a/dev.c
+++ b/dev.c
@@ -4326,11 +4326,25 @@ struct bt_iter_data {
#define MQ_RQ_IN_FLIGHT 1
#define REQ_OP_BITS 8
#define REQ_OP_MASK ((1 << REQ_OP_BITS) - 1)
-#define BLK_MQ_F_TAG_HCTX_SHARED (1 << 3)
static bool blk_mq_is_shared_tags(unsigned int flags)
{
- return flags & BLK_MQ_F_TAG_HCTX_SHARED;
+ static long value = -1;
+ static bool value_fetched = false;
+ struct datatype_member dm;
+
+ if (value_fetched)
+ goto out;
+
+ value_fetched = true;
+ if (enumerator_value("BLK_MQ_F_TAG_HCTX_SHARED", &value))
+ value = dm.value;
+out:
+ if (value < 0)
+ /* Invalid BLK_MQ_F_TAG_HCTX_SHARED */
+ return false;
+ else
+ return flags & value;
}
static uint op_is_write(uint op)
@@ -4464,7 +4478,7 @@ static void blk_mq_queue_tag_busy_iter(ulong q, ulong *hctx, uint
cnt,
readmem(addr + OFFSET(blk_mq_tag_set_flags), KVADDR,
&flags, sizeof(uint), "blk_mq_tag_set.flags", RETURN_ON_ERROR);
- if (blk_mq_is_shared_tags(flags)) {
+ if (blk_mq_is_shared_tags(flags) && VALID_MEMBER(blk_mq_tag_set_shared_tags)) {
addr = addr + OFFSET(blk_mq_tag_set_shared_tags);
queue_for_each_hw_ctx(q, addr, bitmap_tags_is_ptr, dio);
return;
--
2.47.0