Ive writen a quick patch for dev/ata/ata-disk.c:addump under 4.0-stable (03/26/01) which is considerbally faster. I did dumps on a SMP system with 512 megs of ram. Old: 201 seconds. New: 59 seconds. What I could gather from talking to people over irc/email about the problem was that there was a DELAY(1000) in between each printf to deal with problems with serial connections to the debugger. The soultion I came up with simply to display a smaller ammount of printf's the output looks like this: Dump in progress, percentage complete: 10 20 30 40 50 60 70 80 100. Done. The dump_stats() routine probally belongs in some kern/subr_whatever.c and should probally be used in the other dump routines for da/ide etc. Any thoughts or comments ?
--- ata-disk.c.orig Tue Mar 27 10:31:59 2001 +++ ata-disk.c Tue Mar 27 14:39:24 2001 @@ -91,6 +91,7 @@ static struct cdevsw fakewddisk_cdevsw; /* prototypes */ +int dump_stats(int, int, int *); static void ad_timeout(struct ad_request *); static int32_t ad_version(u_int16_t); @@ -259,7 +260,7 @@ struct ad_request request; u_int count, blkno, secsize; vm_offset_t addr = 0; - int error; + int error, left, state, total, percent; if ((error = disk_dumpcheck(dev, &count, &blkno, &secsize))) return error; @@ -271,8 +272,12 @@ adp->controller->mode[ATA_DEV(adp->unit)] = ATA_PIO; ata_reinit(adp->controller); + state = left = 0; + total = (count * DEV_BSIZE) / (1024 * 1024); + + printf("Dump in progress, percentage complete: "); + while (count > 0) { - DELAY(1000); if (is_physical_memory(addr)) pmap_enter(kernel_pmap, (vm_offset_t)CADDR1, trunc_page(addr), VM_PROT_READ, TRUE); @@ -300,9 +305,17 @@ if (wdog_tickler) (*wdog_tickler)(); #endif - printf("%ld ", (long)(count * DEV_BSIZE) / (1024 * 1024)); - } + left++; + percent = left * 100 / total; + /* + * Rate limit printf's to replace old DELAY(1000) + * This is done so that old slow serial connections + * do not get hosed. + */ + + dump_stats(percent, total, &state); + } blkno += howmany(PAGE_SIZE, secsize); count -= howmany(PAGE_SIZE, secsize); addr += PAGE_SIZE; @@ -619,4 +632,96 @@ if (version & (1<<bit)) return bit; return 0; +} + +int +dump_stats(count, total, state) + int count; + int total; + int *state; +{ + switch (*state) + { + case 0: + if (count > 10) + *state = 10; + break; + + case 10: + if (count > 20) + { + printf("%d ", *state); + *state = 20; + } + break; + + case 20: + if (count > 30) + { + printf("%d ", *state); + *state = 30; + } + break; + + case 30: + if (count > 40) + { + printf("%d ", *state); + *state = 40; + } + break; + + case 40: + if (count > 50) + { + printf("%d ", *state); + *state = 50; + } + break; + + case 50: + if (count > 60) + { + printf("%d ", *state); + *state = 60; + } + break; + + case 60: + if (count > 70) + { + printf("%d ", *state); + *state = 70; + } + break; + + case 70: + if (count > 80) + { + printf("%d ", *state); + *state = 80; + } + break; + + case 80: + if (count > 90) + { + printf("%d ", *state); + *state = 90; + } + break; + + case 90: + if (count == 100) + { + *state = 100; + printf("%d. Done", *state); + } + break; + + default: + break; + } + + return 0; }