when zspage define 'huge', crash-utility zram decompress fail.
we need to be compatible with the previous kernel,
so we can't define 'huge' directly in zspage, just move to the right when calculating.
Link: https://lkml.kernel.org/r/20211115185909.3949505-6-minchan@xxxxxxxxxx
Signed-off-by: chenguanyou <chenguanyou@xxxxxxxxxx>
---
defs.h | 13 +++++++++++++
diskdump.c | 39 ++++++++++++++++++++++++++++++---------
2 files changed, 43 insertions(+), 9 deletions(-)
diff --git a/defs.h b/defs.h
index 96a7a2a..0af69cc 100644
--- a/defs.h
+++ b/defs.h
@@ -2225,6 +2225,7 @@ struct offset_table { /* stash of commonly-used offsets */
long module_memory_base;
long module_memory_size;
long irq_data_irq;
+ long zspage_huge;
};
struct size_table { /* stash of commonly-used sizes */
@@ -7221,6 +7222,18 @@ struct zspage {
unsigned int freeobj;
};
+struct zspage6 {
+ struct {
+ unsigned int huge : 1;
+ unsigned int fullness : 2;
+ unsigned int class : 9;
+ unsigned int isolated : 3;
+ unsigned int magic : 8;
+ };
+ unsigned int inuse;
+ unsigned int freeobj;
+};
+
/*
* makedumpfile.c
*/
diff --git a/diskdump.c b/diskdump.c
index 2c284ff..99a8112 100644
--- a/diskdump.c
+++ b/diskdump.c
@@ -2761,9 +2761,11 @@ zram_object_addr(ulong pool, ulong handle, unsigned char *zram_buf)
{
ulong obj, off, class, page, zspage;
struct zspage zspage_s;
+ struct zspage6 zspage6_s;
physaddr_t paddr;
unsigned int obj_idx, class_idx, size;
ulong pages[2], sizes[2];
+ ulong zs_magic;
readmem(handle, KVADDR, &obj, sizeof(void *), "zram entry", FAULT_ON_ERROR);
obj >>= OBJ_TAG_BITS;
@@ -2772,11 +2774,19 @@ zram_object_addr(ulong pool, ulong handle, unsigned char *zram_buf)
readmem(page + OFFSET(page_private), KVADDR, &zspage,
sizeof(void *), "page_private", FAULT_ON_ERROR);
- readmem(zspage, KVADDR, &zspage_s, sizeof(struct zspage), "zspage", FAULT_ON_ERROR);
- class_idx = zspage_s.class;
- if (zspage_s.magic != ZSPAGE_MAGIC)
- error(FATAL, "zspage magic incorrect: %x\n", zspage_s.magic);
+ if (VALID_MEMBER(zspage_huge)) {
+ readmem(zspage, KVADDR, &zspage6_s, sizeof(struct zspage6), "zspage6", FAULT_ON_ERROR);
+ class_idx = zspage6_s.class;
+ zs_magic = zspage6_s.magic;
+ } else {
+ readmem(zspage, KVADDR, &zspage_s, sizeof(struct zspage), "zspage", FAULT_ON_ERROR);
+ class_idx = zspage_s.class;
+ zs_magic = zspage_s.magic;
+ }
+
+ if (zs_magic != ZSPAGE_MAGIC)
+ error(FATAL, "zspage magic incorrect: %x\n", zs_magic);
class = pool + OFFSET(zspoll_size_class);
class += (class_idx * sizeof(void *));
@@ -2794,8 +2804,13 @@ zram_object_addr(ulong pool, ulong handle, unsigned char *zram_buf)
}
pages[0] = page;
- readmem(page + OFFSET(page_freelist), KVADDR, &pages[1],
- sizeof(void *), "page_freelist", FAULT_ON_ERROR);
+ if (VALID_MEMBER(page_freelist)) {
+ readmem(page + OFFSET(page_freelist), KVADDR, &pages[1],
+ sizeof(void *), "page_freelist", FAULT_ON_ERROR);
+ } else {
+ readmem(page + OFFSET(page_index), KVADDR, &pages[1],
+ sizeof(void *), "page_index", FAULT_ON_ERROR);
+ }
sizes[0] = PAGESIZE() - off;
sizes[1] = size - sizes[0];
if (!is_page_ptr(pages[0], &paddr)) {
@@ -2812,9 +2827,15 @@ zram_object_addr(ulong pool, ulong handle, unsigned char *zram_buf)
readmem(paddr, PHYSADDR, zram_buf + sizes[0], sizes[1], "zram buffer[1]", FAULT_ON_ERROR);
out:
- readmem(page, KVADDR, &obj, sizeof(void *), "page flags", FAULT_ON_ERROR);
- if (!(obj & (1<<10))) { //PG_OwnerPriv1 flag
- return (zram_buf + ZS_HANDLE_SIZE);
+ if (!VALID_MEMBER(zspage_huge)) {
+ readmem(page, KVADDR, &obj, sizeof(void *), "page flags", FAULT_ON_ERROR);
+ if (!(obj & (1<<10))) { //PG_OwnerPriv1 flag
+ return (zram_buf + ZS_HANDLE_SIZE);
+ }
+ } else {
+ if (!zspage6_s.huge) {
+ return (zram_buf + ZS_HANDLE_SIZE);
+ }
}
return zram_buf;
--
2.39.0
|
From 60fb0daa3f1988ac3fd12f7fbd8e4a83f9a71989 Mon Sep 17 00:00:00 2001 From: chenguanyou <chenguanyou@xxxxxxxxxx> Date: Mon, 11 Sep 2023 20:59:39 +0800 Subject: [PATCH] Fix: move huge compressed obj from page to zspage when zspage define 'huge', crash-utility zram decompress fail. we need to be compatible with the previous kernel, so we can't define 'huge' directly in zspage, just move to the right when calculating. Link: https://lkml.kernel.org/r/20211115185909.3949505-6-minchan@xxxxxxxxxx Signed-off-by: chenguanyou <chenguanyou@xxxxxxxxxx> --- defs.h | 13 +++++++++++++ diskdump.c | 39 ++++++++++++++++++++++++++++++--------- 2 files changed, 43 insertions(+), 9 deletions(-) diff --git a/defs.h b/defs.h index 96a7a2a..0af69cc 100644 --- a/defs.h +++ b/defs.h @@ -2225,6 +2225,7 @@ struct offset_table { /* stash of commonly-used offsets */ long module_memory_base; long module_memory_size; long irq_data_irq; + long zspage_huge; }; struct size_table { /* stash of commonly-used sizes */ @@ -7221,6 +7222,18 @@ struct zspage { unsigned int freeobj; }; +struct zspage6 { + struct { + unsigned int huge : 1; + unsigned int fullness : 2; + unsigned int class : 9; + unsigned int isolated : 3; + unsigned int magic : 8; + }; + unsigned int inuse; + unsigned int freeobj; +}; + /* * makedumpfile.c */ diff --git a/diskdump.c b/diskdump.c index 2c284ff..99a8112 100644 --- a/diskdump.c +++ b/diskdump.c @@ -2761,9 +2761,11 @@ zram_object_addr(ulong pool, ulong handle, unsigned char *zram_buf) { ulong obj, off, class, page, zspage; struct zspage zspage_s; + struct zspage6 zspage6_s; physaddr_t paddr; unsigned int obj_idx, class_idx, size; ulong pages[2], sizes[2]; + ulong zs_magic; readmem(handle, KVADDR, &obj, sizeof(void *), "zram entry", FAULT_ON_ERROR); obj >>= OBJ_TAG_BITS; @@ -2772,11 +2774,19 @@ zram_object_addr(ulong pool, ulong handle, unsigned char *zram_buf) readmem(page + OFFSET(page_private), KVADDR, &zspage, sizeof(void *), "page_private", FAULT_ON_ERROR); - readmem(zspage, KVADDR, &zspage_s, sizeof(struct zspage), "zspage", FAULT_ON_ERROR); - class_idx = zspage_s.class; - if (zspage_s.magic != ZSPAGE_MAGIC) - error(FATAL, "zspage magic incorrect: %x\n", zspage_s.magic); + if (VALID_MEMBER(zspage_huge)) { + readmem(zspage, KVADDR, &zspage6_s, sizeof(struct zspage6), "zspage6", FAULT_ON_ERROR); + class_idx = zspage6_s.class; + zs_magic = zspage6_s.magic; + } else { + readmem(zspage, KVADDR, &zspage_s, sizeof(struct zspage), "zspage", FAULT_ON_ERROR); + class_idx = zspage_s.class; + zs_magic = zspage_s.magic; + } + + if (zs_magic != ZSPAGE_MAGIC) + error(FATAL, "zspage magic incorrect: %x\n", zs_magic); class = pool + OFFSET(zspoll_size_class); class += (class_idx * sizeof(void *)); @@ -2794,8 +2804,13 @@ zram_object_addr(ulong pool, ulong handle, unsigned char *zram_buf) } pages[0] = page; - readmem(page + OFFSET(page_freelist), KVADDR, &pages[1], - sizeof(void *), "page_freelist", FAULT_ON_ERROR); + if (VALID_MEMBER(page_freelist)) { + readmem(page + OFFSET(page_freelist), KVADDR, &pages[1], + sizeof(void *), "page_freelist", FAULT_ON_ERROR); + } else { + readmem(page + OFFSET(page_index), KVADDR, &pages[1], + sizeof(void *), "page_index", FAULT_ON_ERROR); + } sizes[0] = PAGESIZE() - off; sizes[1] = size - sizes[0]; if (!is_page_ptr(pages[0], &paddr)) { @@ -2812,9 +2827,15 @@ zram_object_addr(ulong pool, ulong handle, unsigned char *zram_buf) readmem(paddr, PHYSADDR, zram_buf + sizes[0], sizes[1], "zram buffer[1]", FAULT_ON_ERROR); out: - readmem(page, KVADDR, &obj, sizeof(void *), "page flags", FAULT_ON_ERROR); - if (!(obj & (1<<10))) { //PG_OwnerPriv1 flag - return (zram_buf + ZS_HANDLE_SIZE); + if (!VALID_MEMBER(zspage_huge)) { + readmem(page, KVADDR, &obj, sizeof(void *), "page flags", FAULT_ON_ERROR); + if (!(obj & (1<<10))) { //PG_OwnerPriv1 flag + return (zram_buf + ZS_HANDLE_SIZE); + } + } else { + if (!zspage6_s.huge) { + return (zram_buf + ZS_HANDLE_SIZE); + } } return zram_buf; -- 2.39.0
-- Crash-utility mailing list Crash-utility@xxxxxxxxxx https://listman.redhat.com/mailman/listinfo/crash-utility Contribution Guidelines: https://github.com/crash-utility/crash/wiki