[Crash-utility] [PATCH] diskdump: use mmap/madvise to improve the start-up

Huang Shijie shijie at os.amperecomputing.com
Wed Mar 30 10:11:24 UTC 2022


1.) The bitmap of vmcore file can be very big in the server kernel panic,
    such as over 256M.

    This patch uses mmap/madvise to improve the read speed
    of the bitmap in the non-FLAT_FORMAT code path.

    Use MADV_SEQUENTIAL for madvise, it will trigger aggressively
    readahead for reading the bitmap.

2.) Test.

    The files:
    vmlinux: 272M
    vmcore : 23G (bitmap is 281018368 bytes)

 #cat ./commands.txt
      quit

 Before this patch:
    #echo  3 > /proc/sys/vm/drop_caches;
    #time ./crash -i ./commands.txt /root/t/vmlinux /root/t/vmcore > /dev/null 2>&1
     ............................
	real    0m55.217s
	user    0m15.114s
	sys     0m3.560s
     ............................

 After this patch:
    #echo  3 > /proc/sys/vm/drop_caches;
    #time ./crash -i ./commands.txt /root/t/vmlinux /root/t/vmcore > /dev/null 2>&1
     ............................
	real    0m46.781s
	user    0m19.693s
	sys     0m1.642s
     ............................

Signed-off-by: Huang Shijie <shijie at os.amperecomputing.com>
---
This patch is based on patch:
   diskdump: Optimize the boot time

---
 diskdump.c | 39 ++++++++++++++++-----------------------
 1 file changed, 16 insertions(+), 23 deletions(-)

diff --git a/diskdump.c b/diskdump.c
index d30db9d..c60b283 100644
--- a/diskdump.c
+++ b/diskdump.c
@@ -724,10 +724,6 @@ restart:
 
 	offset = (off_t)block_size * (1 + header->sub_hdr_size);
 
-	if ((dd->bitmap = malloc(bitmap_len)) == NULL)
-		error(FATAL, "%s: cannot malloc bitmap buffer\n",
-			DISKDUMP_VALID() ? "diskdump" : "compressed kdump");
-
 	dd->dumpable_bitmap = calloc(bitmap_len, 1);
 
 	if (CRASHDEBUG(8))
@@ -736,30 +732,23 @@ restart:
 			(ulonglong)offset);
 
 	if (FLAT_FORMAT()) {
+		if ((dd->bitmap = malloc(bitmap_len)) == NULL)
+			error(FATAL, "%s: cannot malloc bitmap buffer\n",
+				DISKDUMP_VALID() ? "diskdump" : "compressed kdump");
+
 		if (!read_flattened_format(dd->dfd, offset, dd->bitmap, bitmap_len)) {
 			error(INFO, "%s: cannot read memory bitmap\n",
 				DISKDUMP_VALID() ? "diskdump" : "compressed kdump");
 			goto err;
 		}
 	} else {
-		if (lseek(dd->dfd, offset, SEEK_SET) == failed) {
-			error(INFO, "%s: cannot lseek memory bitmap\n",
+		dd->bitmap = mmap(NULL, bitmap_len, PROT_READ,
+					MAP_SHARED, dd->dfd, offset);
+		if (dd->bitmap == MAP_FAILED)
+			error(FATAL, "%s: cannot mmap bitmap buffer\n",
 				DISKDUMP_VALID() ? "diskdump" : "compressed kdump");
-			goto err;
-		}
-		bufptr = dd->bitmap;
-		len = bitmap_len;
-		while (len) {
-			bytes_read = read(dd->dfd, bufptr, len);
-			if (bytes_read <= 0) {
-				error(INFO, "%s: cannot read memory bitmap\n",
-					DISKDUMP_VALID() ? "diskdump"
-					: "compressed kdump");
-				goto err;
-			}
-			len -= bytes_read;
-			bufptr += bytes_read;
-		}
+
+		madvise(dd->bitmap, bitmap_len, MADV_SEQUENTIAL);
 	}
 
 	if (dump_is_partial(header))
@@ -920,8 +909,12 @@ err:
 		free(sub_header);
 	if (sub_header_kdump)
 		free(sub_header_kdump);
-	if (dd->bitmap)
-		free(dd->bitmap);
+	if (dd->bitmap) {
+		if (FLAT_FORMAT())
+			free(dd->bitmap);
+		else
+			munmap(dd->bitmap, dd->bitmap_len);
+	}
 	if (dd->dumpable_bitmap)
 		free(dd->dumpable_bitmap);
 	if (dd->notes_buf)
-- 
2.30.2



More information about the Crash-utility mailing list