Aaron, I like the addition. But I've got a few nits regarding the patch. Given that "kmem -i" is so commonly-used, I prefer not to introduce something that could conceivably generate a command-killing "invalid structure member offset" error. And that could happen in your hugetlb_total_pages() function because of the hstate structure dependencies. (See dump_hstates() for example) Also, in dump_kmeminfo() you use MEMBER_OFFSET(), which should be avoided because it will quietly return -1 if the structure member doesn't exist, leading to bogus output. That's the whole purpose behind using OFFSET(), or at least storing/validating the MEMBER_OFFSET() return value before blindly using it. It may seem pedantic, but if history has shown us anything, it's that kernel developers cannot stop themselves from changing structure/member names. So if you could just adjust those kinds of issues, this patch would be a nice addition. Thanks, Dave ----- Original Message ----- > This patch changes dump_kmeminfo() to report overcommit information similar > to that displayed under the proc/meminfo file. It may be useful to indicate > memory over commitment abuse, for example with forced vmcores from system > hangs due to shortage of memory. The intended output is as follows: > > crash> kmem -i > PAGES TOTAL PERCENTAGE > TOTAL MEM 1965332 7.5 GB ---- > FREE 78080 305 MB 3% of TOTAL MEM > USED 1887252 7.2 GB 96% of TOTAL MEM > SHARED 789954 3 GB 40% of TOTAL MEM > BUFFERS 110606 432.1 MB 5% of TOTAL MEM > CACHED 1212645 4.6 GB 61% of TOTAL MEM > SLAB 146563 572.5 MB 7% of TOTAL MEM > > TOTAL SWAP 1970175 7.5 GB ---- > SWAP USED 5 20 KB 0% of TOTAL SWAP > SWAP FREE 1970170 7.5 GB 99% of TOTAL SWAP > > COMMIT LIMIT 2952841 11.3 GB ---- > COMMITTED 1150595 4.4 GB 38% of TOTAL LIMIT > > Tested under 3.16.4-200.fc20.x86_64 only. > Though this should work under RHEL5 (2.6.18) and above. > > Signed-off-by: Aaron Tomlin <atomlin@xxxxxxxxxx> > Suggested-by: Alexis Solanas <alexis@xxxxxxxxxx> > --- > help.c | 33 ++++++++-------- > memory.c | 132 > +++++++++++++++++++++++++++++++++++++++++++++++++++++++-------- > 2 files changed, 134 insertions(+), 31 deletions(-) > > diff --git a/help.c b/help.c > index 6aa3e20..bedd7c3 100644 > --- a/help.c > +++ b/help.c > @@ -5587,23 +5587,26 @@ char *help_kmem[] = { > "\nEXAMPLES", > " Display memory usage information:\n", > " %s> kmem -i", > -" PAGES TOTAL PERCENTAGE", > -" TOTAL MEM 63602 248.4 MB ----", > -" FREE 993 3.9 MB 1% of TOTAL MEM", > -" USED 62609 244.6 MB 98% of TOTAL MEM", > -" SHARED 34035 132.9 MB 53% of TOTAL MEM", > -" BUFFERS 10928 42.7 MB 17% of TOTAL MEM", > -" CACHED 35249 137.7 MB 55% of TOTAL MEM", > -" SLAB 2823 11 MB 4% of TOTAL MEM", > +" PAGES TOTAL PERCENTAGE", > +" TOTAL MEM 63602 248.4 MB ----", > +" FREE 993 3.9 MB 1% of TOTAL MEM", > +" USED 62609 244.6 MB 98% of TOTAL MEM", > +" SHARED 34035 132.9 MB 53% of TOTAL MEM", > +" BUFFERS 10928 42.7 MB 17% of TOTAL MEM", > +" CACHED 35249 137.7 MB 55% of TOTAL MEM", > +" SLAB 2823 11 MB 4% of TOTAL MEM", > " ", > -" TOTAL HIGH 0 0 0% of TOTAL MEM", > -" FREE HIGH 0 0 0% of TOTAL HIGH", > -" TOTAL LOW 63602 248.4 MB 100% of TOTAL MEM", > -" FREE LOW 993 3.9 MB 1% of TOTAL LOW", > +" TOTAL HIGH 0 0 0% of TOTAL MEM", > +" FREE HIGH 0 0 0% of TOTAL HIGH", > +" TOTAL LOW 63602 248.4 MB 100% of TOTAL MEM", > +" FREE LOW 993 3.9 MB 1% of TOTAL LOW", > " ", > -" TOTAL SWAP 129792 507 MB ----", > -" SWAP USED 14727 57.5 MB 11% of TOTAL SWAP", > -" SWAP FREE 115065 449.5 MB 88% of TOTAL SWAP", > +" TOTAL SWAP 129792 507 MB ----", > +" SWAP USED 14727 57.5 MB 11% of TOTAL SWAP", > +" SWAP FREE 115065 449.5 MB 88% of TOTAL SWAP", > +" ", > +" COMMIT LIMIT 2952841 11.3 GB ----", > +" COMMITTED 1158600 4.4 GB 39% of TOTAL LIMIT", > " ", > " ZONE NAME FREE ACTIVE INACTIVE_DIRTY INACTIVE_CLEAN > MIN/LOW/HIGH", > " 0 DMA 240 1166 7 161 > 128/256/384 ", > diff --git a/memory.c b/memory.c > index 3ac928d..823ec75 100644 > --- a/memory.c > +++ b/memory.c > @@ -227,6 +227,7 @@ static int vm_area_page_dump(ulong, ulong, ulong, ulong, > ulong, > struct reference *); > static void rss_page_types_init(void); > static int dump_swap_info(ulong, ulong *, ulong *); > +static ulong hugetlb_total_pages(void); > static void swap_info_init(void); > static char *get_swapdev(ulong, char *); > static void fill_swap_info(ulong); > @@ -4627,7 +4628,7 @@ cmd_kmem(void) > > } > > - if (iflag == 1) > + if (iflag) > dump_kmeminfo(); > > if (pflag == 1) > @@ -7653,7 +7654,7 @@ bailout: > * by /proc/meminfo, and then some... > */ > > -char *kmeminfo_hdr = " PAGES TOTAL PERCENTAGE\n"; > +char *kmeminfo_hdr = " PAGES TOTAL > PERCENTAGE\n"; > > static void > dump_kmeminfo(void) > @@ -7670,6 +7671,10 @@ dump_kmeminfo(void) > ulong freehighmem_pages; > ulong totallowmem_pages; > ulong freelowmem_pages; > + ulong allowed; > + long committed; > + ulong overcommit_kbytes; > + int overcommit_ratio; > long nr_file_pages, nr_slab; > ulong swapper_space_nrpages; > ulong pct; > @@ -7720,7 +7725,7 @@ dump_kmeminfo(void) > } else > totalram_pages = get_totalram; > > - fprintf(fp, "%10s %7ld %11s ----\n", "TOTAL MEM", > + fprintf(fp, "%13s %7ld %11s ----\n", "TOTAL MEM", > totalram_pages, pages_to_size(totalram_pages, buf)); > > /* > @@ -7731,12 +7736,12 @@ dump_kmeminfo(void) > vt->dump_free_pages(&meminfo); > freeram_pages = meminfo.retval; > pct = (freeram_pages * 100)/totalram_pages; > - fprintf(fp, "%10s %7ld %11s %3ld%% of TOTAL MEM\n", > + fprintf(fp, "%13s %7ld %11s %3ld%% of TOTAL MEM\n", > "FREE", freeram_pages, pages_to_size(freeram_pages, buf), pct); > > used_pages = totalram_pages - freeram_pages; > pct = (used_pages * 100)/totalram_pages; > - fprintf(fp, "%10s %7ld %11s %3ld%% of TOTAL MEM\n", > + fprintf(fp, "%13s %7ld %11s %3ld%% of TOTAL MEM\n", > "USED", used_pages, pages_to_size(used_pages, buf), pct); > > /* > @@ -7745,7 +7750,7 @@ dump_kmeminfo(void) > * pages that have a count of greater than 1. > */ > pct = (shared_pages * 100)/totalram_pages; > - fprintf(fp, "%10s %7ld %11s %3ld%% of TOTAL MEM\n", > + fprintf(fp, "%13s %7ld %11s %3ld%% of TOTAL MEM\n", > "SHARED", shared_pages, pages_to_size(shared_pages, buf), pct); > > subtract_buffer_pages = 0; > @@ -7762,7 +7767,7 @@ dump_kmeminfo(void) > buffer_pages = 0; > > pct = (buffer_pages * 100)/totalram_pages; > - fprintf(fp, "%10s %7ld %11s %3ld%% of TOTAL MEM\n", > + fprintf(fp, "%13s %7ld %11s %3ld%% of TOTAL MEM\n", > "BUFFERS", buffer_pages, pages_to_size(buffer_pages, buf), pct); > > if (CRASHDEBUG(1)) > @@ -7816,7 +7821,7 @@ dump_kmeminfo(void) > > > pct = (page_cache_size * 100)/totalram_pages; > - fprintf(fp, "%10s %7ld %11s %3ld%% of TOTAL MEM\n", > + fprintf(fp, "%13s %7ld %11s %3ld%% of TOTAL MEM\n", > "CACHED", page_cache_size, > pages_to_size(page_cache_size, buf), pct); > > @@ -7826,7 +7831,7 @@ dump_kmeminfo(void) > */ > > pct = (get_slabs * 100)/totalram_pages; > - fprintf(fp, "%10s %7ld %11s %3ld%% of TOTAL MEM\n", > + 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")) { > @@ -7851,7 +7856,7 @@ dump_kmeminfo(void) > > pct = totalhigh_pages ? > (totalhigh_pages * 100)/totalram_pages : 0; > - fprintf(fp, "\n%10s %7ld %11s %3ld%% of TOTAL MEM\n", > + fprintf(fp, "\n%13s %7ld %11s %3ld%% of TOTAL MEM\n", > "TOTAL HIGH", totalhigh_pages, > pages_to_size(totalhigh_pages, buf), pct); > > @@ -7860,19 +7865,19 @@ dump_kmeminfo(void) > freehighmem_pages = meminfo.retval; > pct = freehighmem_pages ? > (freehighmem_pages * 100)/totalhigh_pages : 0; > - fprintf(fp, "%10s %7ld %11s %3ld%% of TOTAL HIGH\n", > + fprintf(fp, "%13s %7ld %11s %3ld%% of TOTAL HIGH\n", > "FREE HIGH", freehighmem_pages, > pages_to_size(freehighmem_pages, buf), pct); > > totallowmem_pages = totalram_pages - totalhigh_pages; > pct = (totallowmem_pages * 100)/totalram_pages; > - fprintf(fp, "%10s %7ld %11s %3ld%% of TOTAL MEM\n", > + fprintf(fp, "%13s %7ld %11s %3ld%% of TOTAL MEM\n", > "TOTAL LOW", totallowmem_pages, > pages_to_size(totallowmem_pages, buf), pct); > > freelowmem_pages = freeram_pages - freehighmem_pages; > pct = (freelowmem_pages * 100)/totallowmem_pages; > - fprintf(fp, "%10s %7ld %11s %3ld%% of TOTAL LOW\n", > + fprintf(fp, "%13s %7ld %11s %3ld%% of TOTAL LOW\n", > "FREE LOW", freelowmem_pages, > pages_to_size(freelowmem_pages, buf), pct); > } > @@ -7884,18 +7889,18 @@ dump_kmeminfo(void) > if (symbol_exists("swapper_space") || symbol_exists("swapper_spaces")) { > if (dump_swap_info(RETURN_ON_ERROR, &totalswap_pages, > &totalused_pages)) { > - fprintf(fp, "%10s %7ld %11s ----\n", > + fprintf(fp, "%13s %7ld %11s ----\n", > "TOTAL SWAP", totalswap_pages, > pages_to_size(totalswap_pages, buf)); > pct = totalswap_pages ? (totalused_pages * 100) / > totalswap_pages : 100; > - fprintf(fp, "%10s %7ld %11s %3ld%% of TOTAL SWAP\n", > + fprintf(fp, "%13s %7ld %11s %3ld%% of TOTAL SWAP\n", > "SWAP USED", totalused_pages, > pages_to_size(totalused_pages, buf), pct); > pct = totalswap_pages ? > ((totalswap_pages - totalused_pages) * > 100) / totalswap_pages : 0; > - fprintf(fp, "%10s %7ld %11s %3ld%% of TOTAL SWAP\n", > + fprintf(fp, "%13s %7ld %11s %3ld%% of TOTAL SWAP\n", > "SWAP FREE", > totalswap_pages - totalused_pages, > pages_to_size(totalswap_pages - totalused_pages, > @@ -7905,6 +7910,56 @@ dump_kmeminfo(void) > "swap_info[%ld].swap_map at %lx is inaccessible\n", > totalused_pages, totalswap_pages); > } > + /* > + * Show committed memory > + */ > + if (kernel_symbol_exists("sysctl_overcommit_memory")) { > + fprintf(fp, "\n"); > + if (kernel_symbol_exists("sysctl_overcommit_kbytes")) { > + get_symbol_data("sysctl_overcommit_kbytes", > + sizeof(ulong), &overcommit_kbytes); > + if (overcommit_kbytes) > + allowed = overcommit_kbytes >> > + (machdep->pageshift - 10); > + else { > + get_symbol_data("sysctl_overcommit_ratio", > + sizeof(int), > + &overcommit_ratio); > + allowed = ((totalram_pages - hugetlb_total_pages()) > + * overcommit_ratio / 100); > + } > + } > + if (symbol_exists("vm_committed_as")) { > + readmem(symbol_value("vm_committed_as") + > + MEMBER_OFFSET("percpu_counter", > + "count"), KVADDR, > + &committed, > + sizeof(long), > + "percpu_counter count", > + FAULT_ON_ERROR); > + > + /* Ensure always positive */ > + if (committed < 0) > + committed = 0; > + } else { > + readmem(symbol_value("vm_committed_space") + > + MEMBER_OFFSET("atomic_t", > + "counter"), KVADDR, > + &committed, sizeof(int), > + "atomic_t counter", > + FAULT_ON_ERROR); > + } > + allowed += totalswap_pages; > + fprintf(fp, "%13s %7ld %11s ----\n", > + "COMMIT LIMIT", allowed, > + pages_to_size(allowed, buf)); > + > + pct = committed ? ((committed * 100) > + / allowed) : 0; > + fprintf(fp, "%13s %7ld %11s %3ld%% of TOTAL LIMIT\n", > + "COMMITTED", committed, > + pages_to_size(committed, buf), pct); > + } > dump_zone_page_usage(); > } > > @@ -14734,6 +14789,51 @@ next_physpage(ulonglong paddr, ulonglong *nextpaddr) > return FALSE; > } > > +ulong > +hugetlb_total_pages(void) > +{ > + ulong hstate_p; > + int i, len; > + ulong nr_total_pages = 0; > + ulong nr_huge_pages; > + uint horder; > + > + if (kernel_symbol_exists("hstates")) { > + STRUCT_SIZE_INIT(hstate, "hstate"); > + MEMBER_OFFSET_INIT(hstate_order, "hstate", "order"); > + MEMBER_OFFSET_INIT(hstate_nr_huge_pages, "hstate", "nr_huge_pages"); > + > + len = get_array_length("hstates", NULL, 0); > + hstate_p = symbol_value("hstates"); > + > + for (i = 0; i < len; i++) { > + hstate_p = hstate_p + (SIZE(hstate) * i); > + > + readmem(hstate_p + OFFSET(hstate_order), KVADDR, > + &horder, sizeof(uint), > + "hstate_order", > + FAULT_ON_ERROR); > + > + readmem(hstate_p + OFFSET(hstate_nr_huge_pages), KVADDR, > + &nr_huge_pages, sizeof(ulong), > + "hstate_nr_huge_pages", > + FAULT_ON_ERROR); > + > + nr_total_pages += nr_huge_pages * (1 << horder); > + } > + } else if (kernel_symbol_exists("nr_huge_pages")) { > + unsigned long hpage_shift = 21; > + > + if ((machine_type("X86") && !(machdep->flags & PAE))) > + hpage_shift = 22; > + get_symbol_data("nr_huge_pages", > + sizeof(ulong), &nr_huge_pages); > + nr_total_pages = nr_huge_pages * ((1 << hpage_shift) / > + machdep->pagesize); > + } > + return nr_total_pages; > +} > + > /* > * Display swap statistics. > */ > -- > 1.9.3 > > -- > Crash-utility mailing list > Crash-utility@xxxxxxxxxx > https://www.redhat.com/mailman/listinfo/crash-utility > -- Crash-utility mailing list Crash-utility@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/crash-utility