From d586679b861fafc99e96c863105826d30de630a7 Mon Sep 17 00:00:00 2001 From: Dave Anderson Date: Fri, 2 Mar 2018 14:53:16 -0500 Subject: [PATCH] As the first step in optimizing the is_page_ptr() function, save the maximum SPARSEMEM section number during initialization, and use it as the topmost delimeter in subsequent mem_section searches. Also allow for per-architecture machdep->is_page_ptr() plugin functions. (anderson@redhat.com) --- defs.h | 3 +++ main.c | 5 +++-- memory.c | 35 +++++++++++++++++++++++++++-------- 3 files changed, 33 insertions(+), 10 deletions(-) diff --git a/defs.h b/defs.h index c5b8c6d0..9663bd89 100644 --- a/defs.h +++ b/defs.h @@ -1030,6 +1030,7 @@ struct machdep_table { int (*verify_line_number)(ulong, ulong, ulong); void (*get_irq_affinity)(int); void (*show_interrupts)(int, ulong *); + int (*is_page_ptr)(ulong, physaddr_t *); }; /* @@ -2369,6 +2370,7 @@ struct vm_table { /* kernel VM-related data */ ulong mask; char *name; } *pageflags_data; + ulong max_mem_section_nr; }; #define NODES (0x1) @@ -5100,6 +5102,7 @@ ulong vm_area_dump(ulong, ulong, ulong, struct reference *); char *fill_vma_cache(ulong); void clear_vma_cache(void); void dump_vma_cache(ulong); +int generic_is_page_ptr(ulong, physaddr_t *); int is_page_ptr(ulong, physaddr_t *); void dump_vm_table(int); int read_string(ulong, char *, int); diff --git a/main.c b/main.c index 2b5b06bd..2aae0c6f 100644 --- a/main.c +++ b/main.c @@ -1,8 +1,8 @@ /* main.c - core analysis suite * * Copyright (C) 1999, 2000, 2001, 2002 Mission Critical Linux, Inc. - * Copyright (C) 2002-2017 David Anderson - * Copyright (C) 2002-2017 Red Hat, Inc. All rights reserved. + * Copyright (C) 2002-2018 David Anderson + * Copyright (C) 2002-2018 Red Hat, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -1109,6 +1109,7 @@ setup_environment(int argc, char **argv) machdep->bits = sizeof(long) * 8; machdep->verify_paddr = generic_verify_paddr; machdep->get_kvaddr_ranges = generic_get_kvaddr_ranges; + machdep->is_page_ptr = generic_is_page_ptr; pc->redhat_debug_loc = DEFAULT_REDHAT_DEBUG_LOCATION; pc->cmdgencur = 0; pc->cmd_table = linux_command_table; diff --git a/memory.c b/memory.c index 0df8ecc0..06692766 100644 --- a/memory.c +++ b/memory.c @@ -1,8 +1,8 @@ /* memory.c - core analysis suite * * Copyright (C) 1999, 2000, 2001, 2002 Mission Critical Linux, Inc. - * Copyright (C) 2002-2017 David Anderson - * Copyright (C) 2002-2017 Red Hat, Inc. All rights reserved. + * Copyright (C) 2002-2018 David Anderson + * Copyright (C) 2002-2018 Red Hat, Inc. All rights reserved. * Copyright (C) 2002 Silicon Graphics, Inc. * * This program is free software; you can redistribute it and/or modify @@ -255,7 +255,7 @@ static void PG_reserved_flag_init(void); static void PG_slab_flag_init(void); static ulong nr_blockdev_pages(void); void sparse_mem_init(void); -void dump_mem_sections(void); +void dump_mem_sections(int); void list_mem_sections(void); ulong sparse_decode_mem_map(ulong, ulong); char *read_mem_section(ulong); @@ -13333,6 +13333,12 @@ kmem_search(struct meminfo *mi) mi->spec_addr, memtype_string(mi->memtype, 0)); } +int +generic_is_page_ptr(ulong addr, physaddr_t *phys) +{ + return FALSE; +} + /* * Determine whether an address is a page pointer from the mem_map[] array. * If the caller requests it, return the associated physical address. @@ -13349,8 +13355,11 @@ is_page_ptr(ulong addr, physaddr_t *phys) ulong coded_mem_map, mem_map, end_mem_map; physaddr_t section_paddr; + if (machdep->is_page_ptr(addr, phys)) + return TRUE; + if (IS_SPARSEMEM()) { - nr_mem_sections = NR_MEM_SECTIONS(); + nr_mem_sections = vt->max_mem_section_nr+1; for (nr = 0; nr < nr_mem_sections ; nr++) { if ((sec_addr = valid_section_nr(nr))) { coded_mem_map = section_mem_map_addr(sec_addr); @@ -13668,6 +13677,7 @@ dump_vm_table(int verbose) fprintf(fp, " swap_info_struct: %lx\n", (ulong)vt->swap_info_struct); fprintf(fp, " mem_sec: %lx\n", (ulong)vt->mem_sec); fprintf(fp, " mem_section: %lx\n", (ulong)vt->mem_section); + fprintf(fp, " max_mem_section_nr: %ld\n", (ulong)vt->max_mem_section_nr); fprintf(fp, " ZONE_HIGHMEM: %d\n", vt->ZONE_HIGHMEM); fprintf(fp, "node_online_map_len: %d\n", vt->node_online_map_len); if (vt->node_online_map_len) { @@ -16295,8 +16305,8 @@ dump_memory_nodes(int initialize) vt->numnodes = n; } - if (!initialize && IS_SPARSEMEM()) - dump_mem_sections(); + if (IS_SPARSEMEM()) + dump_mem_sections(initialize); } /* @@ -17128,9 +17138,9 @@ pfn_to_map(ulong pfn) } void -dump_mem_sections(void) +dump_mem_sections(int initialize) { - ulong nr,addr; + ulong nr, max, addr; ulong nr_mem_sections; ulong coded_mem_map, mem_map, pfn; char buf1[BUFSIZE]; @@ -17140,6 +17150,15 @@ dump_mem_sections(void) nr_mem_sections = NR_MEM_SECTIONS(); + if (initialize) { + for (nr = max = 0; nr < nr_mem_sections ; nr++) { + if (valid_section_nr(nr)) + max = nr; + } + vt->max_mem_section_nr = max; + return; + } + fprintf(fp, "\n"); pad_line(fp, BITS32() ? 59 : 67, '-'); fprintf(fp, "\n\nNR %s %s %s PFN\n",