summaryrefslogtreecommitdiffstats
path: root/sys/dev/ata
diff options
context:
space:
mode:
authorps <ps@FreeBSD.org>2000-10-17 10:05:49 +0000
committerps <ps@FreeBSD.org>2000-10-17 10:05:49 +0000
commitc71ac689e04ce39d113325e3854477539dae464c (patch)
tree331cd4cbe2e1e3d9d7734fa4fce3e6a5554d434c /sys/dev/ata
parent26207dd1489dfcba9ad2215401292904446e000a (diff)
downloadFreeBSD-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.c28
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;
}
OpenPOWER on IntegriCloud