Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/rump/librump/rumpvfs Make the pager loops more resilient...



details:   https://anonhg.NetBSD.org/src/rev/8816eddcf794
branches:  trunk
changeset: 757596:8816eddcf794
user:      pooka <pooka%NetBSD.org@localhost>
date:      Mon Sep 06 21:33:07 2010 +0000

description:
Make the pager loops more resilient against the aobj pager which is
lazy and doesn't like to return anything except the bare minimum.
(forgot to commit this earlier)

diffstat:

 sys/rump/librump/rumpvfs/vm_vfs.c |  30 +++++++++++++++++++++---------
 1 files changed, 21 insertions(+), 9 deletions(-)

diffs (94 lines):

diff -r 72fc4ca8667a -r 8816eddcf794 sys/rump/librump/rumpvfs/vm_vfs.c
--- a/sys/rump/librump/rumpvfs/vm_vfs.c Mon Sep 06 20:33:18 2010 +0000
+++ b/sys/rump/librump/rumpvfs/vm_vfs.c Mon Sep 06 21:33:07 2010 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: vm_vfs.c,v 1.19 2010/09/06 17:56:56 pooka Exp $        */
+/*     $NetBSD: vm_vfs.c,v 1.20 2010/09/06 21:33:07 pooka Exp $        */
 
 /*
  * Copyright (c) 2008 Antti Kantee.  All Rights Reserved.
@@ -29,7 +29,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vm_vfs.c,v 1.19 2010/09/06 17:56:56 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vm_vfs.c,v 1.20 2010/09/06 21:33:07 pooka Exp $");
 
 #include <sys/param.h>
 
@@ -102,7 +102,7 @@
        if (maxpages == 0)
                return;
 
-       pgs = kmem_zalloc(maxpages * sizeof(pgs), KM_SLEEP);
+       pgs = kmem_alloc(maxpages * sizeof(pgs), KM_SLEEP);
        while (len) {
                npages = MIN(maxpages, round_page(len) >> PAGE_SHIFT);
                memset(pgs, 0, npages * sizeof(struct vm_page *));
@@ -113,15 +113,20 @@
                KASSERT(npages > 0);
 
                for (i = 0; i < npages; i++) {
+                       struct vm_page *pg;
                        uint8_t *start;
                        size_t chunkoff, chunklen;
 
+                       pg = pgs[i];
+                       if (pg == NULL)
+                               break;
+
                        chunkoff = off & PAGE_MASK;
                        chunklen = MIN(PAGE_SIZE - chunkoff, len);
-                       start = (uint8_t *)pgs[i]->uanon + chunkoff;
+                       start = (uint8_t *)pg->uanon + chunkoff;
 
                        memset(start, 0, chunklen);
-                       pgs[i]->flags &= ~PG_CLEAN;
+                       pg->flags &= ~PG_CLEAN;
 
                        off += chunklen;
                        len -= chunklen;
@@ -146,7 +151,7 @@
        int i, rv, pagerflags;
 
        pgalloc = npages * sizeof(pgs);
-       pgs = kmem_zalloc(pgalloc, KM_SLEEP);
+       pgs = kmem_alloc(pgalloc, KM_SLEEP);
 
        pagerflags = PAGERFLAGS;
        if (flags & UBC_WRITE)
@@ -155,24 +160,31 @@
                pagerflags |= PGO_OVERWRITE;
 
        do {
+               npages = len2npages(uio->uio_offset, todo);
+               memset(pgs, 0, pgalloc);
                mutex_enter(&uobj->vmobjlock);
-               rv = uobj->pgops->pgo_get(uobj, uio->uio_offset & ~PAGE_MASK,
+               rv = uobj->pgops->pgo_get(uobj, trunc_page(uio->uio_offset),
                    pgs, &npages, 0, VM_PROT_READ | VM_PROT_WRITE, 0,
                    pagerflags);
                if (rv)
                        goto out;
 
                for (i = 0; i < npages; i++) {
+                       struct vm_page *pg;
                        size_t xfersize;
                        off_t pageoff;
 
+                       pg = pgs[i];
+                       if (pg == NULL)
+                               break;
+
                        pageoff = uio->uio_offset & PAGE_MASK;
                        xfersize = MIN(MIN(todo, PAGE_SIZE), PAGE_SIZE-pageoff);
                        KASSERT(xfersize > 0);
-                       uiomove((uint8_t *)pgs[i]->uanon + pageoff,
+                       uiomove((uint8_t *)pg->uanon + pageoff,
                            xfersize, uio);
                        if (uio->uio_rw == UIO_WRITE)
-                               pgs[i]->flags &= ~(PG_CLEAN | PG_FAKE);
+                               pg->flags &= ~(PG_CLEAN | PG_FAKE);
                        todo -= xfersize;
                }
                uvm_page_unbusy(pgs, npages);



Home | Main Index | Thread Index | Old Index