[PATCH] Support running on X86_64 with RISCV target
by Pnina Feder
Signed-off-by: Pnina Feder <pnina.feder(a)mobileye.com>
---
symbols.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/symbols.c b/symbols.c
index e30fafe..5b42ecf 100644
--- a/symbols.c
+++ b/symbols.c
@@ -4539,7 +4539,7 @@ is_shared_object(char *file)
case EM_X86_64:
if (machine_type("X86_64") || machine_type("ARM64") ||
- machine_type("PPC64"))
+ machine_type("PPC64") || machine_type("RISCV64"))
return TRUE;
break;
--
2.43.0
2 weeks, 2 days
[PATCH] RISCV64: Add 'PAGE DIRECTORY' property to the 'vtop' command
by Austin Kim
Currently, 'vtop' command does not include 'PAGE DIRECTORY' information for
RISC-V-based vmcores. Since 'PAGE DIRECTORY' is used as the root page table,
we need this information. Note that Arm64, Arm32 and x86 vmcore shows
'PAGE DIRECTORY' for 'vtop' command.
(before)
crash> vtop 0xffffffff80d8e1e0
VIRTUAL PHYSICAL
ffffffff80d8e1e0 40f8e1e0
PGD: ffffffff81c4fff0 => 4fffe801
PMD: 000000013fffa000 => 00000000103800eb
PTE: 40e00000 => b35030414c583
PAGE: 002cd40c10531000
PTE PHYSICAL FLAGS
b35030414c583 2cd40c10531000 (PRESENT|READ|DIRTY|SOFT)
(after)
crash> vtop 0xffffffff80d8e1e0
VIRTUAL PHYSICAL
ffffffff80d8e1e0 40f8e1e0
PAGE DIRECTORY: ffffffff81c4f000
PGD: ffffffff81c4fff0 => 4fffe801
PMD: 000000013fffa000 => 00000000103800eb
PTE: 40e00000 => b35030414c583
PAGE: 002cd40c10531000
PTE PHYSICAL FLAGS
b35030414c583 2cd40c10531000 (PRESENT|READ|DIRTY|SOFT)
Signed-off-by: Austin Kim <austindh.kim(a)gmail.com>
---
riscv64.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/riscv64.c b/riscv64.c
index 073ebb9..ef5c41d 100644
--- a/riscv64.c
+++ b/riscv64.c
@@ -634,6 +634,9 @@ riscv64_vtop_3level_4k(ulong *pgd, ulong vaddr, physaddr_t *paddr, int verbose)
ulong pte_val, pte_pfn;
ulong pt_phys;
+ if (verbose)
+ fprintf(fp, "PAGE DIRECTORY: %lx\n", (ulong)pgd);
+
/* PGD */
pgd_ptr = pgd + pgd_index_l3_4k(vaddr);
FILL_PGD(pgd, KVADDR, PAGESIZE());
@@ -1213,6 +1216,9 @@ riscv64_vtop_4level_4k(ulong *pgd, ulong vaddr, physaddr_t *paddr, int verbose)
ulong pte_val, pte_pfn;
ulong pt_phys;
+ if (verbose)
+ fprintf(fp, "PAGE DIRECTORY: %lx\n", (ulong)pgd);
+
/* PGD */
pgd_ptr = pgd + pgd_index_l4_4k(vaddr);
FILL_PGD(pgd, KVADDR, PAGESIZE());
@@ -1289,6 +1295,9 @@ riscv64_vtop_5level_4k(ulong *pgd, ulong vaddr, physaddr_t *paddr, int verbose)
ulong pte_val, pte_pfn;
ulong pt_phys;
+ if (verbose)
+ fprintf(fp, "PAGE DIRECTORY: %lx\n", (ulong)pgd);
+
/* PGD */
pgd_ptr = pgd + pgd_index_l5_4k(vaddr);
FILL_PGD(pgd, KVADDR, PAGESIZE());
--
2.34.1
2 weeks, 2 days
[PATCH] mem: rename variable for clarity in get_kmem_cache_slub_data()
by liuye@kylinos.cn
From 33e22a832bdf79b032dd9d4ceac53fead5c2f552 Mon Sep 17 00:00:00 2001
From: Ye Liu <liuye(a)kylinos.cn>
Date: Wed, 3 Sep 2025 15:18:57 +0800
Subject: [PATCH] mem: rename variable for clarity in
get_kmem_cache_slub_data()
Rename 'cpu_slab_ptr' to 'cpu_slab_page_ptr' to better reflect that
it holds a pointer to a page structure rather than a generic slab pointer.
This improves code readability and consistency with related functions.
No functional changes.
Signed-off-by: Ye Liu <liuye(a)kylinos.cn>
---
memory.c | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/memory.c b/memory.c
index 400d31a04cd4..be5c590003a8 100644
--- a/memory.c
+++ b/memory.c
@@ -19426,7 +19426,7 @@ get_kmem_cache_slub_data(long cmd, struct meminfo *si)
{
int i, n, node;
ulong total_objects, total_slabs, free_objects;
- ulong cpu_slab_ptr, node_ptr, cpu_freelist, orig_slab;
+ ulong cpu_slab_page_ptr, node_ptr, cpu_freelist, orig_slab;
ulong node_nr_partial, node_nr_slabs, node_total_objects;
int full_slabs, objects, node_total_avail;
long p;
@@ -19445,12 +19445,12 @@ get_kmem_cache_slub_data(long cmd, struct meminfo *si)
node_total_avail = VALID_MEMBER(kmem_cache_node_total_objects) ? TRUE : FALSE;
for (i = 0; i < kt->cpus; i++) {
- cpu_slab_ptr = get_cpu_slab_ptr(si, i, &cpu_freelist);
+ cpu_slab_page_ptr = get_cpu_slab_ptr(si, i, &cpu_freelist);
- if (!cpu_slab_ptr)
+ if (!cpu_slab_page_ptr)
continue;
- if ((node = page_to_nid(cpu_slab_ptr)) < 0)
+ if ((node = page_to_nid(cpu_slab_page_ptr)) < 0)
goto bailout;
switch (cmd)
@@ -19458,15 +19458,15 @@ get_kmem_cache_slub_data(long cmd, struct meminfo *si)
case GET_SLUB_OBJECTS: {
/* For better error report, set cur slab to si->slab. */
orig_slab = si->slab;
- si->slab = cpu_slab_ptr;
+ si->slab = cpu_slab_page_ptr;
- if (!readmem(cpu_slab_ptr + OFFSET(page_inuse),
+ if (!readmem(cpu_slab_page_ptr + OFFSET(page_inuse),
KVADDR, &inuse, sizeof(short),
"page inuse", RETURN_ON_ERROR)) {
si->slab = orig_slab;
return FALSE;
}
- objects = slub_page_objects(si, cpu_slab_ptr);
+ objects = slub_page_objects(si, cpu_slab_page_ptr);
if (!objects) {
si->slab = orig_slab;
return FALSE;
--
2.43.0
2 weeks, 2 days
Re: [PATCH v2 1/2] vmware_vmss: support segment registers
by Lianbo Jiang
Hi, Ajay
Thank you for the update. For the v2: Ack.
On 8/30/25 21:32, devel-request(a)lists.crash-utility.osci.io wrote:
> Date: Sat, 30 Aug 2025 13:19:07 +0000
> From: Ajay Kaher<ajay.kaher(a)broadcom.com>
> Subject: [Crash-utility] [PATCH v2 1/2] vmware_vmss: support segment
> registers
> To:devel@lists.crash-utility.osci.io,lijiang@redhat.com,
> ltao(a)redhat.com
> Cc:alexey.makhalov@broadcom.com,
> vamsi-krishna.brahmajosyula@broadcom.com,tapas.kundu(a)broadcom.com,
> ajay.kaher(a)broadcom.com
> Message-ID:<20250830131908.1984311-1-ajay.kaher(a)broadcom.com>
>
> adding support for segment registers for vmware vmss dumps.
>
> diff from v1:
> - modified dump_registers_for_vmss_dump() to remove compiler warning.
>
> Signed-off-by: Ajay Kaher<ajay.kaher(a)broadcom.com>
> ---
> vmware_guestdump.c | 2 +-
> vmware_vmss.c | 116 +++++++++++++++++++++++++++++++++++----------
> vmware_vmss.h | 92 ++++++++++++++++++++++++-----------
> 3 files changed, 155 insertions(+), 55 deletions(-)
>
> diff --git a/vmware_guestdump.c b/vmware_guestdump.c
> index 1a6ef9b..dc10d42 100644
> --- a/vmware_guestdump.c
> +++ b/vmware_guestdump.c
> @@ -360,7 +360,7 @@ vmware_guestdump_init(char *filename, FILE *ofp)
> goto exit;
> }
>
> - vmss.vcpu_regs = malloc(vmss.num_vcpus * sizeof(uint32_t));
> + vmss.vcpu_regs = malloc(vmss.num_vcpus * sizeof(uint64_t));
> vmss.regs64 = calloc(vmss.num_vcpus, sizeof(void *));
> if (!vmss.vcpu_regs || !vmss.regs64) {
> error(INFO, LOGPRX"Failed to allocate memory\n");
> diff --git a/vmware_vmss.c b/vmware_vmss.c
> index 8121ab6..3f9ad33 100644
> --- a/vmware_vmss.c
> +++ b/vmware_vmss.c
> @@ -317,7 +317,7 @@ vmware_vmss_init(char *filename, FILE *ofp)
>
> vmss.num_vcpus = u.val32;
> vmss.regs64 = malloc(vmss.num_vcpus * sizeof(void *));
> - vmss.vcpu_regs = malloc(vmss.num_vcpus * sizeof(uint32_t));
> + vmss.vcpu_regs = malloc(vmss.num_vcpus * sizeof(uint64_t));
>
> for (k = 0; k < vmss.num_vcpus; k++) {
> vmss.regs64[k] = malloc(sizeof(vmssregs64));
> @@ -432,15 +432,65 @@ vmware_vmss_init(char *filename, FILE *ofp)
> int cpu = idx[0];
> vmss.regs64[cpu]->rflags |= u.val32;
> vmss.vcpu_regs[cpu] |= REGS_PRESENT_RFLAGS;
> + } else if (strcmp(name, "S.base64") == 0) {
> + int cpu = idx[0];
> + int seg_index = idx[1];
> + switch (seg_index) {
> + case SEG_FS:
> + vmss.regs64[cpu]->fs_base = u.val64;
> + vmss.vcpu_regs[cpu] |= REGS_PRESENT_FS_BASE;
> + break;
> + case SEG_GS:
> + vmss.regs64[cpu]->gs_base = u.val64;
> + vmss.vcpu_regs[cpu] |= REGS_PRESENT_GS_BASE;
> + break;
> + }
> + } else if (strcmp(name, "S") == 0) {
> + int cpu = idx[0];
> + int seg_index = idx[1];
> + switch (seg_index) {
> + case SEG_ES:
> + vmss.regs64[cpu]->es = u.val32;
> + vmss.vcpu_regs[cpu] |= REGS_PRESENT_ES;
> + break;
> + case SEG_CS:
> + vmss.regs64[cpu]->cs = u.val32;
> + vmss.vcpu_regs[cpu] |= REGS_PRESENT_CS;
> + break;
> + case SEG_SS:
> + vmss.regs64[cpu]->ss = u.val32;
> + vmss.vcpu_regs[cpu] |= REGS_PRESENT_SS;
> + break;
> + case SEG_DS:
> + vmss.regs64[cpu]->ds = u.val32;
> + vmss.vcpu_regs[cpu] |= REGS_PRESENT_DS;
> + break;
> + case SEG_FS:
> + vmss.regs64[cpu]->fs = u.val32;
> + vmss.vcpu_regs[cpu] |= REGS_PRESENT_FS;
> + break;
> + case SEG_GS:
> + vmss.regs64[cpu]->gs = u.val32;
> + vmss.vcpu_regs[cpu] |= REGS_PRESENT_GS;
> + break;
> + case SEG_LDTR:
> + vmss.regs64[cpu]->ldtr = u.val32;
> + vmss.vcpu_regs[cpu] |= REGS_PRESENT_LDTR;
> + break;
> + case SEG_TR:
> + vmss.regs64[cpu]->tr = u.val32;
> + vmss.vcpu_regs[cpu] |= REGS_PRESENT_TR;
> + break;
> + default:
> + error(INFO, "Unknown VMSS Segment [%d][%d]\n", cpu, seg_index);
> + }
> }
> }
> -
> DEBUG_PARSE_PRINT((ofp, "\n"));
> }
> }
> }
>
> -
> if (vmss.memsize == 0) {
> char *vmem_filename, *p;
>
> @@ -842,7 +892,7 @@ dump_registers_for_vmss_dump(void)
> fprintf(fp, "CPU %d:\n", i);
>
> if (vmss.vcpu_regs[i] != REGS_PRESENT_ALL) {
> - fprintf(fp, "Missing registers for this CPU: 0x%x\n", vmss.vcpu_regs[i]);
> + fprintf(fp, "Missing registers for this CPU: 0x%lx\n", vmss.vcpu_regs[i]);
> continue;
> }
>
> @@ -902,36 +952,50 @@ vmware_vmss_get_cpu_reg(int cpu, int regno, const char *name, int size,
> if (cpu >= vmss.num_vcpus)
> return FALSE;
>
> - /* All supported registers are 8 bytes long. */
> - if (size != 8)
> - return FALSE;
> -
> -#define CASE(R,r) \
> +#define CASE_32(R,r) \
> case R##_REGNUM: \
> + if (size != 4) \
> + return FALSE; \
> if (!(vmss.vcpu_regs[cpu] & REGS_PRESENT_##R)) \
> return FALSE; \
> memcpy(value, &vmss.regs64[cpu]->r, size); \
> break
>
> +#define CASE_64(R,r) \
> + case R##_REGNUM: \
> + if (size != 8) \
> + return FALSE; \
> + if (!(vmss.vcpu_regs[cpu] & REGS_PRESENT_##R)) \
> + return FALSE; \
> + memcpy(value, &vmss.regs64[cpu]->r, size); \
> + break
>
> switch (regno) {
> - CASE (RAX, rax);
> - CASE (RBX, rbx);
> - CASE (RCX, rcx);
> - CASE (RDX, rdx);
> - CASE (RSI, rsi);
> - CASE (RDI, rdi);
> - CASE (RBP, rbp);
> - CASE (RSP, rsp);
> - CASE (R8, r8);
> - CASE (R9, r9);
> - CASE (R10, r10);
> - CASE (R11, r11);
> - CASE (R12, r12);
> - CASE (R13, r13);
> - CASE (R14, r14);
> - CASE (R15, r15);
> - CASE (RIP, rip);
> + CASE_64 (RAX, rax);
> + CASE_64 (RBX, rbx);
> + CASE_64 (RCX, rcx);
> + CASE_64 (RDX, rdx);
> + CASE_64 (RSI, rsi);
> + CASE_64 (RDI, rdi);
> + CASE_64 (RBP, rbp);
> + CASE_64 (RSP, rsp);
> + CASE_64 (R8, r8);
> + CASE_64 (R9, r9);
> + CASE_64 (R10, r10);
> + CASE_64 (R11, r11);
> + CASE_64 (R12, r12);
> + CASE_64 (R13, r13);
> + CASE_64 (R14, r14);
> + CASE_64 (R15, r15);
> + CASE_64 (RIP, rip);
> + CASE_32 (ES, es);
> + CASE_32 (CS, cs);
> + CASE_32 (SS, ss);
> + CASE_32 (DS, ds);
> + CASE_32 (FS, fs);
> + CASE_32 (GS, gs);
> + CASE_64 (FS_BASE, fs_base);
> + CASE_64 (GS_BASE, gs_base);
> case EFLAGS_REGNUM:
> if (!(vmss.vcpu_regs[cpu] & REGS_PRESENT_RFLAGS))
> return FALSE;
> diff --git a/vmware_vmss.h b/vmware_vmss.h
> index 01d9446..5bc0370 100644
> --- a/vmware_vmss.h
> +++ b/vmware_vmss.h
> @@ -110,41 +110,77 @@ struct vmssregs64 {
> uint64_t r13;
> uint64_t r14;
> uint64_t r15;
> + uint64_t es;
> + uint64_t cs;
> + uint64_t ss;
> + uint64_t ds;
> + uint64_t fs;
> + uint64_t gs;
> + uint64_t ldtr;
> + uint64_t tr;
> +
> /* manually managed */
> uint64_t idtr;
> uint64_t cr[VMW_CR64_SIZE / 8];
> uint64_t rip;
> uint64_t rflags;
> + uint64_t fs_base;
> + uint64_t gs_base;
> };
> typedef struct vmssregs64 vmssregs64;
>
> -#define REGS_PRESENT_RAX 1<<0
> -#define REGS_PRESENT_RCX 1<<1
> -#define REGS_PRESENT_RDX 1<<2
> -#define REGS_PRESENT_RBX 1<<3
> -#define REGS_PRESENT_RBP 1<<4
> -#define REGS_PRESENT_RSP 1<<5
> -#define REGS_PRESENT_RSI 1<<6
> -#define REGS_PRESENT_RDI 1<<7
> -#define REGS_PRESENT_R8 1<<8
> -#define REGS_PRESENT_R9 1<<9
> -#define REGS_PRESENT_R10 1<<10
> -#define REGS_PRESENT_R11 1<<11
> -#define REGS_PRESENT_R12 1<<12
> -#define REGS_PRESENT_R13 1<<13
> -#define REGS_PRESENT_R14 1<<14
> -#define REGS_PRESENT_R15 1<<15
> -#define REGS_PRESENT_IDTR 1<<16
> -#define REGS_PRESENT_CR0 1<<17
> -#define REGS_PRESENT_CR1 1<<18
> -#define REGS_PRESENT_CR2 1<<19
> -#define REGS_PRESENT_CR3 1<<20
> -#define REGS_PRESENT_CR4 1<<21
> -#define REGS_PRESENT_RIP 1<<22
> -#define REGS_PRESENT_RFLAGS 1<<23
> -#define REGS_PRESENT_GPREGS 65535
> -#define REGS_PRESENT_CRS 4063232
> -#define REGS_PRESENT_ALL 16777215
> +typedef enum SegmentName {
> + SEG_ES,
> + SEG_CS,
> + SEG_SS,
> + SEG_DS,
> + SEG_FS,
> + SEG_GS,
> + SEG_LDTR,
> + SEG_TR,
> + NUM_SEGS
> +} SegmentName;
> +
> +#define REGS_PRESENT_RAX 1L<<0
> +#define REGS_PRESENT_RCX 1L<<1
> +#define REGS_PRESENT_RDX 1L<<2
> +#define REGS_PRESENT_RBX 1L<<3
> +#define REGS_PRESENT_RBP 1L<<4
> +#define REGS_PRESENT_RSP 1L<<5
> +#define REGS_PRESENT_RSI 1L<<6
> +#define REGS_PRESENT_RDI 1L<<7
> +#define REGS_PRESENT_R8 1L<<8
> +#define REGS_PRESENT_R9 1L<<9
> +#define REGS_PRESENT_R10 1L<<10
> +#define REGS_PRESENT_R11 1L<<11
> +#define REGS_PRESENT_R12 1L<<12
> +#define REGS_PRESENT_R13 1L<<13
> +#define REGS_PRESENT_R14 1L<<14
> +#define REGS_PRESENT_R15 1L<<15
> +#define REGS_PRESENT_IDTR 1L<<16
> +#define REGS_PRESENT_CR0 1L<<17
> +#define REGS_PRESENT_CR1 1L<<18
> +#define REGS_PRESENT_CR2 1L<<19
> +#define REGS_PRESENT_CR3 1L<<20
> +#define REGS_PRESENT_CR4 1L<<21
> +#define REGS_PRESENT_RIP 1L<<22
> +#define REGS_PRESENT_RFLAGS 1L<<23
> +
> +#define REGS_PRESENT_ES 1L<<24
> +#define REGS_PRESENT_CS 1L<<25
> +#define REGS_PRESENT_SS 1L<<26
> +#define REGS_PRESENT_DS 1L<<27
> +#define REGS_PRESENT_FS 1L<<28
> +#define REGS_PRESENT_GS 1L<<29
> +#define REGS_PRESENT_LDTR 1L<<30
> +#define REGS_PRESENT_TR 1L<<31
> +#define REGS_PRESENT_FS_BASE 1L<<32
> +#define REGS_PRESENT_GS_BASE 1L<<33
> +
> +#define REGS_PRESENT_GPREGS 0x000000000000FFFF
> +#define REGS_PRESENT_CRS 0x00000000003E0000
> +#define REGS_PRESENT_SEG 0x00000003FF000000
> +#define REGS_PRESENT_ALL 0x00000003FFFFFFFF
>
> #define MAX_REGIONS 3
> struct vmssdata {
> @@ -159,7 +195,7 @@ struct vmssdata {
> uint64_t memsize;
> ulong phys_base;
> int separate_vmem;
> - uint32_t *vcpu_regs;
> + uint64_t *vcpu_regs;
> uint64_t num_vcpus;
> vmssregs64 **regs64;
> };
> -- 2.40.4
2 weeks, 2 days
[PATCH] Fix the segfault issue caused by "dis -s" command
by Lianbo Jiang
I did some tests on the vmcore with Rust enabled, and found that
the "dis -s" command may cause a segfault:
crash> dis -s _RNvCscb18lrEyTSA_10rust_panic10area_in_hp
Enable debuginfod for this session? (y or [n])
FILE: rust_panic.rs
LINE: 22
Segmentation fault (core dumped) ./crash /home/lijiang/src/rust/6.16.3-vmcore-rust/vmlinux /home/lijiang/src/rust/6.16.3-vmcore-rust/vmcore
gdb calltrace:
(gdb) bt
#0 decimal (s=0x0, count=count@entry=0) at tools.c:1113
#1 0x00000000008eea96 in list_source_code (req=0x1081860 <shared_bufs>, count_entered=0) at kernel.c:1578
#2 cmd_dis () at kernel.c:2052
#3 0x000000000086b468 in exec_command () at main.c:893
#4 0x000000000086b6aa in main_loop () at main.c:840
#5 0x00000000006b950c in captured_main (data=data@entry=0x7ffe049a3bd0) at main.c:1374
#6 gdb_main (args=args@entry=0x7ffe049a3c10) at main.c:1407
#7 0x00000000006b9579 in gdb_main_entry (argc=2, argv=argv@entry=0x7ffe049a3db8) at main.c:1434
#8 0x000000000090529e in gdb_main_loop (argc=<optimized out>, argc@entry=3, argv=argv@entry=0x7ffe049a3db8)
at gdb_interface.c:81
#9 0x0000000000438344 in main (argc=3, argv=0x7ffe049a3db8) at main.c:721
(gdb)
This is because the decimal() tried to dereference a NULL pointer in the
list_source_code() path, when the source code is not available. Given
that, let's add a check to fix such cases.
With the patch:
crash> dis -s _RNvCscb18lrEyTSA_10rust_panic10area_in_hp
Enable debuginfod for this session? (y or [n])
FILE: rust_panic.rs
LINE: 22
dis: _RNvCscb18lrEyTSA_10rust_panic10area_in_hp: source code is not available
crash>
Signed-off-by: Lianbo Jiang <lijiang(a)redhat.com>
---
tools.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools.c b/tools.c
index c9305bef7c9c..a9ad18d520d9 100644
--- a/tools.c
+++ b/tools.c
@@ -1110,7 +1110,7 @@ decimal(char *s, int count)
} else
cnt = count;
- for (p = &s[0], digits = 0; *p; p++) {
+ for (p = &s[0], digits = 0; p && *p; p++) {
switch(*p)
{
case '0':
--
2.50.1
2 weeks, 2 days
[PATCH RFC] help: Add 'help -l' to show memory layout
by Rongwei Wang
From: Rongwei Wang <rongwei.wrw(a)gmail.com>
'help -m' can show most of variables which
relates to memory layout, e.g. userspace_top,
page_offset, vmalloc_start_addr, etc. They
aren't a visual way to show a memory layout
for kernel space.
This patch provides 'help -l' to show memory
layout in a table-based way, usage likes:
crash> help -l
+---------------------------------------------------------+
|xxxxxxxxxxxxxxxxxxx gap (size: 8.0 MB) xxxxxxxxxxxxxxxxxx|
|xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx|
+---------------------------------------------------------+
| FIXMAP |
| (0xffffffffff578000 - 0xffffffffff7ff000 size: 2.5 MB) |
+---------------------------------------------------------+
|xxxxxxxxxxxxxxxxxxx gap (size: 5.5 MB) xxxxxxxxxxxxxxxxxx|
|xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx|
+---------------------------------------------------------+
| Module Area |
| (0xffffffffa0000000 - 0xffffffffff000000 size: 1.5 GB) |
+---------------------------------------------------------+
|xxxxxxxxxxxxxxxxxx gap (size: 451.9 MB) xxxxxxxxxxxxxxxxx|
|xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx|
+---------------------------------------------------------+
| kernel image |
| (0xffffffff81000000 - 0xffffffff83c26000 size: 44.1 MB) |
+---------------------------------------------------------+
|xxxxxxxxxxxxxxxxxx gap (size: 21.0 TB) xxxxxxxxxxxxxxxxxx|
|xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx|
|xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx|
|xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx|
+---------------------------------------------------------+
| Vmemmap Area |
| (0xffffea0000000000 - 0xffffeaffffffffff size: 1.0 TB) |
+---------------------------------------------------------+
|xxxxxxxxxxxxxxxxxxx gap (size: 1.0 TB) xxxxxxxxxxxxxxxxxx|
|xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx|
|xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx|
+---------------------------------------------------------+
| Vmalloc/Vfree Area |
| (0xffffc90000000000 - 0xffffe8ffffffffff size: 32.0 TB) |
+---------------------------------------------------------+
|xxxxxxxxxxxxxxxxxx gap (size: 512.0 GB) xxxxxxxxxxxxxxxxx|
|xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx|
+---------------------------------------------------------+
| Linear Mapping Area |
| (0xffff888000000000 - 0xffffc87fffffffff size: 64.0 TB) |
+---------------------------------------------------------+
| Kernel Space Offset |
| (0xffff800000000000 - 0xffff887fffffffff size: 8.5 TB) |
+---------------------------------------------------------+
|xxxxxxxxxxxxxxx gap (size: 16776960.0 TB) xxxxxxxxxxxxxxx|
|xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx|
|xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx|
|xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx|
+---------------------------------------------------------+
| User Space |
| (size: 128.0 TB) |
+---------------------------------------------------------+
Signed-off-by: Rongwei Wang <rongwei.wrw(a)gmail.com>
---
defs.h | 14 +-
help.c | 7 +-
memory.c | 11 ++
x86_64.c | 388 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 418 insertions(+), 2 deletions(-)
diff --git a/defs.h b/defs.h
index bbd6d4b..66b1c8e 100644
--- a/defs.h
+++ b/defs.h
@@ -4097,12 +4097,23 @@ typedef signed int s32;
#define __PHYSICAL_MASK_SHIFT_5LEVEL 52
#define __PHYSICAL_MASK_SHIFT (machdep->machspec->physical_mask_shift)
#define __PHYSICAL_MASK ((1UL << __PHYSICAL_MASK_SHIFT) - 1)
-#define __VIRTUAL_MASK_SHIFT 48
+#define __VIRTUAL_MASK_SHIFT 47
#define __VIRTUAL_MASK ((1UL << __VIRTUAL_MASK_SHIFT) - 1)
#define PAGE_SHIFT 12
#define PAGE_SIZE (1UL << PAGE_SHIFT)
#define PHYSICAL_PAGE_MASK (~(PAGE_SIZE-1) & __PHYSICAL_MASK )
+
+#define KASAN_SHADOW_OFFSET 0xdffffc0000000000
+#define KASAN_SHADOW_SCALE_SHIFT 3
+
+#define KASAN_SHADOW_START (KASAN_SHADOW_OFFSET + \
+ ((-1UL << __VIRTUAL_MASK_SHIFT) >> \
+ KASAN_SHADOW_SCALE_SHIFT))
+#define KASAN_SHADOW_END (KASAN_SHADOW_START + \
+ (1ULL << (__VIRTUAL_MASK_SHIFT - \
+ KASAN_SHADOW_SCALE_SHIFT)))
+
#define _PAGE_BIT_NX 63
#define _PAGE_PRESENT 0x001
#define _PAGE_RW 0x002
@@ -5908,6 +5919,7 @@ int phys_to_page(physaddr_t, ulong *);
int generic_get_kvaddr_ranges(struct vaddr_range *);
int l1_cache_size(void);
int dumpfile_memory(int);
+void dump_memory_layout(void);
#define DUMPFILE_MEM_USED (1)
#define DUMPFILE_FREE_MEM (2)
#define DUMPFILE_MEM_DUMP (3)
diff --git a/help.c b/help.c
index 5d61e0d..cd54744 100644
--- a/help.c
+++ b/help.c
@@ -538,7 +538,7 @@ cmd_help(void)
oflag = 0;
while ((c = getopt(argcnt, args,
- "efNDdmM:ngcaBbHhkKsvVoptTzLOr")) != EOF) {
+ "efNDdmM:ngcaBbHhkKsvVoptTzLOrl")) != EOF) {
switch(c)
{
case 'e':
@@ -666,6 +666,7 @@ cmd_help(void)
fprintf(fp, " -v - vm_table\n");
fprintf(fp, " -V - vm_table (verbose)\n");
fprintf(fp, " -z - help options\n");
+ fprintf(fp, " -l - show memory layout\n");
return;
case 'L':
@@ -676,6 +677,10 @@ cmd_help(void)
dump_registers();
return;
+ case 'l':
+ dump_memory_layout();
+ return;
+
default:
argerrs++;
break;
diff --git a/memory.c b/memory.c
index 400d31a..55ed2f1 100644
--- a/memory.c
+++ b/memory.c
@@ -17657,6 +17657,17 @@ dumpfile_memory(int cmd)
return retval;
}
+#ifdef X86_64
+extern void x86_64_dump_memory_layout(void);
+#endif
+
+void dump_memory_layout(void)
+{
+#ifdef X86_64
+ x86_64_dump_memory_layout();
+#endif
+}
+
/*
* Functions for sparse mem support
*/
diff --git a/x86_64.c b/x86_64.c
index d7da536..b4d2821 100644
--- a/x86_64.c
+++ b/x86_64.c
@@ -1151,6 +1151,394 @@ x86_64_dump_machdep_table(ulong arg)
fprintf(fp, "excpetion_functions_orig\n");
}
+#define MAX_LAYOUT 32
+#define MAX_COL_LAYOUT 60
+struct mem_segment {
+ char name[64];
+ char desc[128];
+ unsigned long start;
+ unsigned long end;
+ int width;
+ char fill_char;
+};
+
+struct mem_layout {
+ int count;
+ int capacity;
+ struct mem_segment segs[MAX_LAYOUT];
+};
+
+char* format_bytes(unsigned long bytes, char* buffer, int buffer_size)
+{
+ const char* units[] = {"B", "KB", "MB", "GB", "TB"};
+ int i = 0;
+ double readable_size = (double)bytes;
+
+ /* Handle the edge case of zero bytes */
+ if (bytes == 0) {
+ snprintf(buffer, buffer_size, "0 B");
+ return buffer;
+ }
+
+ /* Handle negative values if necessary, though size is typically non-negative */
+ if (bytes < 0) {
+ snprintf(buffer, buffer_size, "Invalid size");
+ return buffer;
+ }
+
+ while (readable_size >= 1024 && i < (sizeof(units) / sizeof(units[0]) - 1)) {
+ readable_size /= 1024;
+ i++;
+ }
+
+ memset(buffer, '\0', buffer_size);
+ snprintf(buffer, buffer_size, "%.1f %s", readable_size, units[i]);
+
+ return buffer;
+}
+
+int compare_segments(const void *a, const void *b)
+{
+ const struct mem_segment *seg_a = (const struct mem_segment *)a;
+ const struct mem_segment *seg_b = (const struct mem_segment *)b;
+
+ if (seg_a->start > seg_b->start) return -1;
+ if (seg_a->start < seg_b->start) return 1;
+ return 0;
+}
+
+void* make_layout(struct mem_layout *layout, int max_row, int max_col)
+{
+ int col = MAX_COL_LAYOUT;
+ int row = max_row + 1;
+ char *layout_raw;
+ int i,j;
+ unsigned int cursor = 0;
+ int idx = 0;
+
+ if (max_col > col)
+ col = max_col;
+
+ layout_raw = (char *)malloc(row * col * sizeof(char));
+ memset(layout_raw, ' ', row * col * sizeof(char));
+ for (i=0; i<layout->count; i++) {
+ int center_bias = 0;
+ char fill = layout->segs[i].fill_char;
+
+ memset(layout_raw+cursor, '-', col);
+ layout_raw[cursor] = layout_raw[cursor+col-2] = '+';
+ layout_raw[cursor+col-1] = '\n';
+ cursor += col; /* next row */
+
+ memset(layout_raw+cursor, fill, col);
+ layout_raw[cursor] = '|';
+ layout_raw[cursor+col-2] = '|';
+ layout_raw[cursor+col-1] = '\n';
+ center_bias = (col - strlen(layout->segs[i].name)) / 2;
+ memcpy(layout_raw + cursor + center_bias, layout->segs[i].name,
+ strlen(layout->segs[i].name));
+ cursor += col; /* next row */
+
+ if (strlen(layout->segs[i].desc) != 0) {
+ memset(layout_raw+cursor, fill, col);
+ layout_raw[cursor] = '|';
+ layout_raw[cursor+col-2] = '|';
+ layout_raw[cursor+col-1] = '\n';
+
+ center_bias = (col - strlen(layout->segs[i].desc)) / 2;
+ memcpy(layout_raw + cursor + center_bias, layout->segs[i].desc,
+ strlen(layout->segs[i].desc));
+
+ cursor += col; /* next row */
+ } else {
+ /* It's a gap area. */
+ int width = layout->segs[i].width;
+
+ while(width--) {
+ memset(layout_raw+cursor, fill, col);
+ layout_raw[cursor] = '|';
+ layout_raw[cursor+col-2] = '|';
+ layout_raw[cursor+col-1] = '\n';
+ cursor += col; /* next row */
+ }
+ }
+
+ if (i == (layout->count - 1)) {
+ /* last line */
+ memset(layout_raw+cursor, '-', col);
+ layout_raw[cursor] = layout_raw[cursor+col-2] = '+';
+ layout_raw[cursor+col-1] = '\n';
+ layout_raw[cursor+col] = '\0';
+ }
+ }
+
+ return layout_raw;
+}
+
+void print_layout(struct mem_layout *layout)
+{
+ int max_col = 0;
+ int max_row = 0;
+ struct mem_segment *segs = layout->segs;
+ struct mem_segment seg;
+ int i, j;
+ char *layout_raw;
+ char *string;
+
+ if (layout == NULL)
+ return;
+
+ /* calculate the max col which can includes all 'desc' */
+ for (i=0; i<layout->count; i++) {
+ int col = 0;
+ int cursor = 0;
+ int row = 1; /* the minimal row */
+
+ seg = segs[i];
+ col = strlen(seg.name);
+
+ max_col = (max_col >= col) ?: col;
+ /* The gap area has no desc. */
+ if (seg.desc[0] != '\0') {
+ col = strlen(seg.desc);
+ row += 1;
+ max_col = (max_col >= col) ?: col;
+ } else
+ row += segs[i].width;
+
+ max_row += row;
+ }
+ /* add border line */
+ max_row += layout->count + 1;
+ max_col + 3;
+
+ layout_raw = make_layout(layout, max_row, max_col);
+ fprintf(fp, "%s", layout_raw);
+ free(layout_raw);
+}
+
+#define __round_mask(x, y) ((__typeof__(x))((y)-1))
+#define round_up(x, y) ((((x)-1) | __round_mask(x, y))+1)
+#define round_down(x, y) ((x) & ~__round_mask(x, y))
+
+/*
+ * table-based memory layout:
+ *
+ * +---------------------------------------------------------+
+ * |xxxxxxxxxxxxxxxxxxx gap (size: 8.0 MB) xxxxxxxxxxxxxxxxxx|
+ * +---------------------------------------------------------+
+ * | FIXMAP |
+ * | (0xffffffffff578000 - 0xffffffffff7ff000 size: 2.5 MB) |
+ * +---------------------------------------------------------+
+ * |xxxxxxxxxxxxxxxxxxx gap (size: 5.5 MB) xxxxxxxxxxxxxxxxxx|
+ * +---------------------------------------------------------+
+ * | Module Area |
+ * | (0xffffffffa0000000 - 0xffffffffff000000 size: 1.5 GB) |
+ * +---------------------------------------------------------+
+ * |xxxxxxxxxxxxxxxxxx gap (size: 451.9 MB) xxxxxxxxxxxxxxxxx|
+ * +---------------------------------------------------------+
+ * | kernel image |
+ * | (0xffffffff81000000 - 0xffffffff83c26000 size: 44.1 MB) |
+ * +---------------------------------------------------------+
+ * |xxxxxxxxxxxxxxxxxx gap (size: 21.0 TB) xxxxxxxxxxxxxxxxxx|
+ * |xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx|
+ * |xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx|
+ * +---------------------------------------------------------+
+ * | Vmemmap Area |
+ * | (0xffffea0000000000 - 0xffffeaffffffffff size: 1.0 TB) |
+ * +---------------------------------------------------------+
+ * |xxxxxxxxxxxxxxxxxxx gap (size: 1.0 TB) xxxxxxxxxxxxxxxxxx|
+ * |xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx|
+ * +---------------------------------------------------------+
+ * | Vmalloc/Vfree Area |
+ * | (0xffffc90000000000 - 0xffffe8ffffffffff size: 32.0 TB) |
+ * +---------------------------------------------------------+
+ * |xxxxxxxxxxxxxxxxxx gap (size: 512.0 GB) xxxxxxxxxxxxxxxxx|
+ * +---------------------------------------------------------+
+ * | Linear Mapping Area |
+ * | (0xffff888000000000 - 0xffffc87fffffffff size: 64.0 TB) |
+ * +---------------------------------------------------------+
+ * | Kernel Space Offset |
+ * | (0xffff800000000000 - 0xffff887fffffffff size: 8.5 TB) |
+ * +---------------------------------------------------------+
+ * |xxxxxxxxxxxxxxx gap (size: 16776960.0 TB) xxxxxxxxxxxxxxx|
+ * |xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx|
+ * |xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx|
+ * +---------------------------------------------------------+
+ * | User Space |
+ * | (size: 128.0 TB) |
+ * +---------------------------------------------------------+
+ *
+ * kernel space:
+ * _end, _text
+ * vmemmap_end: ms->vmemmap_end
+ * vmemmap_vaddr: ms->vmemmap_vaddr
+ * vmalloc_end: ms->vmalloc_end
+ * vmalloc_start_addr: ms->vmalloc_start_addr
+ * page_offset_base: ms->page_offset
+ *
+ * user space:
+ * userspace_top: ms->userspace_top
+ *
+ */
+void x86_64_dump_memory_layout(void)
+{
+ struct mem_layout *layout = NULL;
+ ulong text_start, text_end;
+ struct machine_specific *ms = machdep->machspec;
+ int i, next_idx;
+ char size_buf[20];
+ long value = 0;
+
+ layout = malloc(sizeof(struct mem_layout));
+ if (layout == NULL || layout->count == 0) {
+ printf("Layout is empty, nothing to print.\n");
+ return;
+ }
+
+ /* Create a temporary copy to sort for printing, preserving the original order. */
+ struct mem_segment *sorted_segments = layout->segs;
+ if(!sorted_segments) {
+ perror("Failed to allocate memory for sorting");
+ return;
+ }
+
+ if (!symbol_exists("_text"))
+ return;
+ else
+ text_start = symbol_value("_text");
+
+ if (!symbol_exists("_end"))
+ return;
+ else
+ text_end = symbol_value("_end");
+
+ snprintf(sorted_segments[0].name, 64, "kernel image");
+ snprintf(sorted_segments[0].desc, 64, "(0x%lx - 0x%lx size: %s)",
+ text_start, text_end,
+ format_bytes(text_end - text_start + 1, size_buf, 20));
+ sorted_segments[0].start = text_start;
+ sorted_segments[0].end = text_end;
+ sorted_segments[0].fill_char = ' ';
+
+ snprintf(sorted_segments[1].name, 64, "Vmemmap Area");
+ snprintf(sorted_segments[1].desc, 64, "(0x%lx - 0x%lx size: %s)",
+ (ulong)ms->vmemmap_vaddr, (ulong)ms->vmemmap_end,
+ format_bytes(ms->vmemmap_end - ms->vmemmap_vaddr + 1, size_buf, 20));
+ sorted_segments[1].start = (ulong)ms->vmemmap_vaddr;
+ sorted_segments[1].end = (ulong)ms->vmemmap_end;
+ sorted_segments[1].fill_char = ' ';
+
+ snprintf(sorted_segments[2].name, 64, "Module Area");
+ snprintf(sorted_segments[2].desc, 64, "(0x%lx - 0x%lx size: %s)",
+ (ulong)ms->modules_vaddr,(ulong)ms->modules_end,
+ format_bytes(ms->modules_end - ms->modules_vaddr + 1, size_buf, 20));
+ sorted_segments[2].start = (ulong)ms->modules_vaddr;
+ sorted_segments[2].end = (ulong)ms->modules_end;
+ sorted_segments[2].fill_char = ' ';
+
+ snprintf(sorted_segments[3].name, 64, "Vmalloc/Vfree Area");
+ snprintf(sorted_segments[3].desc, 64, "(0x%lx - 0x%lx size: %s)",
+ (ulong)ms->vmalloc_start_addr, (ulong)ms->vmalloc_end,
+ format_bytes(ms->vmalloc_end - ms->vmalloc_start_addr + 1, size_buf, 20));
+ sorted_segments[3].start = (ulong)ms->vmalloc_start_addr;
+ sorted_segments[3].end = (ulong)ms->vmalloc_end;
+ sorted_segments[3].fill_char = ' ';
+
+ snprintf(sorted_segments[4].name, 64, "Linear Mapping Area");
+ sorted_segments[4].start = (ulong)ms->page_offset;
+ sorted_segments[4].end = (ulong)ms->page_offset + (1UL << machdep->max_physmem_bits) - 1;
+ sorted_segments[4].fill_char = ' ';
+ snprintf(sorted_segments[4].desc, 64, "(0x%lx - 0x%lx size: %s)",
+ sorted_segments[4].start, sorted_segments[4].end,
+ format_bytes(1UL << machdep->max_physmem_bits, size_buf, 20));
+
+ snprintf(sorted_segments[5].name, 64, "User Space");
+ snprintf(sorted_segments[5].desc, 64, "(size: %s)",
+ format_bytes((ulong)ms->userspace_top, size_buf, 20));
+ sorted_segments[5].start = 0UL;
+ sorted_segments[5].end = (ulong)ms->userspace_top - 1;
+ sorted_segments[5].fill_char = ' ';
+
+ snprintf(sorted_segments[6].name, 64, "Kernel Space Offset");
+ sorted_segments[6].start = -1UL - (1UL << __VIRTUAL_MASK_SHIFT) + 1;
+ sorted_segments[6].end = (ulong)ms->page_offset - 1;
+ sorted_segments[6].fill_char = ' ';
+ snprintf(sorted_segments[6].desc, 64, "(0x%lx - 0x%lx size: %s)",
+ sorted_segments[6].start, sorted_segments[6].end,
+ format_bytes(sorted_segments[6].end - sorted_segments[6].start + 1, size_buf, 20));
+
+ layout->count = 7;
+ if (kernel_symbol_exists("kasan_init")) {
+ snprintf(sorted_segments[7].name, 64, "KASAN");
+ sorted_segments[7].start = KASAN_SHADOW_START;
+ sorted_segments[7].end = KASAN_SHADOW_END;
+ sorted_segments[7].fill_char = ' ';
+ snprintf(sorted_segments[7].desc, 64, "(0x%lx - 0x%lx size: %s)",
+ sorted_segments[7].start, sorted_segments[7].end,
+ format_bytes(sorted_segments[7].end - sorted_segments[7].start + 1, size_buf, 20));
+ layout->count++;
+ }
+
+ if (enumerator_value("__end_of_permanent_fixed_addresses", &value)) {
+ unsigned fixaddr_size = 0;
+ int idx = layout->count;
+
+ fixaddr_size = value << PAGE_SHIFT;
+
+ snprintf(sorted_segments[7].name, 64, "FIXMAP");
+ sorted_segments[idx].end = round_up(VSYSCALL_START + PAGE_SIZE, 1 << PMD_SHIFT) - PAGE_SIZE;
+ sorted_segments[idx].start = sorted_segments[idx].end - fixaddr_size;
+
+ sorted_segments[idx].fill_char = ' ';
+ snprintf(sorted_segments[idx].desc, 64, "(0x%lx - 0x%lx size: %s)",
+ sorted_segments[idx].start, sorted_segments[idx].end,
+ format_bytes(sorted_segments[idx].end - sorted_segments[idx].start + 1, size_buf, 20));
+ layout->count++;
+ }
+
+ /* Sort segments from highest address to lowest. */
+ qsort(sorted_segments, layout->count, sizeof(struct mem_segment), compare_segments);
+
+ next_idx = layout->count;
+ /* Insert gap area */
+ for (i=0; i<layout->count; i++) {
+ unsigned long prev_start;
+ unsigned long end = sorted_segments[i].end;
+
+ if (i == 0)
+ prev_start = -1UL;
+ else
+ prev_start = sorted_segments[i-1].start;
+
+ if (prev_start == (end + 1))
+ continue;
+
+ if ((prev_start - end) >= (8UL * 1024 * 1024 * 1024 * 1024))
+ sorted_segments[next_idx].width = 3;
+ else if ((prev_start - end) >= (1UL * 1024 * 1024 * 1024 * 1024))
+ sorted_segments[next_idx].width = 2;
+ else
+ sorted_segments[next_idx].width = 1;
+
+ sorted_segments[next_idx].start = end + 1;
+ sorted_segments[next_idx].end = (i == 0) ? prev_start : prev_start - 1;
+ sorted_segments[next_idx].fill_char = 'x';
+ snprintf(sorted_segments[next_idx].name, 64, " gap (size: %s) ",
+ format_bytes(sorted_segments[next_idx].end - sorted_segments[next_idx].start + 1,
+ size_buf, 20));
+ sorted_segments[next_idx].desc[0] = '\0';
+
+ next_idx++;
+ }
+
+ layout->count = next_idx;
+ qsort(sorted_segments, layout->count, sizeof(struct mem_segment), compare_segments);
+
+ print_layout(layout);
+ free(layout);
+}
+
/*
* Gather the cpu_pda array info, updating any smp-related items that
* were possibly bypassed or improperly initialized in kernel_init().
--
2.39.3
2 weeks, 3 days
Behind the Scenes of Campus Data Centers: Insights from Crash Utility Practices
by yingashley13@gmail.com
Modern universities rely heavily on digital infrastructure to keep classrooms, online platforms, and administrative systems running smoothly. While students and faculty experience seamless access to online courses, virtual libraries, and academic portals, much of this reliability comes from what happens behind the scenes—specifically within campus data centers. These centers serve as the backbone of digital learning, ensuring continuous access to resources, stable performance, and quick recovery during system failures.
In higher education, the importance of uninterrupted online learning cannot be overstated. Many students, for instance, rely on platforms like Myassignmenthelp for academic support, where they might search for options such as take my online class for me (https://myassignmenthelp.com/take-my-online-class.html
). This highlights how critical system reliability is for educational services, whether hosted directly by universities or through third-party academic support platforms. Without dependable infrastructure, both students and institutions risk losing valuable time, resources, and learning opportunities.
This is where practices drawn from tools like the Crash Utility come into play. Originally designed for analyzing Linux kernel crash dumps, these tools provide system administrators with detailed insights into why systems fail. For campus data centers, adopting similar diagnostic approaches allows IT teams to quickly identify the root cause of failures, prevent recurring issues, and maintain high system availability. In turn, this ensures that students can log into their learning portals, submit assignments, and access lecture recordings without disruption.
Moreover, proactive crash analysis fosters a culture of resilience within educational institutions. Instead of waiting for problems to escalate, IT administrators can anticipate potential bottlenecks or vulnerabilities and resolve them before they affect users. For universities striving to enhance their digital infrastructure, integrating such practices strengthens their ability to support large-scale e-learning initiatives, hybrid classrooms, and research collaborations.
In conclusion, while students may only see the front-end of digital learning systems, the true strength of an institution lies in its backend stability. By incorporating insights from crash utility practices, campus data centers can ensure smooth, uninterrupted academic experiences—making education more accessible, reliable, and future-ready.
2 weeks, 5 days
Behind the Scenes of Campus Data Centers: Insights from Crash Utility Practices
by yingashley13@gmail.com
Modern universities rely heavily on digital infrastructure to keep classrooms, online platforms, and administrative systems running smoothly. While students and faculty experience seamless access to online courses, virtual libraries, and academic portals, much of this reliability comes from what happens behind the scenes—specifically within campus data centers. These centers serve as the backbone of digital learning, ensuring continuous access to resources, stable performance, and quick recovery during system failures.
In higher education, the importance of uninterrupted online learning cannot be overstated. Many students, for instance, rely on platforms like Myassignmenthelp for academic support, where they might search for options such as take my online class for me (https://myassignmenthelp.com/take-my-online-class.html
). This highlights how critical system reliability is for educational services, whether hosted directly by universities or through third-party academic support platforms. Without dependable infrastructure, both students and institutions risk losing valuable time, resources, and learning opportunities.
This is where practices drawn from tools like the Crash Utility come into play. Originally designed for analyzing Linux kernel crash dumps, these tools provide system administrators with detailed insights into why systems fail. For campus data centers, adopting similar diagnostic approaches allows IT teams to quickly identify the root cause of failures, prevent recurring issues, and maintain high system availability. In turn, this ensures that students can log into their learning portals, submit assignments, and access lecture recordings without disruption.
Moreover, proactive crash analysis fosters a culture of resilience within educational institutions. Instead of waiting for problems to escalate, IT administrators can anticipate potential bottlenecks or vulnerabilities and resolve them before they affect users. For universities striving to enhance their digital infrastructure, integrating such practices strengthens their ability to support large-scale e-learning initiatives, hybrid classrooms, and research collaborations.
In conclusion, while students may only see the front-end of digital learning systems, the true strength of an institution lies in its backend stability. By incorporating insights from crash utility practices, campus data centers can ensure smooth, uninterrupted academic experiences—making education more accessible, reliable, and future-ready.
2 weeks, 5 days
Re: [PATCH v1 0/5] extension: Several improvements on eppic extension
by lijiang
Hi, Tao
On Thu, Aug 21, 2025 at 6:58 AM <devel-request(a)lists.crash-utility.osci.io>
wrote:
> Date: Thu, 21 Aug 2025 10:55:24 +1200
> From: Tao Liu <ltao(a)redhat.com>
> Subject: [Crash-utility] [PATCH v1 0/5] extension: Several
> improvements on eppic extension
> To: devel(a)lists.crash-utility.osci.io
> Cc: Tao Liu <ltao(a)redhat.com>
> Message-ID: <20250820225529.6369-1-ltao(a)redhat.com>
> Content-Type: text/plain; charset="US-ASCII"; x-default=true
>
> Eppic works as a crash extension for a long time, and it is a very
> convenient
> tool to extend crash's function:
>
> 1) People don't need to write an actual crash extension, which requires
> knowledge of crash APIs, such as readmem(), gdb_interface() etc.
> Implementing such an crash extension is hard for normal users.
> 2) Eppic programs are C-syntax-like scripting, no compile needed, so
> friendly
> to kernel developers who are already familiar with C. It's a good
> alternative
> for people who are unfamiliar with python (comparing to drgn/pykdump).
> 3) Writing eppic programs is similar to do kernel programming, people can
> use
> kernel data structures/global variables directly, again, friendly to
> kernel
> developers.
>
> Personally I think eppic is a good tool and would like to push it forward
> to
> make it used more widely, improved consistently. However I hardly heard
> anyone
> who are using it, I guess it is due to it's extension position and unknown
> to
> others.
>
> In this patchset, I will make several improvements on eppic, although it is
> still a crash extension, but I think it is made more easily for
> compile/run/scripting.
>
Thank you for your efforts and working on this.
Think it over, I have several comments about this:
[1] In this patchset, the patch[1] and patch[4] are fine to me, although I
haven't looked at the code details and tested them yet(plan to do it in v2)
[2] Currently the patch[2] and patch[3] seem to be unnecessary, the eppic
is an extension module, no need to load it by default, furthermore, this
should be good enough to compile extension modules with the "make
extensions" command, and it is also convenient to load the eppic module
with "extend eppic.so", not very complicated.
[3] The patch[5] is for alias, I do not recommend changing the user
interface(or user habits), and also there is a crash internal command
'alias' to do the same thing.
[4] Can you also add a doc(or description) to give some simple examples,
Eg: how to use it quickly? That can help other people understand the usage.
Thanks
Lianbo
> To-do:
>
> Some crash functions should be exposed to eppic, such as
> maple_tree/rbtree etc, so people can iterate these kernel structures
> with no problem, e.g. vma iteration. The exposure isn't hard and can be
> implemented later.
>
> Tao Liu (5):
> extensions: modify search path and extension preload
> Makefile: allow "make eppic" to create the eppic extension
> configure: Add EPPIC to Cflags
> eppic.patch: Add customized functions to eppic
> alias: create "eppic" alias to run eppic programs
>
> Makefile | 12 ++-
> configure.c | 14 ++-
> defs.h | 2 +-
> extensions.c | 83 +++++++++++-------
> extensions/Makefile | 2 +-
> extensions/eppic.mk | 13 ++-
> extensions/eppic.patch | 195 +++++++++++++++++++++++++++++++++++++++++
> main.c | 16 +++-
> 8 files changed, 295 insertions(+), 42 deletions(-)
> create mode 100644 extensions/eppic.patch
>
> --
> 2.47.0
>
3 weeks
[PATCH] mem: rename variable for clarity in get_kmem_cache_slub_data()
by Ye Liu
Rename 'cpu_slab_ptr' to 'cpu_slab_page_ptr' to better reflect that
it holds a pointer to a page structure rather than a generic slab pointer.
This improves code readability and consistency with related functions.
No functional changes.
Signed-off-by: Ye Liu <liuye(a)kylinos.cn>
---
memory.c | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/memory.c b/memory.c
index 400d31a04cd4..be5c590003a8 100644
--- a/memory.c
+++ b/memory.c
@@ -19426,7 +19426,7 @@ get_kmem_cache_slub_data(long cmd, struct meminfo *si)
{
int i, n, node;
ulong total_objects, total_slabs, free_objects;
- ulong cpu_slab_ptr, node_ptr, cpu_freelist, orig_slab;
+ ulong cpu_slab_page_ptr, node_ptr, cpu_freelist, orig_slab;
ulong node_nr_partial, node_nr_slabs, node_total_objects;
int full_slabs, objects, node_total_avail;
long p;
@@ -19445,12 +19445,12 @@ get_kmem_cache_slub_data(long cmd, struct meminfo *si)
node_total_avail = VALID_MEMBER(kmem_cache_node_total_objects) ? TRUE : FALSE;
for (i = 0; i < kt->cpus; i++) {
- cpu_slab_ptr = get_cpu_slab_ptr(si, i, &cpu_freelist);
+ cpu_slab_page_ptr = get_cpu_slab_ptr(si, i, &cpu_freelist);
- if (!cpu_slab_ptr)
+ if (!cpu_slab_page_ptr)
continue;
- if ((node = page_to_nid(cpu_slab_ptr)) < 0)
+ if ((node = page_to_nid(cpu_slab_page_ptr)) < 0)
goto bailout;
switch (cmd)
@@ -19458,15 +19458,15 @@ get_kmem_cache_slub_data(long cmd, struct meminfo *si)
case GET_SLUB_OBJECTS: {
/* For better error report, set cur slab to si->slab. */
orig_slab = si->slab;
- si->slab = cpu_slab_ptr;
+ si->slab = cpu_slab_page_ptr;
- if (!readmem(cpu_slab_ptr + OFFSET(page_inuse),
+ if (!readmem(cpu_slab_page_ptr + OFFSET(page_inuse),
KVADDR, &inuse, sizeof(short),
"page inuse", RETURN_ON_ERROR)) {
si->slab = orig_slab;
return FALSE;
}
- objects = slub_page_objects(si, cpu_slab_ptr);
+ objects = slub_page_objects(si, cpu_slab_page_ptr);
if (!objects) {
si->slab = orig_slab;
return FALSE;
--
2.43.0
3 weeks