Hi lianbo & qiwu, For the v3, LGTM, so ack. Thanks, Tao Liu On Fri, Sep 20, 2024 at 6:55 PM lijiang <lijiang@xxxxxxxxxx> wrote: > > On Fri, Sep 20, 2024 at 9:30 AM <devel-request@xxxxxxxxxxxxxxxxxxxxxxxxxxx> wrote: >> >> Date: Fri, 20 Sep 2024 01:28:32 -0000 >> From: qiwu.chen@xxxxxxxxxxxxx >> Subject: [PATCH v3] kmem: fix the determination for >> slab page >> To: devel@xxxxxxxxxxxxxxxxxxxxxxxxxxx >> Message-ID: <20240920012832.29184.28326@xxxxxxxxxxxxxxxxxxxxxxxxxxx> >> Content-Type: text/plain; charset="utf-8" >> >> The determination for a slab page has changed due to changing >> PG_slab from a page flag to a page type since kernel commit >> 46df8e73a4a3. >> >> Before apply this patch: >> crash> kmem -s ffff000002aa4100 >> kmem: address is not allocated in slab subsystem: ffff000002aa4100 >> >> After apply this patch: >> crash> kmem -s ffff000002aa4100 >> CACHE OBJSIZE ALLOCATED TOTAL SLABS SSIZE NAME >> ffff00000140f900 4096 94 126 18 32k task_struct >> SLAB MEMORY NODE TOTAL ALLOCATED FREE >> fffffdffc00aa800 ffff000002aa0000 0 7 5 2 >> FREE / [ALLOCATED] >> [ffff000002aa4100] >> >> Signed-off-by: qiwu.chen <qiwu.chen@xxxxxxxxxxxxx> >> --- >> defs.h | 7 ++++++ >> memory.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++--------- >> symbols.c | 2 ++ >> 3 files changed, 66 insertions(+), 11 deletions(-) >> > > Thank you for the update, qiwu. > > I have no other issues, for the v3: Ack > > Thanks > Lianbo > >> >> diff --git a/defs.h b/defs.h >> index 2231cb6..e2a9278 100644 >> --- a/defs.h >> +++ b/defs.h >> @@ -2243,6 +2243,7 @@ struct offset_table { /* stash of commonly-used offsets */ >> long vmap_node_busy; >> long rb_list_head; >> long file_f_inode; >> + long page_page_type; >> }; >> >> struct size_table { /* stash of commonly-used sizes */ >> @@ -2651,6 +2652,7 @@ struct vm_table { /* kernel VM-related data */ >> ulong max_mem_section_nr; >> ulong zero_paddr; >> ulong huge_zero_paddr; >> + uint page_type_base; >> }; >> >> #define NODES (0x1) >> @@ -2684,6 +2686,11 @@ struct vm_table { /* kernel VM-related data */ >> #define SLAB_CPU_CACHE (0x10000000) >> #define SLAB_ROOT_CACHES (0x20000000) >> #define USE_VMAP_NODES (0x40000000) >> +/* >> + * The SLAB_PAGEFLAGS flag is introduced to detect the change of >> + * PG_slab's type from a page flag to a page type. >> + */ >> +#define SLAB_PAGEFLAGS (0x80000000) >> >> #define IS_FLATMEM() (vt->flags & FLATMEM) >> #define IS_DISCONTIGMEM() (vt->flags & DISCONTIGMEM) >> diff --git a/memory.c b/memory.c >> index 967a9cf..8befe8c 100644 >> --- a/memory.c >> +++ b/memory.c >> @@ -351,6 +351,43 @@ static ulong handle_each_vm_area(struct handle_each_vm_area_args *); >> >> static ulong DISPLAY_DEFAULT; >> >> +/* >> + * Before kernel commit ff202303c398e, the value is defined as a macro, so copy it here; >> + * After this commit, the value is defined as an enum, which can be evaluated at runtime. >> + */ >> +#define PAGE_TYPE_BASE 0xf0000000 >> +#define PageType(page_type, flag) \ >> + ((page_type & (vt->page_type_base | flag)) == vt->page_type_base) >> + >> +static void page_type_init(void) >> +{ >> + if (!enumerator_value("PAGE_TYPE_BASE", (long *)&vt->page_type_base)) >> + vt->page_type_base = PAGE_TYPE_BASE; >> +} >> + >> +/* >> + * The PG_slab's type has changed from a page flag to a page type >> + * since kernel commit 46df8e73a4a3. >> + */ >> +static bool page_slab(ulong page, ulong flags) >> +{ >> + if (vt->flags & SLAB_PAGEFLAGS) { >> + if ((flags >> vt->PG_slab) & 1) >> + return TRUE; >> + } >> + >> + if (VALID_MEMBER(page_page_type)) { >> + uint page_type; >> + >> + readmem(page+OFFSET(page_page_type), KVADDR, &page_type, >> + sizeof(page_type), "page_type", FAULT_ON_ERROR); >> + if (PageType(page_type, (uint)vt->PG_slab)) >> + return TRUE; >> + } >> + >> + return FALSE; >> +} >> + >> /* >> * Verify that the sizeof the primitive types are reasonable. >> */ >> @@ -504,6 +541,7 @@ vm_init(void) >> ANON_MEMBER_OFFSET_INIT(page_compound_head, "page", "compound_head"); >> MEMBER_OFFSET_INIT(page_private, "page", "private"); >> MEMBER_OFFSET_INIT(page_freelist, "page", "freelist"); >> + MEMBER_OFFSET_INIT(page_page_type, "page", "page_type"); >> >> MEMBER_OFFSET_INIT(mm_struct_pgd, "mm_struct", "pgd"); >> >> @@ -1278,6 +1316,8 @@ vm_init(void) >> >> page_flags_init(); >> >> + page_type_init(); >> + >> rss_page_types_init(); >> >> vt->flags |= VM_INIT; >> @@ -5931,7 +5971,7 @@ dump_mem_map_SPARSEMEM(struct meminfo *mi) >> if ((flags >> v22_PG_Slab) & 1) >> slabs++; >> } else if (vt->PG_slab) { >> - if ((flags >> vt->PG_slab) & 1) >> + if (page_slab(pp, flags)) >> slabs++; >> } else { >> if ((flags >> v24_PG_slab) & 1) >> @@ -6381,7 +6421,7 @@ dump_mem_map(struct meminfo *mi) >> if ((flags >> v22_PG_Slab) & 1) >> slabs++; >> } else if (vt->PG_slab) { >> - if ((flags >> vt->PG_slab) & 1) >> + if (page_slab(pp, flags)) >> slabs++; >> } else { >> if ((flags >> v24_PG_slab) & 1) >> @@ -6694,7 +6734,6 @@ dump_hstates() >> FREEBUF(hstate); >> } >> >> - >> static void >> page_flags_init(void) >> { >> @@ -6775,6 +6814,9 @@ page_flags_init_from_pageflag_names(void) >> vt->pageflags_data[i].name = nameptr; >> vt->pageflags_data[i].mask = mask; >> >> + if (!strncmp(nameptr, "slab", 4)) >> + vt->flags |= SLAB_PAGEFLAGS; >> + >> if (CRASHDEBUG(1)) { >> fprintf(fp, " %08lx %s\n", >> vt->pageflags_data[i].mask, >> @@ -6835,8 +6877,9 @@ page_flags_init_from_pageflags_enum(void) >> } >> strcpy(nameptr, arglist[0] + strlen("PG_")); >> vt->pageflags_data[p].name = nameptr; >> - vt->pageflags_data[p].mask = 1 << atoi(arglist[2]); >> - >> + vt->pageflags_data[p].mask = 1 << atoi(arglist[2]); >> + if (!strncmp(nameptr, "slab", 4)) >> + vt->flags |= SLAB_PAGEFLAGS; >> p++; >> } >> } else >> @@ -9736,14 +9779,14 @@ vaddr_to_kmem_cache(ulong vaddr, char *buf, int verbose) >> readmem(page+OFFSET(page_flags), KVADDR, >> &page_flags, sizeof(ulong), "page.flags", >> FAULT_ON_ERROR); >> - if (!(page_flags & (1 << vt->PG_slab))) { >> + if (!page_slab(page, page_flags)) { >> if (((vt->flags & KMALLOC_SLUB) || VALID_MEMBER(page_compound_head)) || >> ((vt->flags & KMALLOC_COMMON) && >> VALID_MEMBER(page_slab) && VALID_MEMBER(page_first_page))) { >> readmem(compound_head(page)+OFFSET(page_flags), KVADDR, >> &page_flags, sizeof(ulong), "page.flags", >> FAULT_ON_ERROR); >> - if (!(page_flags & (1 << vt->PG_slab))) >> + if (!page_slab(compound_head(page), page_flags)) >> return NULL; >> } else >> return NULL; >> @@ -14108,6 +14151,8 @@ dump_vm_table(int verbose) >> fprintf(fp, "%sNODELISTS_IS_PTR", others++ ? "|" : "");\ >> if (vt->flags & VM_INIT) >> fprintf(fp, "%sVM_INIT", others++ ? "|" : "");\ >> + if (vt->flags & SLAB_PAGEFLAGS) >> + fprintf(fp, "%sSLAB_PAGEFLAGS", others++ ? "|" : "");\ >> >> fprintf(fp, ")\n"); >> if (vt->kernel_pgd[0] == vt->kernel_pgd[1]) >> @@ -14237,6 +14282,7 @@ dump_vm_table(int verbose) >> vt->pageflags_data[i].mask, >> vt->pageflags_data[i].name); >> } >> + fprintf(fp, " page_type_base: %x\n", vt->page_type_base); >> >> dump_vma_cache(VERBOSE); >> } >> @@ -20195,7 +20241,7 @@ char * >> is_slab_page(struct meminfo *si, char *buf) >> { >> int i, cnt; >> - ulong page_slab, page_flags, name; >> + ulong pg_slab, page_flags, name; >> ulong *cache_list; >> char *retval; >> >> @@ -20210,11 +20256,11 @@ is_slab_page(struct meminfo *si, char *buf) >> RETURN_ON_ERROR|QUIET)) >> return NULL; >> >> - if (!(page_flags & (1 << vt->PG_slab))) >> + if (!page_slab(si->spec_addr, page_flags)) >> return NULL; >> >> if (!readmem(si->spec_addr + OFFSET(page_slab), KVADDR, >> - &page_slab, sizeof(ulong), "page.slab", >> + &pg_slab, sizeof(ulong), "page.slab", >> RETURN_ON_ERROR|QUIET)) >> return NULL; >> >> @@ -20222,7 +20268,7 @@ is_slab_page(struct meminfo *si, char *buf) >> cnt = get_kmem_cache_list(&cache_list); >> >> for (i = 0; i < cnt; i++) { >> - if (page_slab == cache_list[i]) { >> + if (pg_slab == cache_list[i]) { >> if (!readmem(cache_list[i] + OFFSET(kmem_cache_name), >> KVADDR, &name, sizeof(char *), >> "kmem_cache.name", QUIET|RETURN_ON_ERROR)) >> diff --git a/symbols.c b/symbols.c >> index 69a1fbb..014cd29 100644 >> --- a/symbols.c >> +++ b/symbols.c >> @@ -10339,6 +10339,8 @@ dump_offset_table(char *spec, ulong makestruct) >> fprintf(fp, " page_compound_head: %ld\n", >> OFFSET(page_compound_head)); >> fprintf(fp, " page_private: %ld\n", OFFSET(page_private)); >> + fprintf(fp, " page_page_type: %ld\n", >> + OFFSET(page_page_type)); >> >> fprintf(fp, " trace_print_flags_mask: %ld\n", >> OFFSET(trace_print_flags_mask)); >> -- >> 2.25.1 > > -- > Crash-utility mailing list -- devel@xxxxxxxxxxxxxxxxxxxxxxxxxxx > To unsubscribe send an email to devel-leave@xxxxxxxxxxxxxxxxxxxxxxxxxxx > https://${domain_name}/admin/lists/devel.lists.crash-utility.osci.io/ > Contribution Guidelines: https://github.com/crash-utility/crash/wiki -- Crash-utility mailing list -- devel@xxxxxxxxxxxxxxxxxxxxxxxxxxx To unsubscribe send an email to devel-leave@xxxxxxxxxxxxxxxxxxxxxxxxxxx https://${domain_name}/admin/lists/devel.lists.crash-utility.osci.io/ Contribution Guidelines: https://github.com/crash-utility/crash/wiki