summaryrefslogtreecommitdiffstats
path: root/sys/kern/vfs_cache.c
diff options
context:
space:
mode:
authortedu <tedu@openbsd.org>2008-10-23 23:54:02 +0000
committertedu <tedu@openbsd.org>2008-10-23 23:54:02 +0000
commit898645e14acc973b87fd535901c33d1c0630b0a3 (patch)
tree1faca18e41b1a0575cd15fe19a26db2d46ace900 /sys/kern/vfs_cache.c
parentarc(4) also supports SAS adapters. (diff)
downloadwireguard-openbsd-898645e14acc973b87fd535901c33d1c0630b0a3.tar.xz
wireguard-openbsd-898645e14acc973b87fd535901c33d1c0630b0a3.zip
a better fix for the "uvm_km thread runs out of memory" problem.
add a new arg to the backend so it can tell pool to slow down. when we get this flag, yield *after* putting the page in the pool's free list. whatever we do, don't let the thread sleep. this makes things better by still letting the thread run when a huge pf request comes in, but without artificially increasing pressure on the backend by eating pages without feeding them forward. ok deraadt
Diffstat (limited to 'sys/kern/vfs_cache.c')
-rw-r--r--sys/kern/vfs_cache.c18
1 files changed, 10 insertions, 8 deletions
diff --git a/sys/kern/vfs_cache.c b/sys/kern/vfs_cache.c
index 9356cb32039..41b8263819d 100644
--- a/sys/kern/vfs_cache.c
+++ b/sys/kern/vfs_cache.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vfs_cache.c,v 1.27 2008/10/20 20:33:07 deraadt Exp $ */
+/* $OpenBSD: vfs_cache.c,v 1.28 2008/10/23 23:54:02 tedu Exp $ */
/* $NetBSD: vfs_cache.c,v 1.13 1996/02/04 02:18:09 christos Exp $ */
/*
@@ -162,6 +162,9 @@ cache_lookup(struct vnode *dvp, struct vnode **vpp, struct componentname *cnp)
goto remove;
}
+ /* remove from lru now to prevent races */
+ TAILQ_REMOVE(&nclruhead, ncp, nc_lru);
+
vp = ncp->nc_vp;
vpid = vp->v_id;
if (vp == dvp) { /* lookup on "." */
@@ -178,6 +181,8 @@ cache_lookup(struct vnode *dvp, struct vnode **vpp, struct componentname *cnp)
if (!error && (~cnp->cn_flags & (LOCKPARENT|ISLASTCN)) == 0) {
if ((error = vn_lock(dvp, LK_EXCLUSIVE, p)) != 0) {
vput(vp);
+ /* parent has permanent issues; recycle */
+ TAILQ_INSERT_HEAD(&nclruhead, ncp, nc_lru);
return (error);
}
cnp->cn_flags &= ~PDIRUNLOCK;
@@ -204,6 +209,8 @@ cache_lookup(struct vnode *dvp, struct vnode **vpp, struct componentname *cnp)
nchstats.ncs_falsehits++;
} else
nchstats.ncs_badhits++;
+ /* cache entry is stale; recycle */
+ TAILQ_INSERT_HEAD(&nclruhead, ncp, nc_lru);
/*
* The parent needs to be locked when we return to VOP_LOOKUP().
* The `.' case here should be extremely rare (if it can happen
@@ -219,13 +226,8 @@ cache_lookup(struct vnode *dvp, struct vnode **vpp, struct componentname *cnp)
}
nchstats.ncs_goodhits++;
- /*
- * Move this slot to end of LRU chain, if not already there.
- */
- if (TAILQ_NEXT(ncp, nc_lru) != NULL) {
- TAILQ_REMOVE(&nclruhead, ncp, nc_lru);
- TAILQ_INSERT_TAIL(&nclruhead, ncp, nc_lru);
- }
+ /* cache entry is valid; keep it */
+ TAILQ_INSERT_TAIL(&nclruhead, ncp, nc_lru);
*vpp = vp;
return (0);