From 38acd02c7fc09843ffb10fc2d695cccdd10cc7f6 Mon Sep 17 00:00:00 2001 From: Chengen Du Date: Fri, 17 Nov 2023 11:45:33 +0800 Subject: [PATCH 01/14] Fix "rd" command for zram data display in Linux 6.2 and later Kernel commit 7ac07a26dea7 ("zram: preparation for multi-zcomp support") replaced "compressor" member with "comp_algs" in the zram struct. Without the patch, the "rd" command can 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" Related kernel commit: 84b33bf78889 ("zram: introduce recompress sysfs knob") Signed-off-by: Chengen Du Signed-off-by: Kazuhito Hagio Signed-off-by: Lianbo Jiang --- defs.h | 1 + diskdump.c | 47 ++++++++++++++++++++++++++++++----------------- 2 files changed, 31 insertions(+), 17 deletions(-) diff --git a/defs.h b/defs.h index 788f63ada739..2cae5b61e589 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 0fe46f4644d0..25054d96313e 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) @@ -2765,6 +2767,8 @@ zram_init(void) MEMBER_OFFSET_INIT(zram_mempoll, "zram", "mem_pool"); MEMBER_OFFSET_INIT(zram_compressor, "zram", "compressor"); + if (INVALID_MEMBER(zram_compressor)) + MEMBER_OFFSET_INIT(zram_comp_algs, "zram", "comp_algs"); 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 +2786,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); @@ -2981,9 +2987,9 @@ try_zram_decompress(ulonglong pte_val, unsigned char *buf, ulong len, ulonglong ulong zram, zram_table_entry, sector, index, entry, flags, size, outsize, off; - if (INVALID_MEMBER(zram_compressor)) { + if (INVALID_MEMBER(zram_mempoll)) { zram_init(); - if (INVALID_MEMBER(zram_compressor)) { + if (INVALID_MEMBER(zram_mempoll)) { error(WARNING, "Some pages are swapped out to zram. " "Please run mod -s zram.\n"); @@ -2997,8 +3003,28 @@ 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 (VALID_MEMBER(zram_compressor)) + readmem(zram + OFFSET(zram_compressor), KVADDR, name, sizeof(name), + "zram compressor", FAULT_ON_ERROR); + else { + 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)); + } if (STREQ(name, "lzo")) { #ifdef LZO if (!(dd->flags & LZO_SUPPORTED)) { @@ -3019,12 +3045,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 +3054,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.41.0