Hi,

At $JOB, we have machines with 400GB RAM that even the smallest
15GB amd64 minidump takes well over an hour. The major cause of
the slowness is that in minidumpsys(), blk_write() is called
PAGE_SIZE at a time. This causes blk_write() to poll the console
for the Ctrl-C abort once per page.

The attached patch changes blk_write() to be called with a run of
physically contiguous pages. This reduced the dump time by over a
magnitude. Of course, blk_write() could also be changed to poll
the console less frequently (like only on every IO).

If anybody else dumps on machines with lots of RAM, it would be
nice to know the difference this patch makes. I've got a second
set of patches that further reduces the dump time by over half that
I'll try to clean up soon.

http://people.freebsd.org/~bryanv/patches/minidump.patch
commit 25f9e82e4ac93e71c6cf06fe2faa1899967db725
Author: Bryan Venteicher <bryanventeic...@gmail.com>
Date:   Sun Sep 29 13:56:42 2013 -0500

    Call blk_write() with a run of physically contiguous pages
    
    Previously, blk_write() was being called one page at a time, which
    would cause it to poll the console for every page. This change makes
    dumping a magnitude faster, and is especially useful on large memory
    machines.

diff --git a/sys/amd64/amd64/minidump_machdep.c b/sys/amd64/amd64/minidump_machdep.c
index f14c539..26b2b31 100644
--- a/sys/amd64/amd64/minidump_machdep.c
+++ b/sys/amd64/amd64/minidump_machdep.c
@@ -221,7 +221,8 @@ minidumpsys(struct dumperinfo *di)
 	vm_offset_t va;
 	int error;
 	uint64_t bits;
-	uint64_t *pml4, *pdp, *pd, *pt, pa;
+	uint64_t *pml4, *pdp, *pd, *pt, start_pa, pa;
+	size_t sz;
 	int i, ii, j, k, n, bit;
 	int retry_count;
 	struct minidumphdr mdhdr;
@@ -412,18 +413,29 @@ minidumpsys(struct dumperinfo *di)
 	}
 
 	/* Dump memory chunks */
-	/* XXX cluster it up and use blk_dump() */
-	for (i = 0; i < vm_page_dump_size / sizeof(*vm_page_dump); i++) {
+	for (i = 0, start_pa = 0, sz = 0;
+	     i < vm_page_dump_size / sizeof(*vm_page_dump); i++) {
 		bits = vm_page_dump[i];
 		while (bits) {
 			bit = bsfq(bits);
 			pa = (((uint64_t)i * sizeof(*vm_page_dump) * NBBY) + bit) * PAGE_SIZE;
-			error = blk_write(di, 0, pa, PAGE_SIZE);
-			if (error)
-				goto fail;
+			if (sz == 0 || start_pa + sz == pa) {
+				if (sz == 0)
+					start_pa = pa;
+				sz += PAGE_SIZE;
+			} else {
+				error = blk_write(di, 0, start_pa, sz);
+				if (error)
+					goto fail;
+				start_pa = pa;
+				sz = PAGE_SIZE;
+			}
 			bits &= ~(1ul << bit);
 		}
 	}
+	error = blk_write(di, 0, start_pa, sz);
+	if (error)
+		goto fail;
 
 	error = blk_flush(di);
 	if (error)
_______________________________________________
freebsd-current@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-unsubscr...@freebsd.org"

Reply via email to