Index: sys/amd64/amd64/minidump_machdep.c =================================================================== --- sys/amd64/amd64/minidump_machdep.c +++ sys/amd64/amd64/minidump_machdep.c @@ -81,48 +81,13 @@ return (error); } -static struct { - int min_per; - int max_per; - int visited; -} progress_track[10] = { - { 0, 10, 0}, - { 10, 20, 0}, - { 20, 30, 0}, - { 30, 40, 0}, - { 40, 50, 0}, - { 50, 60, 0}, - { 60, 70, 0}, - { 70, 80, 0}, - { 80, 90, 0}, - { 90, 100, 0} -}; - -static void -report_progress(size_t progress, size_t dumpsize) -{ - int sofar, i; - - sofar = 100 - ((progress * 100) / dumpsize); - for (i = 0; i < nitems(progress_track); i++) { - if (sofar < progress_track[i].min_per || - sofar > progress_track[i].max_per) - continue; - if (progress_track[i].visited) - return; - progress_track[i].visited = 1; - printf("..%d%%", sofar); - return; - } -} - /* Pat the watchdog approximately every 128MB of the dump. */ #define WDOG_DUMP_INTERVAL (128 * 1024 * 1024) static int blk_write(struct dumperinfo *di, char *ptr, vm_paddr_t pa, size_t sz) { - size_t len; + size_t len, delta; int error, i, c; u_int maxdumpsz; @@ -148,14 +113,17 @@ if (error) return (error); } + delta = 0; while (sz) { len = maxdumpsz - fragsz; if (len > sz) len = sz; counter += len; progress -= len; + delta += len; if (counter >> 24) { - report_progress(progress, dumpsize); + minidumpsys_pb_progress(delta); + delta = 0; counter &= (1<<24) - 1; } if (progress <= wdog_next) { @@ -192,6 +160,8 @@ if (c != -1) printf(" (CTRL-C to abort) "); } + if (delta > 0) + minidumpsys_pb_progress(delta); return (0); } @@ -214,8 +184,7 @@ retry: retry_count++; counter = 0; - for (i = 0; i < nitems(progress_track); i++) - progress_track[i].visited = 0; + /* Walk page table pages, set bits in vm_page_dump */ pmapsize = 0; for (va = VM_MIN_KERNEL_ADDRESS; va < MAX(KERNBASE + nkpt * NBPDR, @@ -298,6 +267,7 @@ dumpsize += PAGE_SIZE; wdog_next = progress = dumpsize; + minidumpsys_pb_init(dumpsize); /* Initialize mdhdr */ bzero(&mdhdr, sizeof(mdhdr)); Index: sys/arm/arm/minidump_machdep.c =================================================================== --- sys/arm/arm/minidump_machdep.c +++ sys/arm/arm/minidump_machdep.c @@ -63,9 +63,7 @@ /* Handle chunked writes. */ static size_t fragsz; static void *dump_va; -static uint64_t counter, progress; - -#define PG2MB(pgs) (((pgs) + (1 << 8) - 1) >> 8) +static uint64_t counter; static int blk_flush(struct dumperinfo *di) @@ -83,7 +81,7 @@ static int blk_write(struct dumperinfo *di, char *ptr, vm_paddr_t pa, size_t sz) { - size_t len; + size_t len, delta; int error, i, c; u_int maxdumpsz; @@ -111,14 +109,16 @@ if (error) return (error); } + delta = 0; while (sz) { len = maxdumpsz - fragsz; if (len > sz) len = sz; counter += len; - progress -= len; + delta += len; if (counter >> 22) { - printf(" %lld", PG2MB(progress >> PAGE_SHIFT)); + minidumpsys_pb_progress(delta); + delta = 0; counter &= (1<<22) - 1; } @@ -152,6 +152,8 @@ if (c != -1) printf(" (CTRL-C to abort) "); } + if (delta > 0) + minidumpsys_pb_progress(delta); return (0); } @@ -206,7 +208,7 @@ } dumpsize += PAGE_SIZE; - progress = dumpsize; + minidumpsys_pb_init(dumpsize); /* Initialize mdhdr */ bzero(&mdhdr, sizeof(mdhdr)); Index: sys/arm64/arm64/minidump_machdep.c =================================================================== --- sys/arm64/arm64/minidump_machdep.c +++ sys/arm64/arm64/minidump_machdep.c @@ -62,7 +62,7 @@ /* Handle chunked writes. */ static size_t fragsz; static void *dump_va; -static size_t counter, progress, dumpsize; +static size_t counter, dumpsize; static uint64_t tmpbuffer[Ln_ENTRIES]; @@ -79,45 +79,10 @@ return (error); } -static struct { - int min_per; - int max_per; - int visited; -} progress_track[10] = { - { 0, 10, 0}, - { 10, 20, 0}, - { 20, 30, 0}, - { 30, 40, 0}, - { 40, 50, 0}, - { 50, 60, 0}, - { 60, 70, 0}, - { 70, 80, 0}, - { 80, 90, 0}, - { 90, 100, 0} -}; - -static void -report_progress(size_t progress, size_t dumpsize) -{ - int sofar, i; - - sofar = 100 - ((progress * 100) / dumpsize); - for (i = 0; i < nitems(progress_track); i++) { - if (sofar < progress_track[i].min_per || - sofar > progress_track[i].max_per) - continue; - if (progress_track[i].visited) - return; - progress_track[i].visited = 1; - printf("..%d%%", sofar); - return; - } -} - static int blk_write(struct dumperinfo *di, char *ptr, vm_paddr_t pa, size_t sz) { - size_t len; + size_t len, delta; int error, c; u_int maxdumpsz; @@ -146,14 +111,16 @@ if (error) return (error); } + delta = 0; while (sz) { len = maxdumpsz - fragsz; if (len > sz) len = sz; counter += len; - progress -= len; + delta += len; if (counter >> 22) { - report_progress(progress, dumpsize); + minidumpsys_pb_progress(delta); + delta = 0; counter &= (1 << 22) - 1; } @@ -182,6 +149,8 @@ if (c != -1) printf(" (CTRL-C to abort) "); } + if (delta > 0) + minidumpsys_pb_progress(delta); return (0); } @@ -245,7 +214,7 @@ } dumpsize += PAGE_SIZE; - progress = dumpsize; + minidumpsys_pb_init(dumpsize); /* Initialize mdhdr */ bzero(&mdhdr, sizeof(mdhdr)); Index: sys/kern/kern_dump.c =================================================================== --- sys/kern/kern_dump.c +++ sys/kern/kern_dump.c @@ -385,3 +385,60 @@ printf("\n** DUMP FAILED (ERROR %d) **\n", error); return (error); } + +/* Minidump progress bar */ +static struct { + const int min_per; + const int max_per; + bool visited; +} progress_track[10] = { + { 0, 10, false}, + { 10, 20, false}, + { 20, 30, false}, + { 30, 40, false}, + { 40, 50, false}, + { 50, 60, false}, + { 60, 70, false}, + { 70, 80, false}, + { 80, 90, false}, + { 90, 100, false} +}; + +static uint64_t minidump_size; +static uint64_t minidump_remaining; + +/* Reset the progress bar for a dump of dumpsize. */ +void +minidumpsys_pb_init(uint64_t dumpsize) +{ + int i; + + minidump_remaining = minidump_size = dumpsize; + + for (i = 0; i < nitems(progress_track); i++) + progress_track[i].visited = false; +} + +/* + * Update the progress according to the delta bytes that were written out. + * Check and print the progress percentage. + */ +void +minidumpsys_pb_progress(size_t delta) +{ + int sofar, i; + + minidump_remaining -= delta; + + sofar = 100 - ((minidump_remaining * 100) / minidump_size); + for (i = 0; i < nitems(progress_track); i++) { + if (sofar < progress_track[i].min_per || + sofar > progress_track[i].max_per) + continue; + if (!progress_track[i].visited) { + progress_track[i].visited = true; + printf("..%d%%", sofar); + } + break; + } +} Index: sys/mips/mips/minidump_machdep.c =================================================================== --- sys/mips/mips/minidump_machdep.c +++ sys/mips/mips/minidump_machdep.c @@ -58,51 +58,16 @@ static struct kerneldumpheader kdh; /* Handle chunked writes. */ -static uint64_t counter, progress, dumpsize; +static uint64_t counter, dumpsize; /* Just auxiliary bufffer */ static char tmpbuffer[PAGE_SIZE] __aligned(sizeof(uint64_t)); extern pd_entry_t *kernel_segmap; -static struct { - int min_per; - int max_per; - int visited; -} progress_track[10] = { - { 0, 10, 0}, - { 10, 20, 0}, - { 20, 30, 0}, - { 30, 40, 0}, - { 40, 50, 0}, - { 50, 60, 0}, - { 60, 70, 0}, - { 70, 80, 0}, - { 80, 90, 0}, - { 90, 100, 0} -}; - -static void -report_progress(uint64_t progress, uint64_t dumpsize) -{ - int sofar, i; - - sofar = 100 - ((progress * 100) / dumpsize); - for (i = 0; i < nitems(progress_track); i++) { - if (sofar < progress_track[i].min_per || - sofar > progress_track[i].max_per) - continue; - if (progress_track[i].visited) - return; - progress_track[i].visited = 1; - printf("..%d%%", sofar); - return; - } -} - static int write_buffer(struct dumperinfo *di, char *ptr, size_t sz) { - size_t len; + size_t len, delta; int error, c; u_int maxdumpsz; @@ -112,14 +77,16 @@ maxdumpsz = PAGE_SIZE; error = 0; + delta = 0; while (sz) { len = min(maxdumpsz, sz); counter += len; - progress -= len; + delta += len; if (counter >> 22) { - report_progress(progress, dumpsize); + minidumpsys_pb_progress(delta); + delta = 0; counter &= (1<<22) - 1; } @@ -142,6 +109,8 @@ if (c != -1) printf(" (CTRL-C to abort) "); } + if (delta > 0) + minidumpsys_pb_progress(delta); return (0); } @@ -203,7 +172,7 @@ } dumpsize += PAGE_SIZE; - progress = dumpsize; + minidumpsys_pb_init(dumpsize); /* Initialize mdhdr */ bzero(&mdhdr, sizeof(mdhdr)); Index: sys/powerpc/powerpc/minidump_machdep.c =================================================================== --- sys/powerpc/powerpc/minidump_machdep.c +++ sys/powerpc/powerpc/minidump_machdep.c @@ -69,24 +69,7 @@ static struct kerneldumpheader kdh; static char pgbuf[PAGE_SIZE]; -static struct { - int min_per; - int max_per; - int visited; -} progress_track[10] = { - { 0, 10, 0}, - { 10, 20, 0}, - { 20, 30, 0}, - { 30, 40, 0}, - { 40, 50, 0}, - { 50, 60, 0}, - { 60, 70, 0}, - { 70, 80, 0}, - { 80, 90, 0}, - { 90, 100, 0} -}; - -static size_t counter, dumpsize, progress; +static size_t counter, dumpsize; /* Handle chunked writes. */ static size_t fragsz; @@ -98,24 +81,6 @@ pmap_kenter(va, pa); } -static void -report_progress(void) -{ - int sofar, i; - - sofar = 100 - ((progress * 100) / dumpsize); - for (i = 0; i < nitems(progress_track); i++) { - if (sofar < progress_track[i].min_per || - sofar > progress_track[i].max_per) - continue; - if (progress_track[i].visited) - return; - progress_track[i].visited = 1; - printf("..%d%%", sofar); - return; - } -} - static int blk_flush(struct dumperinfo *di) { @@ -133,7 +98,7 @@ static int blk_write(struct dumperinfo *di, char *ptr, vm_paddr_t pa, size_t sz) { - size_t len, maxdumpsz; + size_t len, delta, maxdumpsz; int error, i, c; maxdumpsz = MIN(di->maxiosize, MAXDUMPPGS * PAGE_SIZE); @@ -161,14 +126,16 @@ if (error) return (error); } + delta = 0; while (sz) { len = maxdumpsz - fragsz; if (len > sz) len = sz; counter += len; - progress -= len; + delta += len; if (counter >> 20) { - report_progress(); + minidumpsys_pb_progress(delta); + delta = 0; counter &= (1<<20) - 1; } @@ -201,6 +168,8 @@ if (c != -1) printf(" (CTRL-C to abort) "); } + if (delta > 0) + minidumpsys_pb_progress(delta); return (0); } @@ -231,7 +200,7 @@ minidumpsys(struct dumperinfo *di) { vm_paddr_t pa; - int error, i, retry_count; + int error, retry_count; uint32_t pmapsize; struct minidumphdr mdhdr; @@ -241,11 +210,6 @@ fragsz = 0; DBG(total = dumptotal = 0;) - /* Reset progress */ - counter = 0; - for (i = 0; i < nitems(progress_track); i++) - progress_track[i].visited = 0; - /* Build set of dumpable pages from kernel pmap */ pmapsize = dumpsys_scan_pmap(); if (pmapsize % PAGE_SIZE != 0) { @@ -266,7 +230,7 @@ else dump_drop_page(pa); } - progress = dumpsize; + minidumpsys_pb_init(dumpsize); /* Initialize mdhdr */ bzero(&mdhdr, sizeof(mdhdr)); Index: sys/riscv/riscv/minidump_machdep.c =================================================================== --- sys/riscv/riscv/minidump_machdep.c +++ sys/riscv/riscv/minidump_machdep.c @@ -60,45 +60,10 @@ /* Handle chunked writes. */ static size_t fragsz; static void *dump_va; -static size_t counter, progress, dumpsize; +static size_t counter, dumpsize; static uint64_t tmpbuffer[PAGE_SIZE / sizeof(uint64_t)]; -static struct { - int min_per; - int max_per; - int visited; -} progress_track[10] = { - { 0, 10, 0}, - { 10, 20, 0}, - { 20, 30, 0}, - { 30, 40, 0}, - { 40, 50, 0}, - { 50, 60, 0}, - { 60, 70, 0}, - { 70, 80, 0}, - { 80, 90, 0}, - { 90, 100, 0} -}; - -static void -report_progress(size_t progress, size_t dumpsize) -{ - int sofar, i; - - sofar = 100 - ((progress * 100) / dumpsize); - for (i = 0; i < nitems(progress_track); i++) { - if (sofar < progress_track[i].min_per || - sofar > progress_track[i].max_per) - continue; - if (progress_track[i].visited) - return; - progress_track[i].visited = 1; - printf("..%d%%", sofar); - return; - } -} - static int blk_flush(struct dumperinfo *di) { @@ -123,7 +88,7 @@ static int blk_write(struct dumperinfo *di, char *ptr, vm_paddr_t pa, size_t sz) { - size_t len; + size_t len, delta; int error, c; u_int maxdumpsz; @@ -152,14 +117,16 @@ if (error != 0) return (error); } + delta = 0; while (sz) { len = maxdumpsz - fragsz; if (len > sz) len = sz; counter += len; - progress -= len; + delta += len; if (counter >> 22) { - report_progress(progress, dumpsize); + minidumpsys_pb_progress(delta); + delta = 0; counter &= (1 << 22) - 1; } @@ -188,6 +155,8 @@ if (c != -1) printf(" (CTRL-C to abort) "); } + if (delta > 0) + minidumpsys_pb_progress(delta); return (0); } @@ -253,7 +222,7 @@ } dumpsize += PAGE_SIZE; - progress = dumpsize; + minidumpsys_pb_init(dumpsize); /* Initialize mdhdr */ bzero(&mdhdr, sizeof(mdhdr)); Index: sys/sys/kerneldump.h =================================================================== --- sys/sys/kerneldump.h +++ sys/sys/kerneldump.h @@ -153,6 +153,9 @@ extern int do_minidump; +void minidumpsys_pb_init(uint64_t); +void minidumpsys_pb_progress(size_t); + #endif #endif /* _SYS_KERNELDUMP_H */