Source-Changes-HG archive

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

[src/trunk]: src/sys/miscfs/genfs fix two problems:



details:   https://anonhg.NetBSD.org/src/rev/a85518c55d59
branches:  trunk
changeset: 522454:a85518c55d59
user:      chs <chs%NetBSD.org@localhost>
date:      Tue Feb 19 15:49:39 2002 +0000

description:
fix two problems:
 - when yielding the cpu while using the vnode's page list, use a marker page
   to keep our place in the list (like the other cases where we drop the lock).
 - wait until no one else has the page busy before deciding if the page needs
   to be cleaned.  a page will be dirty while it's being initialized but will
   be marked clean before PG_BUSY is cleared.
both found by enami.

diffstat:

 sys/miscfs/genfs/genfs_vnops.c |  69 +++++++++++++++++++++++------------------
 1 files changed, 38 insertions(+), 31 deletions(-)

diffs (111 lines):

diff -r 048ef7e3ac94 -r a85518c55d59 sys/miscfs/genfs/genfs_vnops.c
--- a/sys/miscfs/genfs/genfs_vnops.c    Tue Feb 19 15:03:33 2002 +0000
+++ b/sys/miscfs/genfs/genfs_vnops.c    Tue Feb 19 15:49:39 2002 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: genfs_vnops.c,v 1.48 2002/02/13 05:20:41 enami Exp $   */
+/*     $NetBSD: genfs_vnops.c,v 1.49 2002/02/19 15:49:39 chs Exp $     */
 
 /*
  * Copyright (c) 1982, 1986, 1989, 1993
@@ -35,7 +35,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: genfs_vnops.c,v 1.48 2002/02/13 05:20:41 enami Exp $");
+__KERNEL_RCSID(0, "$NetBSD: genfs_vnops.c,v 1.49 2002/02/19 15:49:39 chs Exp $");
 
 #include "opt_nfsserver.h"
 
@@ -1013,7 +1013,7 @@
        int i, s, error, npages, nback;
        int freeflag;
        struct vm_page *pgs[n], *pg, *nextpg, *tpg, curmp, endmp;
-       boolean_t wasclean, by_list, needs_clean;
+       boolean_t wasclean, by_list, needs_clean, yield;
        boolean_t async = (flags & PGO_SYNCIO) == 0;
        UVMHIST_FUNC("genfs_putpages"); UVMHIST_CALLED(ubchist);
 
@@ -1071,12 +1071,6 @@
        }
        nextpg = NULL;
        while (by_list || off < endoff) {
-               if (curproc->p_cpu->ci_schedstate.spc_flags &
-                   SPCF_SHOULDYIELD) {
-                       simple_unlock(slock);
-                       preempt(NULL);
-                       simple_lock(slock);
-               }
 
                /*
                 * if the current page is not interesting, move on to the next.
@@ -1109,6 +1103,41 @@
                 * wait for it to become unbusy.
                 */
 
+               yield = curproc->p_cpu->ci_schedstate.spc_flags &
+                   SPCF_SHOULDYIELD;
+               if (pg->flags & PG_BUSY || yield) {
+                       KASSERT(curproc != uvm.pagedaemon_proc);
+                       UVMHIST_LOG(ubchist, "busy %p", pg,0,0,0);
+                       if (by_list) {
+                               TAILQ_INSERT_BEFORE(pg, &curmp, listq);
+                               UVMHIST_LOG(ubchist, "curmp next %p",
+                                           TAILQ_NEXT(&curmp, listq), 0,0,0);
+                       }
+                       if (yield) {
+                               simple_unlock(slock);
+                               preempt(NULL);
+                               simple_lock(slock);
+                       } else {
+                               pg->flags |= PG_WANTED;
+                               UVM_UNLOCK_AND_WAIT(pg, slock, 0, "genput", 0);
+                               simple_lock(slock);
+                       }
+                       if (by_list) {
+                               UVMHIST_LOG(ubchist, "after next %p",
+                                           TAILQ_NEXT(&curmp, listq), 0,0,0);
+                               pg = TAILQ_NEXT(&curmp, listq);
+                               TAILQ_REMOVE(&uobj->memq, &curmp, listq);
+                       } else {
+                               pg = uvm_pagelookup(uobj, off);
+                       }
+                       continue;
+               }
+
+               /*
+                * if we're freeing, remove all mappings of the page now.
+                * if we're cleaning, check if the page is needs to be cleaned.
+                */
+
                if (flags & PGO_FREE) {
                        pmap_page_protect(pg, VM_PROT_NONE);
                }
@@ -1119,28 +1148,6 @@
                } else {
                        needs_clean = FALSE;
                }
-               if (needs_clean && pg->flags & PG_BUSY) {
-                       KASSERT(curproc != uvm.pagedaemon_proc);
-                       UVMHIST_LOG(ubchist, "busy %p", pg,0,0,0);
-                       if (by_list) {
-                               TAILQ_INSERT_BEFORE(pg, &curmp, listq);
-                               UVMHIST_LOG(ubchist, "curmp next %p",
-                                           TAILQ_NEXT(&curmp, listq), 0,0,0);
-                       }
-                       pg->flags |= PG_WANTED;
-                       pg->flags &= ~PG_CLEAN;
-                       UVM_UNLOCK_AND_WAIT(pg, slock, 0, "genput", 0);
-                       simple_lock(slock);
-                       if (by_list) {
-                               UVMHIST_LOG(ubchist, "after next %p",
-                                           TAILQ_NEXT(&curmp, listq), 0,0,0);
-                               pg = TAILQ_NEXT(&curmp, listq);
-                               TAILQ_REMOVE(&uobj->memq, &curmp, listq);
-                       } else {
-                               pg = uvm_pagelookup(uobj, off);
-                       }
-                       continue;
-               }
 
                /*
                 * if we're cleaning, build a cluster.



Home | Main Index | Thread Index | Old Index