[Crash-utility] [PATCH] Fix 'rd' command for zram data display in Linux 6.2+

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



A kernel commit 7ac07a26dea7 (zram: preparation for multi-zcomp support)
in Linux replaces "compressor" with "comp_algs" in the zram struct.
If not fixed, the issue triggers the following error:
  rd: WARNING: Some pages are swapped out to zram. Please run mod -s zram.
  rd: invalid user virtual address: ffff7d23f010  type: "64-bit UVADDR"

Signed-off-by: Chengen Du <chengen.du@xxxxxxxxxxxxx>
---
 defs.h     |  1 +
 diskdump.c | 61 +++++++++++++++++++++++++++++++++++-------------------
 2 files changed, 41 insertions(+), 21 deletions(-)

diff --git a/defs.h b/defs.h
index 788f63a..2cae5b6 100644
--- a/defs.h
+++ b/defs.h
@@ -2227,6 +2227,7 @@ struct offset_table {                    /* stash of commonly-used offsets */
 	long module_memory_size;
 	long irq_data_irq;
 	long zspage_huge;
+	long zram_comp_algs;
 };
 
 struct size_table {         /* stash of commonly-used sizes */
diff --git a/diskdump.c b/diskdump.c
index 0fe46f4..0103221 100644
--- a/diskdump.c
+++ b/diskdump.c
@@ -2757,6 +2757,8 @@ diskdump_device_dump_info(FILE *ofp)
 
 static ulong ZRAM_FLAG_SHIFT;
 static ulong ZRAM_FLAG_SAME_BIT;
+static ulong ZRAM_COMP_PRIORITY_BIT1;
+static ulong ZRAM_COMP_PRIORITY_MASK;
 
 static void
 zram_init(void)
@@ -2764,7 +2766,10 @@ zram_init(void)
 	long zram_flag_shift;
 
 	MEMBER_OFFSET_INIT(zram_mempoll, "zram", "mem_pool");
-	MEMBER_OFFSET_INIT(zram_compressor, "zram", "compressor");
+	if (THIS_KERNEL_VERSION >= LINUX(6, 2, 0))
+		MEMBER_OFFSET_INIT(zram_comp_algs, "zram", "comp_algs");
+	else
+		MEMBER_OFFSET_INIT(zram_compressor, "zram", "compressor");
 	MEMBER_OFFSET_INIT(zram_table_flag, "zram_table_entry", "flags");
 	if (INVALID_MEMBER(zram_table_flag))
 		MEMBER_OFFSET_INIT(zram_table_flag, "zram_table_entry", "value");
@@ -2782,6 +2787,8 @@ zram_init(void)
 
 	ZRAM_FLAG_SHIFT = 1 << zram_flag_shift;
 	ZRAM_FLAG_SAME_BIT = 1 << (zram_flag_shift+1);
+	ZRAM_COMP_PRIORITY_BIT1 = ZRAM_FLAG_SHIFT + 7;
+	ZRAM_COMP_PRIORITY_MASK = 0x3;
 
 	if (CRASHDEBUG(1))
 		fprintf(fp, "zram_flag_shift: %ld\n", zram_flag_shift);
@@ -2980,13 +2987,17 @@ try_zram_decompress(ulonglong pte_val, unsigned char *buf, ulong len, ulonglong
 	unsigned char *outbuf = NULL;
 	ulong zram, zram_table_entry, sector, index, entry, flags, size,
 		outsize, off;
+	int comp_alg_unavail;
 
-	if (INVALID_MEMBER(zram_compressor)) {
+	comp_alg_unavail = (THIS_KERNEL_VERSION >= LINUX(6, 2, 0))
+		? INVALID_MEMBER(zram_comp_algs) : INVALID_MEMBER(zram_compressor);
+	if (comp_alg_unavail) {
 		zram_init();
-		if (INVALID_MEMBER(zram_compressor)) {
-			error(WARNING,
-			      "Some pages are swapped out to zram. "
-			      "Please run mod -s zram.\n");
+		comp_alg_unavail = (THIS_KERNEL_VERSION >= LINUX(6, 2, 0))
+			? INVALID_MEMBER(zram_comp_algs) : INVALID_MEMBER(zram_compressor);
+		if (comp_alg_unavail) {
+			error(WARNING, "some pages are swapped out to zram. "
+				"please run mod -s zram.\n");
 			return 0;
 		}
 	}
@@ -2997,8 +3008,29 @@ try_zram_decompress(ulonglong pte_val, unsigned char *buf, ulong len, ulonglong
 	if (!get_disk_name_private_data(pte_val, vaddr, NULL, &zram))
 		return 0;
 
-	readmem(zram + OFFSET(zram_compressor), KVADDR, name,
-		sizeof(name), "zram compressor", FAULT_ON_ERROR);
+	if (THIS_KERNEL_VERSION >= LINUX(2, 6, 0)) {
+		swp_offset = (ulonglong)__swp_offset(pte_val);
+	} else {
+		swp_offset = (ulonglong)SWP_OFFSET(pte_val);
+	}
+
+	sector = swp_offset << (PAGESHIFT() - 9);
+	index = sector >> SECTORS_PER_PAGE_SHIFT;
+	readmem(zram, KVADDR, &zram_table_entry,
+		sizeof(void *), "zram_table_entry", FAULT_ON_ERROR);
+	zram_table_entry += (index * SIZE(zram_table_entry));
+	readmem(zram_table_entry + OFFSET(zram_table_flag), KVADDR, &flags,
+		sizeof(void *), "zram_table_flag", FAULT_ON_ERROR);
+	if (THIS_KERNEL_VERSION >= LINUX(6, 2, 0)) {
+		ulong comp_alg_addr;
+		uint32_t prio = (flags >> ZRAM_COMP_PRIORITY_BIT1) & ZRAM_COMP_PRIORITY_MASK;
+		readmem(zram + OFFSET(zram_comp_algs) + sizeof(const char *) * prio, KVADDR,
+			&comp_alg_addr, sizeof(comp_alg_addr), "zram comp_algs", FAULT_ON_ERROR);
+		read_string(comp_alg_addr, name, sizeof(name));
+	} else {
+		readmem(zram + OFFSET(zram_compressor), KVADDR, name, sizeof(name),
+			"zram compressor", FAULT_ON_ERROR);
+	}
 	if (STREQ(name, "lzo")) {
 #ifdef LZO
 		if (!(dd->flags & LZO_SUPPORTED)) {
@@ -3019,12 +3051,6 @@ try_zram_decompress(ulonglong pte_val, unsigned char *buf, ulong len, ulonglong
 		return 0;
 	}
 
-	if (THIS_KERNEL_VERSION >= LINUX(2, 6, 0)) {
-		swp_offset = (ulonglong)__swp_offset(pte_val);
-	} else {
-		swp_offset = (ulonglong)SWP_OFFSET(pte_val);
-	}
-
 	zram_buf = (unsigned char *)GETBUF(PAGESIZE());
 	/* lookup page from swap cache */
 	off = PAGEOFFSET(vaddr);
@@ -3034,15 +3060,8 @@ try_zram_decompress(ulonglong pte_val, unsigned char *buf, ulong len, ulonglong
 		goto out;
 	}
 
-	sector = swp_offset << (PAGESHIFT() - 9);
-	index = sector >> SECTORS_PER_PAGE_SHIFT;
-	readmem(zram, KVADDR, &zram_table_entry,
-		sizeof(void *), "zram_table_entry", FAULT_ON_ERROR);
-	zram_table_entry += (index * SIZE(zram_table_entry));
 	readmem(zram_table_entry, KVADDR, &entry,
 		sizeof(void *), "entry of table", FAULT_ON_ERROR);
-	readmem(zram_table_entry + OFFSET(zram_table_flag), KVADDR, &flags,
-		sizeof(void *), "zram_table_flag", FAULT_ON_ERROR);
 	if (!entry || (flags & ZRAM_FLAG_SAME_BIT)) {
 		int count;
 		ulong *same_buf = (ulong *)GETBUF(PAGESIZE());
-- 
2.40.1
--
Crash-utility mailing list -- devel@xxxxxxxxxxxxxxxxxxxxxxxxxxx
To unsubscribe send an email to devel-leave@xxxxxxxxxxxxxxxxxxxxxxxxxxx
%(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s
Contribution Guidelines: https://github.com/crash-utility/crash/wiki




[Index of Archives]     [Fedora Development]     [Fedora Desktop]     [Fedora SELinux]     [Yosemite News]     [KDE Users]     [Fedora Tools]

 

Powered by Linux