Hi, The "kmem -[sS]" commands can take several minutes to complete with the following conditions: * The system has a lot of memory sections with CONFIG_SPARSEMEM. * The kernel uses SLUB and it has a very long partial slab list. crash> kmem -s dentry | awk '{print strftime("%T"), $0}' 10:18:34 CACHE NAME OBJSIZE ALLOCATED TOTAL SLABS SSIZE 10:19:41 ffff88017fc78a00 dentry 192 9038949 10045728 239184 8k crash> kmem -S dentry | bash -c 'cat >/dev/null ; echo $SECONDS' 334 One of the causes is that is_page_ptr() in count_partial() checks if a given slub page address is a page struct by searching all memory sections linearly for the one which includes it. nr_mem_sections = NR_MEM_SECTIONS(); for (nr = 0; nr < nr_mem_sections ; nr++) { if ((sec_addr = valid_section_nr(nr))) { ... With CONFIG_SPARSEMEM{_VMEMMAP}, we can calculate the memory section which includes a page struct with its page.flags, or its address and VMEMMAP_VADDR. With this patch doing so, the computation amount can be significantly reduced in that case. crash> kmem -s dentry | awk '{print strftime("%T"), $0}' 10:34:55 CACHE NAME OBJSIZE ALLOCATED TOTAL SLABS SSIZE 10:34:55 ffff88017fc78a00 dentry 192 9038949 10045728 239184 8k crash> kmem -S dentry | bash -c 'cat >/dev/null ; echo $SECONDS' 2 This patch uses VMEMMAP_VADDR. It is not defined on PPC64, but it looks like PPC64 supports VMEMMAP flag and machdep->machspec->vmemmap_base is it, so this patch also defines it for PPC64. This might need some help from PPC folks. Signed-off-by: Kazuhito Hagio <k-hagio@xxxxxxxxxxxxx> --- defs.h | 2 ++ memory.c | 15 +++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/defs.h b/defs.h index aa17792..84e68ca 100644 --- a/defs.h +++ b/defs.h @@ -3861,6 +3861,8 @@ struct efi_memory_desc_t { #define IS_VMALLOC_ADDR(X) machdep->machspec->is_vmaddr(X) #define KERNELBASE machdep->pageoffset +#define VMEMMAP_VADDR (machdep->machspec->vmemmap_base) + #define PGDIR_SHIFT (machdep->pageshift + (machdep->pageshift -3) + (machdep->pageshift - 2)) #define PMD_SHIFT (machdep->pageshift + (machdep->pageshift - 3)) diff --git a/memory.c b/memory.c index 0df8ecc..0696763 100644 --- a/memory.c +++ b/memory.c @@ -13348,10 +13348,25 @@ is_page_ptr(ulong addr, physaddr_t *phys) ulong nr_mem_sections; ulong coded_mem_map, mem_map, end_mem_map; physaddr_t section_paddr; +#ifdef VMEMMAP_VADDR + ulong flags; +#endif if (IS_SPARSEMEM()) { nr_mem_sections = NR_MEM_SECTIONS(); +#ifdef VMEMMAP_VADDR + nr = nr_mem_sections; + if (machdep->flags & VMEMMAP) + nr = pfn_to_section_nr((addr - VMEMMAP_VADDR) / SIZE(page)); + else if (readmem(addr + OFFSET(page_flags), KVADDR, &flags, + sizeof(ulong), "page.flags", RETURN_ON_ERROR|QUIET)) + nr = (flags >> (SIZE(page_flags)*8 - SECTIONS_SHIFT()) + & ((1UL << SECTIONS_SHIFT()) - 1)); + + if (nr < nr_mem_sections) { +#else for (nr = 0; nr < nr_mem_sections ; nr++) { +#endif if ((sec_addr = valid_section_nr(nr))) { coded_mem_map = section_mem_map_addr(sec_addr); mem_map = sparse_decode_mem_map(coded_mem_map, nr); -- 1.8.3.1 -- Crash-utility mailing list Crash-utility@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/crash-utility