Kernel - properly handle max. io size when dumping
authorFrançois Tigeot <ftigeot@wolfpond.org>
Sat, 7 Apr 2012 07:08:46 +0000 (09:08 +0200)
committerFrançois Tigeot <ftigeot@wolfpond.org>
Sat, 7 Apr 2012 07:50:48 +0000 (09:50 +0200)
* A magic constant was used to define the maximum IO size used when
  dumping core

* Stop this practice and use the information provided by the underlying
  device driver, capping the result to MAXPHYS if needed.

* This should fix issue #2343

sys/kern/subr_disk.c
sys/platform/pc32/i386/dump_machdep.c
sys/platform/pc32/i386/minidump_machdep.c
sys/platform/pc64/x86_64/dump_machdep.c
sys/platform/pc64/x86_64/minidump_machdep.c

index 78a37b6..d29cd2c 100644 (file)
@@ -850,6 +850,7 @@ disk_dumpconf(cdev_t dev, u_int onoff)
        di.dumper = diskdump;
        di.priv = dev;
        di.blocksize = secsize;
+       di.maxiosize = dev->si_iosize_max;
        di.mediaoffset = blkno * DEV_BSIZE;
        di.mediasize = size * DEV_BSIZE;
 
index b956304..4b02c54 100644 (file)
@@ -159,19 +159,21 @@ cb_dumpdata(struct md_pa *mdp, int seqnr, void *arg)
        uint64_t pgs;
        size_t counter, sz, chunk;
        int i, c, error;
+       int max_iosize;
 
        error = 0;      /* catch case in which chunk size is 0 */
        counter = 0;    /* Update twiddle every 16MB */
        va = NULL;
        pgs = mdp->md_size / PAGE_SIZE;
        pa = mdp->md_start;
+       max_iosize = min(MAXPHYS, di->maxiosize);
 
        kprintf("  chunk %d: %lldMB (%lld pages)", seqnr, PG2MB(pgs), pgs);
 
        while (pgs) {
                chunk = pgs;
-               if (chunk > MAXDUMPPGS)
-                       chunk = MAXDUMPPGS;
+               if (chunk > (max_iosize/PAGE_SIZE))
+                       chunk =  max_iosize/PAGE_SIZE;
                sz = chunk << PAGE_SHIFT;
                counter += sz;
                if (counter >> 24) {
index 824d92c..8155976 100644 (file)
@@ -102,6 +102,7 @@ blk_write(struct dumperinfo *di, char *ptr, vm_paddr_t pa, size_t sz)
 {
        size_t len;
        int error, i, c;
+       int max_iosize;
 
        error = 0;
        if ((sz % PAGE_SIZE) != 0) {
@@ -122,8 +123,9 @@ blk_write(struct dumperinfo *di, char *ptr, vm_paddr_t pa, size_t sz)
                if (error)
                        return (error);
        }
+       max_iosize = min(MAXPHYS, di->maxiosize);
        while (sz) {
-               len = (MAXDUMPPGS * PAGE_SIZE) - fragsz;
+               len = max_iosize - fragsz;
                if (len > sz)
                        len = sz;
                counter += len;
@@ -148,7 +150,7 @@ blk_write(struct dumperinfo *di, char *ptr, vm_paddr_t pa, size_t sz)
                        fragsz += len;
                        pa += len;
                        sz -= len;
-                       if (fragsz == (MAXDUMPPGS * PAGE_SIZE)) {
+                       if (fragsz == max_iosize) {
                                error = blk_flush(di);
                                if (error)
                                        return (error);
index 9a144e0..dbc52dc 100644 (file)
@@ -158,19 +158,21 @@ cb_dumpdata(struct md_pa *mdp, int seqnr, void *arg)
        uint64_t pgs;
        size_t counter, sz, chunk;
        int i, c, error;
+       int max_iosize;
 
        error = 0;      /* catch case in which chunk size is 0 */
        counter = 0;    /* Update twiddle every 16MB */
        va = NULL;
        pgs = mdp->md_size / PAGE_SIZE;
        pa = mdp->md_start;
+       max_iosize = min(MAXPHYS, di->maxiosize);
 
        kprintf("  chunk %d: %ldMB (%ld pages)", seqnr, PG2MB(pgs), pgs);
 
        while (pgs) {
                chunk = pgs;
-               if (chunk > MAXDUMPPGS)
-                       chunk = MAXDUMPPGS;
+               if (chunk > (max_iosize/PAGE_SIZE))
+                       chunk = max_iosize/PAGE_SIZE;
                sz = chunk << PAGE_SHIFT;
                counter += sz;
                if (counter >> 24) {
index b4f3b2a..12950c6 100644 (file)
@@ -104,6 +104,7 @@ blk_write(struct dumperinfo *di, char *ptr, vm_paddr_t pa, size_t sz)
 {
        size_t len;
        int error, i, c;
+       int max_iosize;
 
        error = 0;
        if ((sz & PAGE_MASK)) {
@@ -127,8 +128,9 @@ blk_write(struct dumperinfo *di, char *ptr, vm_paddr_t pa, size_t sz)
                if (error)
                        return (error);
        }
+       max_iosize = min(MAXPHYS, di->maxiosize);
        while (sz) {
-               len = (MAXDUMPPGS * PAGE_SIZE) - fragsz;
+               len = max_iosize - fragsz;
                if (len > sz)
                        len = sz;
                counter += len;
@@ -155,7 +157,7 @@ blk_write(struct dumperinfo *di, char *ptr, vm_paddr_t pa, size_t sz)
                        fragsz += len;
                        pa += len;
                        sz -= len;
-                       if (fragsz == (MAXDUMPPGS * PAGE_SIZE)) {
+                       if (fragsz == max_iosize) {
                                error = blk_flush(di);
                                if (error)
                                        return (error);