[Crash-utility] [PATCH v2] "kmem -i" extremely slow on dumps from large memory systems

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The "kmem -i" command is extremely slow (appears to hang) on dumps from large memory systems.

For example, on 120GB crash dump from a high-end server with 32TB of RAM (ie. 8Giga Pages),
the "kmem -i" command is taking over 50 minutes to execute on a DL380 Gen10. To report basic
general memory usage figures, we should only be reading global counters, without having to walk
the full flat/sparse mem map page table. Hence, dump_kmeminfo() should first be reading globals,
and then only call dump_mem_map() if important information (ie. slabs or total ram) is missing.

Signed-off-by: Georges Aureau <georges.aureau@xxxxxxx>
--
diff --git a/memory.c b/memory.c
index 8c01ed0..eb4574c 100644
--- a/memory.c
+++ b/memory.c
@@ -8546,18 +8546,23 @@ dump_kmeminfo(void)
         ulong get_buffers;
         ulong get_slabs;
 	char buf[BUFSIZE];
+	ulong flags;
 
-
-	BZERO(&meminfo, sizeof(struct meminfo));
-	meminfo.flags = GET_ALL;
-	dump_mem_map(&meminfo);
-	get_totalram = meminfo.get_totalram;
-	shared_pages = meminfo.get_shared;
-	get_buffers = meminfo.get_buffers;
-	get_slabs = meminfo.get_slabs;
+	/*
+	 * By default, we will no longer call dump_mem_map() as this is too
+	 * slow for large memory systems. If we have to call it (eg. missing
+	 * important information such as slabs or total ram), we will also
+	 * collect shared pages. Otherwise, we won't print shared pages.
+	 * Shared page
+	 */
+	flags = GET_SHARED_PAGES;
+	shared_pages = 0;
+	get_totalram = 0;
+	get_buffers = 0;
+	get_slabs = 0;
 
 	/*
-	 *  If vm_stat array exists, override page search info.
+	 *  If vm_stat array does not exists, then set mem map flag.
 	 */
 	if (vm_stat_init()) {
 		if (dump_vm_stat("NR_SLAB", &nr_slab, 0))
@@ -8572,9 +8577,10 @@ dump_kmeminfo(void)
 			if (dump_vm_stat("NR_SLAB_UNRECLAIMABLE_B", &nr_slab, 0))
 				get_slabs += nr_slab;
 		}
+	} else {
+		flags |= GET_SLAB_PAGES;
 	}
 
-	fprintf(fp, "%s", kmeminfo_hdr);
 	/*
 	 *  Get total RAM based upon how the various versions of si_meminfo()
          *  have done it, latest to earliest:
@@ -8586,9 +8592,32 @@ dump_kmeminfo(void)
 	    symbol_exists("_totalram_pages")) {
 		totalram_pages = vt->totalram_pages ? 
 			vt->totalram_pages : get_totalram; 
-	} else 
-		totalram_pages = get_totalram;
+	} else {
+		flags |= GET_TOTALRAM_PAGES;
+	}
 
+	/*
+	 * If we want more than just shared pages (missing slabs or total ram)
+	 * then call dump_mem_map() and also collect buffers.
+	 */
+	if (flags != GET_SHARED_PAGES) {
+		BZERO(&meminfo, sizeof(struct meminfo));
+		flags |= GET_BUFFERS_PAGES;
+		meminfo.flags = flags;
+		dump_mem_map(&meminfo);
+		/* Update the missing information */
+		if (flags & GET_SLAB_PAGES) {
+			get_slabs = meminfo.get_slabs;
+		}
+		if (flags & GET_TOTALRAM_PAGES) {
+			get_totalram = meminfo.get_totalram;
+			totalram_pages = get_totalram;
+		}
+		shared_pages = meminfo.get_shared;
+		get_buffers = meminfo.get_buffers;
+	}
+
+	fprintf(fp, "%s", kmeminfo_hdr);
 	fprintf(fp, "%13s  %7ld  %11s         ----\n", "TOTAL MEM", 
 		totalram_pages, pages_to_size(totalram_pages, buf));
 
@@ -8613,9 +8642,11 @@ dump_kmeminfo(void)
          *  differently than the kernel -- it just tallies the non-reserved
          *  pages that have a count of greater than 1.
 	 */
-        pct = (shared_pages * 100)/totalram_pages;
-        fprintf(fp, "%13s  %7ld  %11s  %3ld%% of TOTAL MEM\n", 
-		"SHARED", shared_pages, pages_to_size(shared_pages, buf), pct);
+	if (shared_pages) {
+		pct = (shared_pages * 100)/totalram_pages;
+		fprintf(fp, "%13s  %7ld  %11s  %3ld%% of TOTAL MEM\n", 
+			"SHARED", shared_pages, pages_to_size(shared_pages, buf), pct);
+	}
 
 	subtract_buffer_pages = 0;
 	if (symbol_exists("buffermem_pages")) { 
@@ -8634,7 +8665,7 @@ dump_kmeminfo(void)
         fprintf(fp, "%13s  %7ld  %11s  %3ld%% of TOTAL MEM\n", 
 		"BUFFERS", buffer_pages, pages_to_size(buffer_pages, buf), pct);
 
-	if (CRASHDEBUG(1)) 
+	if (CRASHDEBUG(1)&&(flags&GET_BUFFERS_PAGES)) 
         	error(NOTE, "pages with buffers: %ld\n", get_buffers);
 
 	/*
--
Crash-utility mailing list -- devel@xxxxxxxxxxxxxxxxxxxxxxxxxxx
To unsubscribe send an email to devel-leave@xxxxxxxxxxxxxxxxxxxxxxxxxxx
https://${domain_name}/admin/lists/devel.lists.crash-utility.osci.io/
Contribution Guidelines: https://github.com/crash-utility/crash/wiki




[Index of Archives]     [Fedora Development]     [Fedora Desktop]     [Fedora SELinux]     [Yosemite News]     [KDE Users]     [Fedora Tools]

 

Powered by Linux