Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/miscfs/fdesc Use a kmutex to protect the hash chains and...
details: https://anonhg.NetBSD.org/src/rev/d6db1d5b0047
branches: trunk
changeset: 756394:d6db1d5b0047
user: hannken <hannken%NetBSD.org@localhost>
date: Fri Jul 16 10:41:12 2010 +0000
description:
Use a kmutex to protect the hash chains and always take this mutex
before removing a node from the hash chain.
Release the hash list lock before calling getnewvnode() and check the
hash list again like other file systems do.
Take v_interlock before calling vget().
diffstat:
sys/miscfs/fdesc/fdesc_vnops.c | 64 +++++++++++++++++++++--------------------
1 files changed, 33 insertions(+), 31 deletions(-)
diffs (130 lines):
diff -r 3e7a47526880 -r d6db1d5b0047 sys/miscfs/fdesc/fdesc_vnops.c
--- a/sys/miscfs/fdesc/fdesc_vnops.c Fri Jul 16 08:23:28 2010 +0000
+++ b/sys/miscfs/fdesc/fdesc_vnops.c Fri Jul 16 10:41:12 2010 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: fdesc_vnops.c,v 1.110 2010/06/24 13:03:12 hannken Exp $ */
+/* $NetBSD: fdesc_vnops.c,v 1.111 2010/07/16 10:41:12 hannken Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -41,7 +41,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: fdesc_vnops.c,v 1.110 2010/06/24 13:03:12 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: fdesc_vnops.c,v 1.111 2010/07/16 10:41:12 hannken Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -69,9 +69,7 @@
#define cttyvp(p) ((p)->p_lflag & PL_CONTROLT ? (p)->p_session->s_ttyvp : NULL)
-#define FDL_WANT 0x01
-#define FDL_LOCKED 0x02
-static int fdcache_lock;
+static kmutex_t fdcache_lock;
dev_t devctty;
@@ -187,6 +185,7 @@
/* locate the major number */
cttymajor = devsw_name2chr("ctty", NULL, 0);
devctty = makedev(cttymajor, 0);
+ mutex_init(&fdcache_lock, MUTEX_DEFAULT, IPL_NONE);
fdhashtbl = hashinit(NFDCACHE, HASH_LIST, true, &fdhash);
}
@@ -197,6 +196,7 @@
fdesc_done(void)
{
hashdone(fdhashtbl, HASH_LIST, fdhash);
+ mutex_destroy(&fdcache_lock);
}
/*
@@ -211,29 +211,36 @@
fc = FD_NHASH(ix);
loop:
- for (fd = fc->lh_first; fd != 0; fd = fd->fd_hash.le_next) {
+ mutex_enter(&fdcache_lock);
+ LIST_FOREACH(fd, fc, fd_hash) {
if (fd->fd_ix == ix && fd->fd_vnode->v_mount == mp) {
- if (vget(fd->fd_vnode, LK_EXCLUSIVE))
+ mutex_enter(&fd->fd_vnode->v_interlock);
+ mutex_exit(&fdcache_lock);
+ if (vget(fd->fd_vnode, LK_INTERLOCK | LK_EXCLUSIVE))
goto loop;
*vpp = fd->fd_vnode;
- return (error);
+ return 0;
+ }
+ }
+ mutex_exit(&fdcache_lock);
+
+ error = getnewvnode(VT_FDESC, mp, fdesc_vnodeop_p, vpp);
+ if (error)
+ return error;
+
+ mutex_enter(&fdcache_lock);
+ LIST_FOREACH(fd, fc, fd_hash) {
+ if (fd->fd_ix == ix && fd->fd_vnode->v_mount == mp) {
+ /*
+ * Another thread beat us, push back freshly
+ * allocated vnode and retry.
+ */
+ mutex_exit(&fdcache_lock);
+ ungetnewvnode(*vpp);
+ goto loop;
}
}
- /*
- * otherwise lock the array while we call getnewvnode
- * since that can block.
- */
- if (fdcache_lock & FDL_LOCKED) {
- fdcache_lock |= FDL_WANT;
- (void) tsleep(&fdcache_lock, PINOD, "fdcache", 0);
- goto loop;
- }
- fdcache_lock |= FDL_LOCKED;
-
- error = getnewvnode(VT_FDESC, mp, fdesc_vnodeop_p, vpp);
- if (error)
- goto out;
fd = malloc(sizeof(struct fdescnode), M_TEMP, M_WAITOK);
(*vpp)->v_data = fd;
fd->fd_vnode = *vpp;
@@ -244,16 +251,9 @@
uvm_vnp_setsize(*vpp, 0);
VOP_LOCK(*vpp, LK_EXCLUSIVE);
LIST_INSERT_HEAD(fc, fd, fd_hash);
-
-out:;
- fdcache_lock &= ~FDL_LOCKED;
+ mutex_exit(&fdcache_lock);
- if (fdcache_lock & FDL_WANT) {
- fdcache_lock &= ~FDL_WANT;
- wakeup(&fdcache_lock);
- }
-
- return (error);
+ return 0;
}
/*
@@ -956,9 +956,11 @@
struct vnode *vp = ap->a_vp;
struct fdescnode *fd = VTOFDESC(vp);
+ mutex_enter(&fdcache_lock);
LIST_REMOVE(fd, fd_hash);
free(vp->v_data, M_TEMP);
vp->v_data = 0;
+ mutex_exit(&fdcache_lock);
return (0);
}
Home |
Main Index |
Thread Index |
Old Index