[Crash-utility] [RFC PATCH 1/2] crash: Show memory overcommit data in dump_kmeminfo()
Dave Anderson
anderson at redhat.com
Fri Nov 21 20:50:45 UTC 2014
----- Original Message -----
>
>
> Aaron -- FYI: this warning looks legit:
>
> $ make warn
> TARGET: X86_64
> CRASH: 7.1.0rc5
> GDB: 7.6
>
> cc -c -g -DX86_64 -DLZO -DSNAPPY -DGDB_7_6 build_data.c -Wall -O2 -Wstrict-prototypes -Wmissing-prototypes -fstack-protector -Wformat-security
> cc -c -g -DX86_64 -DLZO -DSNAPPY -DGDB_7_6 memory.c -Wall -O2 -Wstrict-prototypes -Wmissing-prototypes -fstack-protector -Wformat-security
> memory.c: In function ‘dump_kmeminfo’:
> memory.c:7952:11: warning: ‘allowed’ may be used uninitialized in this function [-Wmaybe-uninitialized]
> cc -c -g -DX86_64 -DLZO -DSNAPPY -DGDB_7_6 help.c -Wall -O2 -Wstrict-prototypes -Wmissing-prototypes -fstack-protector -Wformat-security
> ...
Sure enough, in a 2.6.30 kernel, which has no "sysctl_overcommit_kbytes", I get
a SIGFPE on this line:
pct = committed ? ((committed * 100)
/ allowed) : 0;
because sysctl_overcommit_kbytes doesn't exist. I don't know what
the initial setting should be, because certainly 0 won't work.
Dave
>
> 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 at redhat.com>
> > Suggested-by: Alexis Solanas <alexis at redhat.com>
> > ---
> > 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 at redhat.com
> > https://www.redhat.com/mailman/listinfo/crash-utility
> >
>
> --
> Crash-utility mailing list
> Crash-utility at redhat.com
> https://www.redhat.com/mailman/listinfo/crash-utility
More information about the Crash-utility
mailing list