Skip to content

Commit

Permalink
diskdump: use mmap/madvise to improve the start-up
Browse files Browse the repository at this point in the history
Sometimes, the size of bitmap in vmcore can be very large, such as over
256M. This patch uses mmap/madvise to improve the performance of reading
bitmap in the non-FLAT_FORMAT code path.

Without the 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
    ............................

With the patch:
    #echo  3 > /proc/sys/vm/drop_caches;
    #time ./crash -i ./commands.txt /root/t/vmlinux /root/t/vmcore > /dev/null 2>&1
    ............................
        real    0m44.097s
        user    0m19.031s
        sys     0m1.620s
    ............................

Note:
    Test files:
        vmlinux: 272M
        vmcore : 23G (bitmap_len: 4575985664)
    #cat ./commands.txt
        quit

Signed-off-by: Huang Shijie <[email protected]>
  • Loading branch information
HuangShijie2024 authored and lian-bo committed Apr 10, 2022
1 parent 8736908 commit a334423
Showing 1 changed file with 16 additions and 26 deletions.
42 changes: 16 additions & 26 deletions diskdump.c
Original file line number Diff line number Diff line change
Expand Up @@ -538,9 +538,6 @@ read_dump_header(char *file)
struct kdump_sub_header *sub_header_kdump = NULL;
size_t size;
off_t bitmap_len;
char *bufptr;
size_t len;
ssize_t bytes_read;
int block_size = (int)sysconf(_SC_PAGESIZE);
off_t offset;
const off_t failed = (off_t)-1;
Expand Down Expand Up @@ -723,10 +720,6 @@ read_dump_header(char *file)

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))
Expand All @@ -735,30 +728,23 @@ read_dump_header(char *file)
(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_WILLNEED);
}

if (dump_is_partial(header))
Expand Down Expand Up @@ -914,8 +900,12 @@ read_dump_header(char *file)
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)
Expand Down

0 comments on commit a334423

Please sign in to comment.