[PATCH] diskdump: use mmap/madvise to improve the start-up
by Huang Shijie
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(a)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
2 years, 7 months
invalid structure member offset: page_active #115
by sholck
Hello:
A patch named 0001-Fix-for-kmem-s-S-on-Linux-5.17.0.patch to fix "invalid structure member offset: page_active #115",
you can get from attachment.
================================================================
>From c8bd4ad430abdfe2dc86149694f424ea24f2b7ec Mon Sep 17 00:00:00 2001
From: xiaer1921 <xiaer1921(a)gmail.com>
Date: Tue, 29 Mar 2022 20:03:03 +0800
Subject: [PATCH] Fix for "kmem -s|-S" on Linux 5.17.0+
Since the following kernel commits split slab info from struct page
into struct slab, crash cannot get several slab related offsets from
struct page.
d122019bf061 ("mm: Split slab into its own type")
401fb12c68c2 ("mm: Differentiate struct slab fields by sl*b implementations")
07f910f9b729 ("mm: Remove slab from struct page")
Without the patch, "kmem -s|-S" options cannot work
correctly with the following errors:
crash> kmem -s
kmem: invalid structure member offset: page_active
FILE: memory.c LINE: 12225 FUNCTION: verify_slab_overload_page()
[/usr/bin/crash] error trace: 532526 => 53353a => 5e0a6a => 5e09dc
[Detaching after fork from child process 28299]
5e09dc: OFFSET_verify.part.36+92
[Detaching after fork from child process 28301]
5e0a6a: OFFSET_verify+58
[Detaching after fork from child process 28303]
53353a: verify_slab_overload_page+588
[Detaching after fork from child process 28305]
532526: do_slab_chain_slab_overload_page+1171
kmem: invalid structure member offset: page_active
FILE: memory.c LINE: 12225 FUNCTION: verify_slab_overload_page()
Signed-off-by: xiaer1921 <xiaer1921(a)gmail.com>
---
memory.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/memory.c b/memory.c
index 8448ddc..388b12d 100644
--- a/memory.c
+++ b/memory.c
@@ -680,6 +680,8 @@ vm_init(void)
MEMBER_OFFSET_INIT(slab_s_mem, "slab", "s_mem");
MEMBER_OFFSET_INIT(slab_inuse, "slab", "inuse");
MEMBER_OFFSET_INIT(slab_free, "slab", "free");
+ MEMBER_OFFSET_INIT(page_s_mem, "slab", "s_mem");
+ MEMBER_OFFSET_INIT(page_active, "slab", "active");
/*
* slab members were moved to an anonymous union in 2.6.39.
*/
@@ -691,6 +693,10 @@ vm_init(void)
ANON_MEMBER_OFFSET_INIT(slab_inuse, "slab", "inuse");
if (INVALID_MEMBER(slab_free))
ANON_MEMBER_OFFSET_INIT(slab_free, "slab", "free");
+ if (INVALID_MEMBER(page_s_mem))
+ ANON_MEMBER_OFFSET_INIT(page_s_mem, "slab", "s_mem");
+ if (INVALID_MEMBER(page_active))
+ ANON_MEMBER_OFFSET_INIT(page_active, "slab", "active");
}
MEMBER_OFFSET_INIT(array_cache_avail, "array_cache", "avail");
--
2.7.4
================================================================
Thanks.
2 years, 7 months