Fix for the "kmem -i" option on Linux 5.0 and later kernels that contain commit ca79b0c211af63fa3276f0e3fd7dd9ada2439839, titled "mm: convert totalram_pages and totalhigh_pages variables to atomic". Without the patch, the command prints some incorrect values, and besides doesn't print high/low memory information on kernels which are configured with CONFIG_HIGHMEM. crash> kmem -i PAGES TOTAL PERCENTAGE TOTAL MEM -4395174638254716088 53602483503169.4 GB ---- FREE 398314 1.5 GB 0% of TOTAL MEM USED -4395174638255114402 53602483503167.9 GB 0% of TOTAL MEM ... Tested with 5.0 and 4.20 Fedora kernels for x86_64 and x86. Signed-off-by: Kazuhito Hagio <k-hagio@xxxxxxxxxxxxx> --- memory.c | 75 +++++++++++++++++++++++++++----------------------------- 1 file changed, 36 insertions(+), 39 deletions(-) diff --git a/memory.c b/memory.c index 9c1019a..ab561b3 100644 --- a/memory.c +++ b/memory.c @@ -910,26 +910,40 @@ vm_init(void) if (IS_VMALLOC_ADDR(vt->mem_map)) vt->flags |= V_MEM_MAP; vt->total_pages = BTOP(VTOP(vt->high_memory)); - switch (get_syment_array("totalram_pages", sp_array, 2)) - { - case 1: - get_symbol_data("totalram_pages", sizeof(ulong), - &vt->totalram_pages); - break; - case 2: - if (!(readmem(sp_array[0]->value, KVADDR, - &value1, sizeof(ulong), - "totalram_pages #1", RETURN_ON_ERROR))) + + if (symbol_exists("_totalram_pages")) { + readmem(symbol_value("_totalram_pages") + + OFFSET(atomic_t_counter), KVADDR, + &vt->totalram_pages, sizeof(ulong), + "_totalram_pages", FAULT_ON_ERROR); + } else { + switch (get_syment_array("totalram_pages", sp_array, 2)) + { + case 1: + get_symbol_data("totalram_pages", sizeof(ulong), + &vt->totalram_pages); break; - if (!(readmem(sp_array[1]->value, KVADDR, - &value2, sizeof(ulong), - "totalram_pages #2", RETURN_ON_ERROR))) - break; - vt->totalram_pages = MAX(value1, value2); - break; + case 2: + if (!(readmem(sp_array[0]->value, KVADDR, + &value1, sizeof(ulong), + "totalram_pages #1", RETURN_ON_ERROR))) + break; + if (!(readmem(sp_array[1]->value, KVADDR, + &value2, sizeof(ulong), + "totalram_pages #2", RETURN_ON_ERROR))) + break; + vt->totalram_pages = MAX(value1, value2); + break; + } } - if (symbol_exists("totalhigh_pages")) { + if (symbol_exists("_totalhigh_pages")) { + readmem(symbol_value("_totalhigh_pages") + + OFFSET(atomic_t_counter), KVADDR, + &vt->totalhigh_pages, sizeof(ulong), + "_totalhigh_pages", FAULT_ON_ERROR); + vt->total_pages += vt->totalhigh_pages; + } else if (symbol_exists("totalhigh_pages")) { switch (get_syment_array("totalhigh_pages", sp_array, 2)) { case 1: @@ -8169,7 +8183,6 @@ dump_kmeminfo(void) long nr_file_pages, nr_slab; ulong swapper_space_nrpages; ulong pct; - ulong value1, value2; uint tmp; struct meminfo meminfo; struct gnu_request req; @@ -8177,7 +8190,6 @@ dump_kmeminfo(void) ulong get_totalram; ulong get_buffers; ulong get_slabs; - struct syment *sp_array[2]; char buf[BUFSIZE]; @@ -8210,7 +8222,8 @@ dump_kmeminfo(void) * Prior to 2.3.36, count all mem_map pages minus the reserved ones. * From 2.3.36 onwards, use "totalram_pages" if set. */ - if (symbol_exists("totalram_pages")) { + if (symbol_exists("totalram_pages") || + symbol_exists("_totalram_pages")) { totalram_pages = vt->totalram_pages ? vt->totalram_pages : get_totalram; } else @@ -8362,25 +8375,9 @@ dump_kmeminfo(void) fprintf(fp, "%13s %7ld %11s %3ld%% of TOTAL MEM\n", "SLAB", get_slabs, pages_to_size(get_slabs, buf), pct); - if (symbol_exists("totalhigh_pages")) { - switch (get_syment_array("totalhigh_pages", sp_array, 2)) - { - case 1: - get_symbol_data("totalhigh_pages", sizeof(ulong), - &totalhigh_pages); - break; - case 2: - if (!(readmem(sp_array[0]->value, KVADDR, - &value1, sizeof(ulong), - "totalhigh_pages #1", RETURN_ON_ERROR))) - break; - if (!(readmem(sp_array[1]->value, KVADDR, - &value2, sizeof(ulong), - "totalhigh_pages #2", RETURN_ON_ERROR))) - break; - totalhigh_pages = MAX(value1, value2); - break; - } + if (symbol_exists("totalhigh_pages") || + symbol_exists("_totalhigh_pages")) { + totalhigh_pages = vt->totalhigh_pages; pct = totalhigh_pages ? (totalhigh_pages * 100)/totalram_pages : 0; -- 2.17.0 -- Crash-utility mailing list Crash-utility@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/crash-utility