diff --git a/sys/amd64/amd64/minidump_machdep.c b/sys/amd64/amd64/minidump_machdep.c --- a/sys/amd64/amd64/minidump_machdep.c +++ b/sys/amd64/amd64/minidump_machdep.c @@ -60,14 +60,12 @@ /* Handle chunked writes. */ static size_t fragsz; static void *dump_va; -static size_t counter, progress, dumpsize, wdog_next; +static size_t progress, dumpsize, wdog_next; static int dump_retry_count = 5; SYSCTL_INT(_machdep, OID_AUTO, dump_retry_count, CTLFLAG_RWTUN, &dump_retry_count, 0, "Number of times dump has to retry before bailing out"); -#define PG2MB(pgs) (((pgs) + (1 << 8) - 1) >> 8) - static int blk_flush(struct dumperinfo *di) { @@ -81,41 +79,6 @@ 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) @@ -152,12 +115,9 @@ len = maxdumpsz - fragsz; if (len > sz) len = sz; - counter += len; progress -= len; - if (counter >> 24) { - report_progress(progress, dumpsize); - counter &= (1<<24) - 1; - } + + dumpsys_pb_progress(len); if (progress <= wdog_next) { wdog_kern_pat(WD_LASTVAL); if (wdog_next > WDOG_DUMP_INTERVAL) @@ -213,9 +173,7 @@ retry_count = 0; 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 +256,7 @@ dumpsize += PAGE_SIZE; wdog_next = progress = dumpsize; + dumpsys_pb_init(dumpsize); /* Initialize mdhdr */ bzero(&mdhdr, sizeof(mdhdr)); diff --git a/sys/arm/arm/minidump_machdep.c b/sys/arm/arm/minidump_machdep.c --- a/sys/arm/arm/minidump_machdep.c +++ b/sys/arm/arm/minidump_machdep.c @@ -63,9 +63,6 @@ /* 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 int blk_flush(struct dumperinfo *di) @@ -115,13 +112,8 @@ len = maxdumpsz - fragsz; if (len > sz) len = sz; - counter += len; - progress -= len; - if (counter >> 22) { - printf(" %lld", PG2MB(progress >> PAGE_SHIFT)); - counter &= (1<<22) - 1; - } + dumpsys_pb_progress(len); #ifdef SW_WATCHDOG wdog_kern_pat(WD_LASTVAL); #endif @@ -182,7 +174,6 @@ */ dcache_wbinv_poc_all(); - counter = 0; /* Walk page table pages, set bits in vm_page_dump */ ptesize = 0; for (va = KERNBASE; va < kernel_vm_end; va += PAGE_SIZE) { @@ -206,7 +197,7 @@ } dumpsize += PAGE_SIZE; - progress = dumpsize; + dumpsys_pb_init(dumpsize); /* Initialize mdhdr */ bzero(&mdhdr, sizeof(mdhdr)); diff --git a/sys/arm/include/dump.h b/sys/arm/include/dump.h --- a/sys/arm/include/dump.h +++ b/sys/arm/include/dump.h @@ -36,6 +36,9 @@ #define DUMPSYS_MD_PA_NPAIRS 20 #define DUMPSYS_NUM_AUX_HDRS 1 +/* How often to check the dump progress bar? */ +#define DUMPSYS_PB_CHECK_BITS 22 /* Every 4MB */ + void dumpsys_wbinv_all(void); int dumpsys_write_aux_headers(struct dumperinfo *di); diff --git a/sys/arm64/arm64/minidump_machdep.c b/sys/arm64/arm64/minidump_machdep.c --- a/sys/arm64/arm64/minidump_machdep.c +++ b/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 dumpsize; static uint64_t tmpbuffer[Ln_ENTRIES]; @@ -79,41 +79,6 @@ 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) { @@ -150,13 +115,8 @@ len = maxdumpsz - fragsz; if (len > sz) len = sz; - counter += len; - progress -= len; - if (counter >> 22) { - report_progress(progress, dumpsize); - counter &= (1 << 22) - 1; - } + dumpsys_pb_progress(len); wdog_kern_pat(WD_LASTVAL); if (ptr) { @@ -245,7 +205,7 @@ } dumpsize += PAGE_SIZE; - progress = dumpsize; + dumpsys_pb_init(dumpsize); /* Initialize mdhdr */ bzero(&mdhdr, sizeof(mdhdr)); diff --git a/sys/arm64/include/dump.h b/sys/arm64/include/dump.h --- a/sys/arm64/include/dump.h +++ b/sys/arm64/include/dump.h @@ -40,6 +40,9 @@ #define DUMPSYS_MD_PA_NPAIRS 20 #define DUMPSYS_NUM_AUX_HDRS 1 +/* How often to check the dump progress bar? */ +#define DUMPSYS_PB_CHECK_BITS 22 /* Every 4MB */ + void dumpsys_wbinv_all(void); int dumpsys_write_aux_headers(struct dumperinfo *di); diff --git a/sys/i386/i386/minidump_machdep_base.c b/sys/i386/i386/minidump_machdep_base.c --- a/sys/i386/i386/minidump_machdep_base.c +++ b/sys/i386/i386/minidump_machdep_base.c @@ -60,9 +60,6 @@ /* 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 int blk_flush(struct dumperinfo *di) @@ -110,13 +107,8 @@ len = maxdumpsz - fragsz; if (len > sz) len = sz; - counter += len; - progress -= len; - if (counter >> 24) { - printf(" %lld", PG2MB(progress >> PAGE_SHIFT)); - counter &= (1<<24) - 1; - } + dumpsys_pb_progress(len); wdog_kern_pat(WD_LASTVAL); if (ptr) { @@ -173,7 +165,6 @@ int j, k; struct minidumphdr mdhdr; - counter = 0; /* Walk page table pages, set bits in vm_page_dump */ ptesize = 0; for (va = KERNBASE; va < kernel_vm_end; va += NBPDR) { @@ -224,7 +215,7 @@ } dumpsize += PAGE_SIZE; - progress = dumpsize; + dumpsys_pb_init(dumpsize); /* Initialize mdhdr */ bzero(&mdhdr, sizeof(mdhdr)); diff --git a/sys/kern/kern_dump.c b/sys/kern/kern_dump.c --- a/sys/kern/kern_dump.c +++ b/sys/kern/kern_dump.c @@ -385,3 +385,72 @@ 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 dumpsys_pb_size; +static uint64_t dumpsys_pb_remaining; +static uint64_t dumpsys_pb_check; + +/* Reset the progress bar for a dump of dumpsize. */ +void +dumpsys_pb_init(uint64_t dumpsize) +{ + int i; + + dumpsys_pb_size = dumpsys_pb_remaining = dumpsize; + dumpsys_pb_check = 0; + + 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 +dumpsys_pb_progress(size_t delta) +{ + int sofar, i; + + dumpsys_pb_remaining -= delta; + dumpsys_pb_check += delta; + + /* + * To save time while dumping, only loop through progress_track + * occasionally. + */ + if ((dumpsys_pb_check >> DUMPSYS_PB_CHECK_BITS) == 0) + return; + else + dumpsys_pb_check &= (1 << DUMPSYS_PB_CHECK_BITS) - 1; + + sofar = 100 - ((dumpsys_pb_remaining * 100) / dumpsys_pb_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; + } +} diff --git a/sys/mips/include/dump.h b/sys/mips/include/dump.h --- a/sys/mips/include/dump.h +++ b/sys/mips/include/dump.h @@ -36,6 +36,9 @@ #define DUMPSYS_MD_PA_NPAIRS 20 #define DUMPSYS_NUM_AUX_HDRS 0 +/* How often to check the dump progress bar? */ +#define DUMPSYS_PB_CHECK_BITS 22 /* Every 4MB */ + void dumpsys_wbinv_all(void); static inline void diff --git a/sys/mips/mips/minidump_machdep.c b/sys/mips/mips/minidump_machdep.c --- a/sys/mips/mips/minidump_machdep.c +++ b/sys/mips/mips/minidump_machdep.c @@ -58,47 +58,12 @@ static struct kerneldumpheader kdh; /* Handle chunked writes. */ -static uint64_t counter, progress, dumpsize; +static uint64_t 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) { @@ -115,14 +80,8 @@ while (sz) { len = min(maxdumpsz, sz); - counter += len; - progress -= len; - - if (counter >> 22) { - report_progress(progress, dumpsize); - counter &= (1<<22) - 1; - } + dumpsys_pb_progress(len); wdog_kern_pat(WD_LASTVAL); if (ptr) { @@ -163,7 +122,6 @@ /* Flush cache */ mips_dcache_wbinv_all(); - counter = 0; /* Walk page table pages, set bits in vm_page_dump */ ptesize = 0; @@ -203,7 +161,7 @@ } dumpsize += PAGE_SIZE; - progress = dumpsize; + dumpsys_pb_init(dumpsize); /* Initialize mdhdr */ bzero(&mdhdr, sizeof(mdhdr)); diff --git a/sys/powerpc/include/dump.h b/sys/powerpc/include/dump.h --- a/sys/powerpc/include/dump.h +++ b/sys/powerpc/include/dump.h @@ -35,6 +35,9 @@ #define DUMPSYS_MD_PA_NPAIRS (PHYS_AVAIL_SZ + 1) #define DUMPSYS_NUM_AUX_HDRS 0 +/* How often to check the dump progress bar? */ +#define DUMPSYS_PB_CHECK_BITS 20 /* Every 1MB */ + void dumpsys_pa_init(void); void dumpsys_unmap_chunk(vm_paddr_t, size_t, void *); size_t dumpsys_scan_pmap(void); diff --git a/sys/powerpc/powerpc/minidump_machdep.c b/sys/powerpc/powerpc/minidump_machdep.c --- a/sys/powerpc/powerpc/minidump_machdep.c +++ b/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 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) { @@ -165,12 +130,8 @@ len = maxdumpsz - fragsz; if (len > sz) len = sz; - counter += len; - progress -= len; - if (counter >> 20) { - report_progress(); - counter &= (1<<20) - 1; - } + + dumpsys_pb_progress(len); if (ptr) { error = dump_append(di, ptr, 0, len); @@ -231,7 +192,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 +202,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 +222,7 @@ else dump_drop_page(pa); } - progress = dumpsize; + dumpsys_pb_init(dumpsize); /* Initialize mdhdr */ bzero(&mdhdr, sizeof(mdhdr)); diff --git a/sys/riscv/include/dump.h b/sys/riscv/include/dump.h --- a/sys/riscv/include/dump.h +++ b/sys/riscv/include/dump.h @@ -37,6 +37,9 @@ #define DUMPSYS_MD_PA_NPAIRS 10 #define DUMPSYS_NUM_AUX_HDRS 0 +/* How often to check the dump progress bar? */ +#define DUMPSYS_PB_CHECK_BITS 22 /* Every 4MB */ + static inline void dumpsys_pa_init(void) { diff --git a/sys/riscv/riscv/minidump_machdep.c b/sys/riscv/riscv/minidump_machdep.c --- a/sys/riscv/riscv/minidump_machdep.c +++ b/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 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) { @@ -156,13 +121,8 @@ len = maxdumpsz - fragsz; if (len > sz) len = sz; - counter += len; - progress -= len; - if (counter >> 22) { - report_progress(progress, dumpsize); - counter &= (1 << 22) - 1; - } + dumpsys_pb_progress(len); wdog_kern_pat(WD_LASTVAL); if (ptr) { @@ -253,7 +213,7 @@ } dumpsize += PAGE_SIZE; - progress = dumpsize; + dumpsys_pb_init(dumpsize); /* Initialize mdhdr */ bzero(&mdhdr, sizeof(mdhdr)); diff --git a/sys/sys/kerneldump.h b/sys/sys/kerneldump.h --- a/sys/sys/kerneldump.h +++ b/sys/sys/kerneldump.h @@ -151,6 +151,9 @@ void dumpsys_gen_unmap_chunk(vm_paddr_t, size_t, void *); int dumpsys_gen_write_aux_headers(struct dumperinfo *); +void dumpsys_pb_init(uint64_t); +void dumpsys_pb_progress(size_t); + extern int do_minidump; #endif diff --git a/sys/x86/include/dump.h b/sys/x86/include/dump.h --- a/sys/x86/include/dump.h +++ b/sys/x86/include/dump.h @@ -42,6 +42,9 @@ #define DUMPSYS_MD_PA_NPAIRS 10 #define DUMPSYS_NUM_AUX_HDRS 0 +/* How often to check the dump progress bar? */ +#define DUMPSYS_PB_CHECK_BITS 24 /* Every 16MB */ + static inline void dumpsys_pa_init(void) {