Blame SOURCES/0011-Fix-for-dev-d-D-options-to-support-blk-mq-change-on-.patch

aefe19
From 68ce0b9a35d77d767872dd1a729c50e4695a30a8 Mon Sep 17 00:00:00 2001
aefe19
From: Lianbo Jiang <lijiang@redhat.com>
aefe19
Date: Thu, 2 Jun 2022 20:12:56 +0800
aefe19
Subject: [PATCH 11/18] Fix for "dev -d|-D" options to support blk-mq change on
aefe19
 Linux v5.18-rc1
aefe19
aefe19
Kernel commit 4e5cc99e1e48 ("blk-mq: manage hctx map via xarray") removed
aefe19
the "queue_hw_ctx" member from struct request_queue at Linux v5.18-rc1,
aefe19
and replaced it with a struct xarray "hctx_table". Without the patch, the
aefe19
"dev -d|-D" options will print an error:
aefe19
aefe19
  crash> dev -d
aefe19
  MAJOR GENDISK            NAME       REQUEST_QUEUE      TOTAL  READ WRITE
aefe19
aefe19
  dev: invalid structure member offset: request_queue_queue_hw_ctx
aefe19
aefe19
With the patch:
aefe19
  crash> dev -d
aefe19
  MAJOR GENDISK            NAME       REQUEST_QUEUE      TOTAL  READ WRITE
aefe19
      8 ffff8e99d0a1ae00   sda        ffff8e9c14c59980      10     6     4
aefe19
aefe19
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
aefe19
---
aefe19
 defs.h    |  1 +
aefe19
 dev.c     | 42 +++++++++++++++++++++++++++++++++---------
aefe19
 symbols.c |  2 ++
aefe19
 3 files changed, 36 insertions(+), 9 deletions(-)
aefe19
aefe19
diff --git a/defs.h b/defs.h
aefe19
index 2681586a33dc..7d3b73422f48 100644
aefe19
--- a/defs.h
aefe19
+++ b/defs.h
aefe19
@@ -2180,6 +2180,7 @@ struct offset_table {                    /* stash of commonly-used offsets */
aefe19
 	long blk_mq_tags_breserved_tags;
aefe19
 	long blk_mq_tags_nr_reserved_tags;
aefe19
 	long blk_mq_tags_rqs;
aefe19
+	long request_queue_hctx_table;
aefe19
 };
aefe19
 
aefe19
 struct size_table {         /* stash of commonly-used sizes */
aefe19
diff --git a/dev.c b/dev.c
aefe19
index 4be4c96df8b0..0172c83ffaea 100644
aefe19
--- a/dev.c
aefe19
+++ b/dev.c
aefe19
@@ -4369,20 +4369,42 @@ static void get_mq_diskio_from_hw_queues(ulong q, struct diskio *dio)
aefe19
 	uint cnt = 0;
aefe19
 	ulong addr = 0, hctx_addr = 0;
aefe19
 	ulong *hctx_array = NULL;
aefe19
+	struct list_pair *lp = NULL;
aefe19
+
aefe19
+	if (VALID_MEMBER(request_queue_hctx_table)) {
aefe19
+		addr = q + OFFSET(request_queue_hctx_table);
aefe19
+		cnt = do_xarray(addr, XARRAY_COUNT, NULL);
aefe19
+		lp = (struct list_pair *)GETBUF(sizeof(struct list_pair) * (cnt + 1));
aefe19
+		if (!lp)
aefe19
+			error(FATAL, "fail to get memory for list_pair.\n");
aefe19
+		lp[0].index = cnt;
aefe19
+		cnt = do_xarray(addr, XARRAY_GATHER, lp);
aefe19
+	} else {
aefe19
+		addr = q + OFFSET(request_queue_nr_hw_queues);
aefe19
+		readmem(addr, KVADDR, &cnt, sizeof(uint),
aefe19
+			"request_queue.nr_hw_queues", FAULT_ON_ERROR);
aefe19
 
aefe19
-	addr = q + OFFSET(request_queue_nr_hw_queues);
aefe19
-	readmem(addr, KVADDR, &cnt, sizeof(uint),
aefe19
-		"request_queue.nr_hw_queues", FAULT_ON_ERROR);
aefe19
-
aefe19
-	addr = q + OFFSET(request_queue_queue_hw_ctx);
aefe19
-	readmem(addr, KVADDR, &hctx_addr, sizeof(void *),
aefe19
-		"request_queue.queue_hw_ctx", FAULT_ON_ERROR);
aefe19
+		addr = q + OFFSET(request_queue_queue_hw_ctx);
aefe19
+		readmem(addr, KVADDR, &hctx_addr, sizeof(void *),
aefe19
+			"request_queue.queue_hw_ctx", FAULT_ON_ERROR);
aefe19
+	}
aefe19
 
aefe19
 	hctx_array = (ulong *)GETBUF(sizeof(void *) * cnt);
aefe19
-	if (!hctx_array)
aefe19
+	if (!hctx_array) {
aefe19
+		if (lp)
aefe19
+			FREEBUF(lp);
aefe19
 		error(FATAL, "fail to get memory for the hctx_array\n");
aefe19
+	}
aefe19
+
aefe19
+	if (lp && hctx_array) {
aefe19
+		uint i;
aefe19
+
aefe19
+		/* copy it from list_pair to hctx_array */
aefe19
+		for (i = 0; i < cnt; i++)
aefe19
+			hctx_array[i] = (ulong)lp[i].value;
aefe19
 
aefe19
-	if (!readmem(hctx_addr, KVADDR, hctx_array, sizeof(void *) * cnt,
aefe19
+		FREEBUF(lp);
aefe19
+	} else if (!readmem(hctx_addr, KVADDR, hctx_array, sizeof(void *) * cnt,
aefe19
 			"request_queue.queue_hw_ctx[]", RETURN_ON_ERROR)) {
aefe19
 		FREEBUF(hctx_array);
aefe19
 		return;
aefe19
@@ -4755,6 +4777,8 @@ void diskio_init(void)
aefe19
 			"request_queue", "queue_hw_ctx");
aefe19
 		MEMBER_OFFSET_INIT(request_queue_nr_hw_queues,
aefe19
 			"request_queue", "nr_hw_queues");
aefe19
+		MEMBER_OFFSET_INIT(request_queue_hctx_table,
aefe19
+			"request_queue", "hctx_table");
aefe19
 		MEMBER_OFFSET_INIT(blk_mq_ctx_rq_dispatched, "blk_mq_ctx",
aefe19
 			"rq_dispatched");
aefe19
 		MEMBER_OFFSET_INIT(blk_mq_ctx_rq_completed, "blk_mq_ctx",
aefe19
diff --git a/symbols.c b/symbols.c
aefe19
index c1f09556d710..bee1faf92c83 100644
aefe19
--- a/symbols.c
aefe19
+++ b/symbols.c
aefe19
@@ -10403,6 +10403,8 @@ dump_offset_table(char *spec, ulong makestruct)
aefe19
 		OFFSET(request_queue_queue_hw_ctx));
aefe19
 	fprintf(fp, "    request_queue_nr_hw_queues: %ld\n",
aefe19
 		OFFSET(request_queue_nr_hw_queues));
aefe19
+	fprintf(fp, "      request_queue_hctx_table: %ld\n",
aefe19
+		OFFSET(request_queue_hctx_table));
aefe19
 	fprintf(fp, "      blk_mq_ctx_rq_dispatched: %ld\n",
aefe19
 		OFFSET(blk_mq_ctx_rq_dispatched));
aefe19
 	fprintf(fp, "       blk_mq_ctx_rq_completed: %ld\n",
aefe19
-- 
aefe19
2.30.2
aefe19