Blame SOURCES/0016-Make-dev-d-D-options-parse-sbitmap-on-Linux-4.18-and.patch

1a20ba
From c07068266b41450ca6821ee0a1a3adf34206015f Mon Sep 17 00:00:00 2001
1a20ba
From: Kazuhito Hagio <k-hagio-ab@nec.com>
1a20ba
Date: Fri, 10 Jun 2022 15:21:53 +0900
1a20ba
Subject: [PATCH 16/18] Make "dev -d|-D" options parse sbitmap on Linux 4.18
1a20ba
 and later
1a20ba
1a20ba
There have been a few reports that the "dev -d|-D" options displayed
1a20ba
incorrect I/O stats due to racy blk_mq_ctx.rq_* counters.  To fix it,
1a20ba
make the options parse sbitmap to count I/O stats on Linux 4.18 and
1a20ba
later kernels, which include RHEL8 ones.
1a20ba
1a20ba
To do this, adjust to the blk_mq_tags structure of Linux 5.10 through
1a20ba
5.15 kernels, which contain kernel commit 222a5ae03cdd ("blk-mq: Use
1a20ba
pointers for blk_mq_tags bitmap tags") and do not contain ae0f1a732f4a
1a20ba
("blk-mq: Stop using pointers for blk_mq_tags bitmap tags").
1a20ba
1a20ba
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
1a20ba
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
1a20ba
---
1a20ba
 dev.c | 25 +++++++++++++++++++++++--
1a20ba
 1 file changed, 23 insertions(+), 2 deletions(-)
1a20ba
1a20ba
diff --git a/dev.c b/dev.c
1a20ba
index 0172c83ffaea..db97f8aebdc2 100644
1a20ba
--- a/dev.c
1a20ba
+++ b/dev.c
1a20ba
@@ -4339,6 +4339,10 @@ static void bt_for_each(ulong q, ulong tags, ulong sbq, uint reserved, uint nr_r
1a20ba
 static void queue_for_each_hw_ctx(ulong q, ulong *hctx, uint cnt, struct diskio *dio)
1a20ba
 {
1a20ba
 	uint i;
1a20ba
+	int bitmap_tags_is_ptr = 0;
1a20ba
+
1a20ba
+	if (MEMBER_TYPE("blk_mq_tags", "bitmap_tags") == TYPE_CODE_PTR)
1a20ba
+		bitmap_tags_is_ptr = 1;
1a20ba
 
1a20ba
 	for (i = 0; i < cnt; i++) {
1a20ba
 		ulong addr = 0, tags = 0;
1a20ba
@@ -4357,9 +4361,17 @@ static void queue_for_each_hw_ctx(ulong q, ulong *hctx, uint cnt, struct diskio
1a20ba
 
1a20ba
 		if (nr_reserved_tags) {
1a20ba
 			addr = tags + OFFSET(blk_mq_tags_breserved_tags);
1a20ba
+			if (bitmap_tags_is_ptr &&
1a20ba
+			    !readmem(addr, KVADDR, &addr, sizeof(ulong),
1a20ba
+					"blk_mq_tags.bitmap_tags", RETURN_ON_ERROR))
1a20ba
+				break;
1a20ba
 			bt_for_each(q, tags, addr, 1, nr_reserved_tags, dio);
1a20ba
 		}
1a20ba
 		addr = tags + OFFSET(blk_mq_tags_bitmap_tags);
1a20ba
+		if (bitmap_tags_is_ptr &&
1a20ba
+		    !readmem(addr, KVADDR, &addr, sizeof(ulong),
1a20ba
+				"blk_mq_tags.bitmap_tags", RETURN_ON_ERROR))
1a20ba
+			break;
1a20ba
 		bt_for_each(q, tags, addr, 0, nr_reserved_tags, dio);
1a20ba
 	}
1a20ba
 }
1a20ba
@@ -4423,14 +4435,23 @@ get_mq_diskio(unsigned long q, unsigned long *mq_count)
1a20ba
 	unsigned long mctx_addr;
1a20ba
 	struct diskio tmp = {0};
1a20ba
 
1a20ba
-	if (INVALID_MEMBER(blk_mq_ctx_rq_dispatched) ||
1a20ba
-	    INVALID_MEMBER(blk_mq_ctx_rq_completed)) {
1a20ba
+	/*
1a20ba
+	 * Currently this function does not support old blk-mq implementation
1a20ba
+	 * before 12f5b9314545 ("blk-mq: Remove generation seqeunce"), so
1a20ba
+	 * filter them out.
1a20ba
+	 */
1a20ba
+	if (VALID_MEMBER(request_state)) {
1a20ba
+		if (CRASHDEBUG(1))
1a20ba
+			fprintf(fp, "mq: using sbitmap\n");
1a20ba
 		get_mq_diskio_from_hw_queues(q, &tmp);
1a20ba
 		mq_count[0] = tmp.read;
1a20ba
 		mq_count[1] = tmp.write;
1a20ba
 		return;
1a20ba
 	}
1a20ba
 
1a20ba
+	if (CRASHDEBUG(1))
1a20ba
+		fprintf(fp, "mq: using blk_mq_ctx.rq_{completed,dispatched} counters\n");
1a20ba
+
1a20ba
 	readmem(q + OFFSET(request_queue_queue_ctx), KVADDR, &queue_ctx,
1a20ba
 		sizeof(ulong), "request_queue.queue_ctx",
1a20ba
 		FAULT_ON_ERROR);
1a20ba
-- 
1a20ba
2.30.2
1a20ba