Skip to content

Commit

Permalink
diskdump: Optimize the boot time
Browse files Browse the repository at this point in the history
1.) The vmcore file maybe very big.

    For example, I have a vmcore file which is over 23G,
    and the panic kernel had 767.6G memory,
    its max_sect_len is 4468736.

    Current code costs too much time to do the following loop:
    ..............................................
        for (i = 1; i < max_sect_len + 1; i++) {
                dd->valid_pages[i] = dd->valid_pages[i - 1];
                for (j = 0; j < BITMAP_SECT_LEN; j++, pfn++)
                        if (page_is_dumpable(pfn))
                                dd->valid_pages[i]++;
    ..............................................

    For my case, it costs about 56 seconds to finish the
    big loop.

    This patch moves the hweightXX macros to defs.h,
    and uses hweight64 to optimize the loop.

    For my vmcore, the loop only costs about one second now.

2.) Tests result:
  # cat ./commands.txt
      quit

 Before:

  #echo  3 > /proc/sys/vm/drop_caches;
  #time ./crash -i ./commands.txt /root/t/vmlinux /root/t/vmcore > /dev/null 2>&1
   ............................
        real    1m54.259s
        user    1m12.494s
        sys     0m3.857s
   ............................

 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    0m55.217s
        user    0m15.114s
        sys     0m3.560s
   ............................

Signed-off-by: Huang Shijie <shijie@os.amperecomputing.com>
  • Loading branch information
HuangShijie2024 authored and lian-bo committed Apr 11, 2022
1 parent a334423 commit b811a04
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 22 deletions.
20 changes: 20 additions & 0 deletions defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -4531,6 +4531,26 @@ struct machine_specific {
#define NUM_IN_BITMAP(bitmap, x) (bitmap[(x)/BITS_PER_LONG] & NUM_TO_BIT(x))
#define SET_BIT(bitmap, x) (bitmap[(x)/BITS_PER_LONG] |= NUM_TO_BIT(x))

static inline unsigned int __const_hweight8(unsigned long w)
{
return
(!!((w) & (1ULL << 0))) +
(!!((w) & (1ULL << 1))) +
(!!((w) & (1ULL << 2))) +
(!!((w) & (1ULL << 3))) +
(!!((w) & (1ULL << 4))) +
(!!((w) & (1ULL << 5))) +
(!!((w) & (1ULL << 6))) +
(!!((w) & (1ULL << 7)));
}

#define __const_hweight16(w) (__const_hweight8(w) + __const_hweight8((w) >> 8))
#define __const_hweight32(w) (__const_hweight16(w) + __const_hweight16((w) >> 16))
#define __const_hweight64(w) (__const_hweight32(w) + __const_hweight32((w) >> 32))

#define hweight32(w) __const_hweight32(w)
#define hweight64(w) __const_hweight64(w)

/*
* precision lengths for fprintf
*/
Expand Down
12 changes: 9 additions & 3 deletions diskdump.c
Original file line number Diff line number Diff line change
Expand Up @@ -544,6 +544,7 @@ read_dump_header(char *file)
ulong pfn;
int i, j, max_sect_len;
int is_split = 0;
ulonglong tmp, *bitmap;

if (block_size < 0)
return FALSE;
Expand Down Expand Up @@ -885,11 +886,16 @@ read_dump_header(char *file)

dd->valid_pages = calloc(sizeof(ulong), max_sect_len + 1);
dd->max_sect_len = max_sect_len;

/* It is safe to convert it to (ulonglong *). */
bitmap = (ulonglong *)dd->dumpable_bitmap;
for (i = 1; i < max_sect_len + 1; i++) {
dd->valid_pages[i] = dd->valid_pages[i - 1];
for (j = 0; j < BITMAP_SECT_LEN; j++, pfn++)
if (page_is_dumpable(pfn))
dd->valid_pages[i]++;
for (j = 0; j < BITMAP_SECT_LEN; j += 64, pfn += 64) {
tmp = bitmap[pfn >> 6];
if (tmp)
dd->valid_pages[i] += hweight64(tmp);
}
}

return TRUE;
Expand Down
19 changes: 0 additions & 19 deletions sbitmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,25 +49,6 @@ struct sbitmapq_data {

static uint sb_flags = 0;

static inline unsigned int __const_hweight8(unsigned long w)
{
return
(!!((w) & (1ULL << 0))) +
(!!((w) & (1ULL << 1))) +
(!!((w) & (1ULL << 2))) +
(!!((w) & (1ULL << 3))) +
(!!((w) & (1ULL << 4))) +
(!!((w) & (1ULL << 5))) +
(!!((w) & (1ULL << 6))) +
(!!((w) & (1ULL << 7)));
}

#define __const_hweight16(w) (__const_hweight8(w) + __const_hweight8((w) >> 8))
#define __const_hweight32(w) (__const_hweight16(w) + __const_hweight16((w) >> 16))
#define __const_hweight64(w) (__const_hweight32(w) + __const_hweight32((w) >> 32))

#define hweight32(w) __const_hweight32(w)
#define hweight64(w) __const_hweight64(w)

#define BIT(nr) (1UL << (nr))

Expand Down

0 comments on commit b811a04

Please sign in to comment.