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