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 | 56 +++++++++++++++++++++++++++++++++++------------------- 2 files changed, 37 insertions(+), 20 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..d7e4380 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); @@ -2980,13 +2986,15 @@ 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 = INVALID_MEMBER(zram_compressor) && INVALID_MEMBER(zram_comp_algs); + 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 = INVALID_MEMBER(zram_compressor) && INVALID_MEMBER(zram_comp_algs); + if (comp_alg_unavail) { + error(WARNING, "some pages are swapped out to zram. " + "please run mod -s zram.\n"); return 0; } } @@ -2997,8 +3005,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 (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 +3048,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 +3057,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