- instead of scaning a list when looking up

{a idle thread, a socket with pending requests},
  maintain dedicated list of them.
- add spin locks.
This commit is contained in:
yamt 2003-06-25 14:37:50 +00:00
parent 200e944501
commit 45c519f76f
3 changed files with 114 additions and 43 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: nfs.h,v 1.36 2003/04/24 21:21:04 drochner Exp $ */
/* $NetBSD: nfs.h,v 1.37 2003/06/25 14:37:50 yamt Exp $ */
/*
* Copyright (c) 1989, 1993, 1995
* The Regents of the University of California. All rights reserved.
@ -410,6 +410,7 @@ struct nfsuid {
struct nfssvc_sock {
TAILQ_ENTRY(nfssvc_sock) ns_chain; /* List of all nfssvc_sock's */
TAILQ_ENTRY(nfssvc_sock) ns_pending; /* List of pending sockets */
TAILQ_HEAD(, nfsuid) ns_uidlruhead;
struct file *ns_fp;
struct socket *ns_so;
@ -440,6 +441,7 @@ struct nfssvc_sock {
#define SLP_ALLFLAGS 0xff
extern TAILQ_HEAD(nfssvc_sockhead, nfssvc_sock) nfssvc_sockhead;
extern struct nfssvc_sockhead nfssvc_sockpending;
extern int nfssvc_sockhead_flag;
#define SLP_INIT 0x01
#define SLP_WANTINIT 0x02
@ -449,6 +451,7 @@ extern int nfssvc_sockhead_flag;
*/
struct nfsd {
TAILQ_ENTRY(nfsd) nfsd_chain; /* List of all nfsd's */
SLIST_ENTRY(nfsd) nfsd_idle; /* List of idle nfsd's */
int nfsd_flag; /* NFSD_ flags */
struct nfssvc_sock *nfsd_slp; /* Current socket */
int nfsd_authlen; /* Authenticator len */
@ -505,7 +508,9 @@ struct nfsrv_descript {
#define ND_KERBFULL 0x40
#define ND_KERBAUTH (ND_KERBNICK | ND_KERBFULL)
extern struct simplelock nfsd_slock;
extern TAILQ_HEAD(nfsdhead, nfsd) nfsd_head;
extern SLIST_HEAD(nfsdidlehead, nfsd) nfsd_idle_head;
extern int nfsd_head_flag;
#define NFSD_CHECKSLP 0x01

View File

@ -1,4 +1,4 @@
/* $NetBSD: nfs_socket.c,v 1.89 2003/06/23 11:02:19 martin Exp $ */
/* $NetBSD: nfs_socket.c,v 1.90 2003/06/25 14:37:50 yamt Exp $ */
/*
* Copyright (c) 1989, 1991, 1993, 1995
@ -43,7 +43,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: nfs_socket.c,v 1.89 2003/06/23 11:02:19 martin Exp $");
__KERNEL_RCSID(0, "$NetBSD: nfs_socket.c,v 1.90 2003/06/25 14:37:50 yamt Exp $");
#include "fs_nfs.h"
#include "opt_nfs.h"
@ -2204,18 +2204,28 @@ nfsrv_wakenfsd(slp)
if ((slp->ns_flag & SLP_VALID) == 0)
return;
TAILQ_FOREACH(nd, &nfsd_head, nfsd_chain) {
if (nd->nfsd_flag & NFSD_WAITING) {
nd->nfsd_flag &= ~NFSD_WAITING;
if (nd->nfsd_slp)
panic("nfsd wakeup");
slp->ns_sref++;
nd->nfsd_slp = slp;
wakeup((caddr_t)nd);
return;
}
simple_lock(&nfsd_slock);
if (slp->ns_flag & SLP_DOREC) {
simple_unlock(&nfsd_slock);
return;
}
nd = SLIST_FIRST(&nfsd_idle_head);
if (nd) {
SLIST_REMOVE_HEAD(&nfsd_idle_head, nfsd_idle);
simple_unlock(&nfsd_slock);
KASSERT(nd->nfsd_flag & NFSD_WAITING);
nd->nfsd_flag &= ~NFSD_WAITING;
if (nd->nfsd_slp)
panic("nfsd wakeup");
slp->ns_sref++;
nd->nfsd_slp = slp;
wakeup(nd);
return;
}
slp->ns_flag |= SLP_DOREC;
nfsd_head_flag |= NFSD_CHECKSLP;
TAILQ_INSERT_TAIL(&nfssvc_sockpending, slp, ns_pending);
simple_unlock(&nfsd_slock);
}
#endif /* NFSSERVER */

View File

@ -1,4 +1,4 @@
/* $NetBSD: nfs_syscalls.c,v 1.65 2003/05/26 13:30:07 yamt Exp $ */
/* $NetBSD: nfs_syscalls.c,v 1.66 2003/06/25 14:37:50 yamt Exp $ */
/*
* Copyright (c) 1989, 1993
@ -39,7 +39,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: nfs_syscalls.c,v 1.65 2003/05/26 13:30:07 yamt Exp $");
__KERNEL_RCSID(0, "$NetBSD: nfs_syscalls.c,v 1.66 2003/06/25 14:37:50 yamt Exp $");
#include "fs_nfs.h"
#include "opt_nfs.h"
@ -113,11 +113,16 @@ static int modify_flag = 0;
static struct nfsdrt nfsdrt;
#endif
#ifdef NFSSERVER
struct simplelock nfsd_slock = SIMPLELOCK_INITIALIZER;
struct nfssvc_sockhead nfssvc_sockhead;
struct nfssvc_sockhead nfssvc_sockpending;
struct nfsdhead nfsd_head;
struct nfsdidlehead nfsd_idle_head;
int nfssvc_sockhead_flag;
int nfsd_head_flag;
#endif
MALLOC_DEFINE(M_NFSUID, "NFS uid", "Nfs uid mapping structure");
@ -155,6 +160,7 @@ sys_nfssvc(l, v, retval)
} */ *uap = v;
struct proc *p = l->l_proc;
int error;
int s;
#ifdef NFS
struct nameidata nd;
struct nfsmount *nmp;
@ -176,10 +182,15 @@ sys_nfssvc(l, v, retval)
error = suser(p->p_ucred, &p->p_acflag);
if(error)
return (error);
s = splsoftnet();
simple_lock(&nfsd_slock);
while (nfssvc_sockhead_flag & SLP_INIT) {
nfssvc_sockhead_flag |= SLP_WANTINIT;
(void) tsleep((caddr_t)&nfssvc_sockhead, PSOCK, "nfsd init", 0);
(void) ltsleep(&nfssvc_sockhead, PSOCK, "nfsd init", 0,
&nfsd_slock);
}
simple_unlock(&nfsd_slock);
splx(s);
if (SCARG(uap, flag) & NFSSVC_BIOD) {
#if defined(NFS) && defined(COMPAT_14)
error = nfssvc_iod(l);
@ -351,12 +362,17 @@ static struct nfssvc_sock *
nfsrv_sockalloc()
{
struct nfssvc_sock *slp;
int s;
slp = (struct nfssvc_sock *)
malloc(sizeof (struct nfssvc_sock), M_NFSSVC, M_WAITOK);
memset(slp, 0, sizeof (struct nfssvc_sock));
TAILQ_INIT(&slp->ns_uidlruhead);
s = splsoftnet();
simple_lock(&nfsd_slock);
TAILQ_INSERT_TAIL(&nfssvc_sockhead, slp, ns_chain);
simple_unlock(&nfsd_slock);
splx(s);
return slp;
}
@ -490,8 +506,10 @@ nfssvc_nfsd(nsd, argp, l)
malloc(sizeof (struct nfsd), M_NFSD, M_WAITOK);
memset((caddr_t)nfsd, 0, sizeof (struct nfsd));
nfsd->nfsd_procp = p;
simple_lock(&nfsd_slock);
TAILQ_INSERT_TAIL(&nfsd_head, nfsd, nfsd_chain);
nfs_numnfsd++;
simple_unlock(&nfsd_slock);
}
PHOLD(l);
/*
@ -499,31 +517,46 @@ nfssvc_nfsd(nsd, argp, l)
*/
for (;;) {
if ((nfsd->nfsd_flag & NFSD_REQINPROG) == 0) {
simple_lock(&nfsd_slock);
while (nfsd->nfsd_slp == (struct nfssvc_sock *)0 &&
(nfsd_head_flag & NFSD_CHECKSLP) == 0) {
SLIST_INSERT_HEAD(&nfsd_idle_head, nfsd,
nfsd_idle);
nfsd->nfsd_flag |= NFSD_WAITING;
nfsd_waiting++;
error = tsleep((caddr_t)nfsd, PSOCK | PCATCH,
"nfsd", 0);
error = ltsleep(nfsd, PSOCK | PCATCH, "nfsd",
0, &nfsd_slock);
nfsd_waiting--;
if (error)
if (error) {
slp = nfsd->nfsd_slp;
nfsd->nfsd_slp = NULL;
if (!slp)
SLIST_REMOVE(&nfsd_idle_head,
nfsd, nfsd, nfsd_idle);
simple_unlock(&nfsd_slock);
if (slp) {
nfsrv_wakenfsd(slp);
nfsrv_slpderef(slp);
}
goto done;
}
}
if (nfsd->nfsd_slp == (struct nfssvc_sock *)0 &&
(nfsd_head_flag & NFSD_CHECKSLP) != 0) {
TAILQ_FOREACH(slp, &nfssvc_sockhead, ns_chain) {
if ((slp->ns_flag &
slp = TAILQ_FIRST(&nfssvc_sockpending);
if (slp) {
KASSERT((slp->ns_flag &
(SLP_VALID | SLP_DOREC))
== (SLP_VALID | SLP_DOREC)) {
slp->ns_flag &= ~SLP_DOREC;
slp->ns_sref++;
nfsd->nfsd_slp = slp;
break;
}
}
if (slp == 0)
== (SLP_VALID | SLP_DOREC));
TAILQ_REMOVE(&nfssvc_sockpending, slp,
ns_pending);
slp->ns_flag &= ~SLP_DOREC;
slp->ns_sref++;
nfsd->nfsd_slp = slp;
} else
nfsd_head_flag &= ~NFSD_CHECKSLP;
}
simple_unlock(&nfsd_slock);
if ((slp = nfsd->nfsd_slp) == (struct nfssvc_sock *)0)
continue;
if (slp->ns_flag & SLP_VALID) {
@ -777,7 +810,9 @@ nfssvc_nfsd(nsd, argp, l)
}
done:
PRELE(l);
simple_lock(&nfsd_slock);
TAILQ_REMOVE(&nfsd_head, nfsd, nfsd_chain);
simple_unlock(&nfsd_slock);
splx(s);
free((caddr_t)nfsd, M_NFSD);
nsd->nsd_nfsd = (struct nfsd *)0;
@ -847,9 +882,15 @@ void
nfsrv_slpderef(slp)
struct nfssvc_sock *slp;
{
LOCK_ASSERT(!simple_lock_held(&nfsd_slock));
if (--(slp->ns_sref) == 0 && (slp->ns_flag & SLP_VALID) == 0) {
int s = splsoftnet();
simple_lock(&nfsd_slock);
TAILQ_REMOVE(&nfssvc_sockhead, slp, ns_chain);
free((caddr_t)slp, M_NFSSVC);
simple_unlock(&nfsd_slock);
splx(s);
free(slp, M_NFSSVC);
}
}
@ -862,32 +903,39 @@ void
nfsrv_init(terminating)
int terminating;
{
struct nfssvc_sock *slp, *nslp;
struct nfssvc_sock *slp;
int s;
s = splsoftnet();
simple_lock(&nfsd_slock);
if (nfssvc_sockhead_flag & SLP_INIT)
panic("nfsd init");
nfssvc_sockhead_flag |= SLP_INIT;
if (terminating) {
for (slp = TAILQ_FIRST(&nfssvc_sockhead); slp != 0;
slp = nslp) {
nslp = TAILQ_NEXT(slp, ns_chain);
while ((slp = TAILQ_FIRST(&nfssvc_sockhead)) != NULL) {
TAILQ_REMOVE(&nfssvc_sockhead, slp, ns_chain);
simple_unlock(&nfsd_slock);
if (slp->ns_flag & SLP_VALID)
nfsrv_zapsock(slp);
TAILQ_REMOVE(&nfssvc_sockhead, slp, ns_chain);
free((caddr_t)slp, M_NFSSVC);
free(slp, M_NFSSVC);
simple_lock(&nfsd_slock);
}
simple_unlock(&nfsd_slock);
splx(s);
nfsrv_cleancache(); /* And clear out server cache */
} else
} else {
simple_unlock(&nfsd_slock);
splx(s);
nfs_pub.np_valid = 0;
TAILQ_INIT(&nfssvc_sockhead);
nfssvc_sockhead_flag &= ~SLP_INIT;
if (nfssvc_sockhead_flag & SLP_WANTINIT) {
nfssvc_sockhead_flag &= ~SLP_WANTINIT;
wakeup((caddr_t)&nfssvc_sockhead);
}
TAILQ_INIT(&nfssvc_sockhead);
TAILQ_INIT(&nfssvc_sockpending);
nfssvc_sockhead_flag &= ~SLP_INIT;
TAILQ_INIT(&nfsd_head);
SLIST_INIT(&nfsd_idle_head);
nfsd_head_flag &= ~NFSD_CHECKSLP;
nfs_udpsock = nfsrv_sockalloc();
@ -899,6 +947,14 @@ nfsrv_init(terminating)
#ifdef ISO
nfs_cltpsock = nfsrv_sockalloc();
#endif
simple_lock(&nfsd_slock);
if (nfssvc_sockhead_flag & SLP_WANTINIT) {
nfssvc_sockhead_flag &= ~SLP_WANTINIT;
wakeup(&nfssvc_sockhead);
}
simple_unlock(&nfsd_slock);
splx(s);
}
/*