[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