diff options
author | ps <ps@FreeBSD.org> | 2000-10-17 10:05:49 +0000 |
---|---|---|
committer | ps <ps@FreeBSD.org> | 2000-10-17 10:05:49 +0000 |
commit | c71ac689e04ce39d113325e3854477539dae464c (patch) | |
tree | 331cd4cbe2e1e3d9d7734fa4fce3e6a5554d434c /sys/dev/ata | |
parent | 26207dd1489dfcba9ad2215401292904446e000a (diff) | |
download | FreeBSD-src-c71ac689e04ce39d113325e3854477539dae464c.zip FreeBSD-src-c71ac689e04ce39d113325e3854477539dae464c.tar.gz |
Implement write combining for crashdumps. This is useful when
write caching is disabled on both SCSI and IDE disks where large
memory dumps could take up to an hour to complete.
Taking an i386 scsi based system with 512MB of ram and timing (in
seconds) how long it took to complete a dump, the following results
were obtained:
Before: After:
WCE TIME WCE TIME
------------------ ------------------
1 141.820972 1 15.600111
0 797.265072 0 65.480465
Obtained from: Yahoo!
Reviewed by: peter
Diffstat (limited to 'sys/dev/ata')
-rw-r--r-- | sys/dev/ata/ata-disk.c | 28 |
1 files changed, 20 insertions, 8 deletions
diff --git a/sys/dev/ata/ata-disk.c b/sys/dev/ata/ata-disk.c index dba5fbe..85421c2 100644 --- a/sys/dev/ata/ata-disk.c +++ b/sys/dev/ata/ata-disk.c @@ -257,7 +257,10 @@ addump(dev_t dev) struct ad_request request; u_int count, blkno, secsize; vm_offset_t addr = 0; + long blkcnt; + int dumppages = MAXDUMPPGS; int error; + int i; if ((error = disk_dumpcheck(dev, &count, &blkno, &secsize))) return error; @@ -269,18 +272,27 @@ addump(dev_t dev) adp->controller->mode[ATA_DEV(adp->unit)] = ATA_PIO; ata_reinit(adp->controller); + blkcnt = howmany(PAGE_SIZE, secsize); + while (count > 0) { caddr_t va; DELAY(1000); - if (is_physical_memory(addr)) - va = pmap_kenter_temporary(trunc_page(addr)); - else - va = pmap_kenter_temporary(trunc_page(0)); + + if ((count / blkcnt) < dumppages) + dumppages = count / blkcnt; + + for (i = 0; i < dumppages; ++i) { + vm_offset_t a = addr + (i * PAGE_SIZE); + if (is_physical_memory(a)) + va = pmap_kenter_temporary(trunc_page(a), i); + else + va = pmap_kenter_temporary(trunc_page(0), i); + } bzero(&request, sizeof(struct ad_request)); request.device = adp; request.blockaddr = blkno; - request.bytecount = PAGE_SIZE; + request.bytecount = PAGE_SIZE * dumppages; request.data = va; while (request.bytecount > 0) { @@ -300,9 +312,9 @@ addump(dev_t dev) printf("%ld ", (long)(count * DEV_BSIZE) / (1024 * 1024)); } - blkno += howmany(PAGE_SIZE, secsize); - count -= howmany(PAGE_SIZE, secsize); - addr += PAGE_SIZE; + blkno += blkcnt * dumppages; + count -= blkcnt * dumppages; + addr += PAGE_SIZE * dumppages; if (cncheckc() != -1) return EINTR; } |