nfssvc_nfsd: reduce a chance for a slow peer to capture all our threads.
instead of sleeping to wait for the socket to send our reply, just hand-off our reply to the thread which is holding the socket.
This commit is contained in:
parent
a5da6cae5b
commit
7416ebb551
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: nfs.h,v 1.53 2006/01/03 11:41:03 yamt Exp $ */
|
||||
/* $NetBSD: nfs.h,v 1.54 2006/01/03 12:30:01 yamt Exp $ */
|
||||
/*
|
||||
* Copyright (c) 1989, 1993, 1995
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
@ -444,6 +444,7 @@ struct nfssvc_sock {
|
||||
int ns_reclen;
|
||||
int ns_numuids;
|
||||
u_int32_t ns_sref;
|
||||
SIMPLEQ_HEAD(, nfsrv_descript) ns_sendq; /* send reply list */
|
||||
LIST_HEAD(, nfsrv_descript) ns_tq; /* Write gather lists */
|
||||
LIST_HEAD(, nfsuid) ns_uidhashtbl[NFS_UIDHASHSIZ];
|
||||
LIST_HEAD(nfsrvw_delayhash, nfsrv_descript) ns_wdelayhashtbl[NFS_WDELAYHASHSIZ];
|
||||
@ -457,6 +458,7 @@ struct nfssvc_sock {
|
||||
#define SLP_BUSY 0x10
|
||||
#define SLP_WANT 0x20
|
||||
#define SLP_LASTFRAG 0x40
|
||||
#define SLP_SENDING 0x80
|
||||
|
||||
extern TAILQ_HEAD(nfssvc_sockhead, nfssvc_sock) nfssvc_sockhead;
|
||||
extern struct nfssvc_sockhead nfssvc_sockpending;
|
||||
@ -467,6 +469,7 @@ extern int nfssvc_sockhead_flag;
|
||||
int nfsdsock_lock(struct nfssvc_sock *, boolean_t);
|
||||
void nfsdsock_unlock(struct nfssvc_sock *);
|
||||
int nfsdsock_drain(struct nfssvc_sock *);
|
||||
int nfsdsock_sendreply(struct nfssvc_sock *, struct nfsrv_descript *);
|
||||
|
||||
/*
|
||||
* One of these structures is allocated for each nfsd.
|
||||
@ -499,6 +502,7 @@ struct nfsrv_descript {
|
||||
LIST_ENTRY(nfsrv_descript) nd_hash; /* Hash list */
|
||||
LIST_ENTRY(nfsrv_descript) nd_tq; /* and timer list */
|
||||
LIST_HEAD(,nfsrv_descript) nd_coalesce; /* coalesced writes */
|
||||
SIMPLEQ_ENTRY(nfsrv_descript) nd_sendq; /* send reply list */
|
||||
struct mbuf *nd_mrep; /* Request mbuf list */
|
||||
struct mbuf *nd_md; /* Current dissect mbuf */
|
||||
struct mbuf *nd_mreq; /* Reply mbuf list */
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: nfs_socket.c,v 1.121 2006/01/03 11:41:03 yamt Exp $ */
|
||||
/* $NetBSD: nfs_socket.c,v 1.122 2006/01/03 12:30:01 yamt Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1989, 1991, 1993, 1995
|
||||
@ -39,7 +39,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: nfs_socket.c,v 1.121 2006/01/03 11:41:03 yamt Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: nfs_socket.c,v 1.122 2006/01/03 12:30:01 yamt Exp $");
|
||||
|
||||
#include "fs_nfs.h"
|
||||
#include "opt_nfs.h"
|
||||
@ -2562,4 +2562,45 @@ nfsrv_wakenfsd(slp)
|
||||
TAILQ_INSERT_TAIL(&nfssvc_sockpending, slp, ns_pending);
|
||||
simple_unlock(&nfsd_slock);
|
||||
}
|
||||
|
||||
int
|
||||
nfsdsock_sendreply(struct nfssvc_sock *slp, struct nfsrv_descript *nd)
|
||||
{
|
||||
int error;
|
||||
|
||||
if (nd->nd_mrep != NULL) {
|
||||
m_freem(nd->nd_mrep);
|
||||
nd->nd_mrep = NULL;
|
||||
}
|
||||
|
||||
simple_lock(&slp->ns_lock);
|
||||
if ((slp->ns_flag & SLP_SENDING) != 0) {
|
||||
SIMPLEQ_INSERT_TAIL(&slp->ns_sendq, nd, nd_sendq);
|
||||
simple_unlock(&slp->ns_lock);
|
||||
return 0;
|
||||
}
|
||||
KASSERT(SIMPLEQ_EMPTY(&slp->ns_sendq));
|
||||
slp->ns_flag |= SLP_SENDING;
|
||||
simple_unlock(&slp->ns_lock);
|
||||
|
||||
again:
|
||||
error = nfs_send(slp->ns_so, nd->nd_nam2, nd->nd_mreq, NULL, curlwp);
|
||||
if (nd->nd_nam2) {
|
||||
m_free(nd->nd_nam2);
|
||||
}
|
||||
pool_put(&nfs_srvdesc_pool, nd);
|
||||
|
||||
simple_lock(&slp->ns_lock);
|
||||
KASSERT((slp->ns_flag & SLP_SENDING) != 0);
|
||||
nd = SIMPLEQ_FIRST(&slp->ns_sendq);
|
||||
if (nd != NULL) {
|
||||
SIMPLEQ_REMOVE_HEAD(&slp->ns_sendq, nd_sendq);
|
||||
simple_unlock(&slp->ns_lock);
|
||||
goto again;
|
||||
}
|
||||
slp->ns_flag &= ~SLP_SENDING;
|
||||
simple_unlock(&slp->ns_lock);
|
||||
|
||||
return error;
|
||||
}
|
||||
#endif /* NFSSERVER */
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: nfs_syscalls.c,v 1.85 2006/01/03 11:41:03 yamt Exp $ */
|
||||
/* $NetBSD: nfs_syscalls.c,v 1.86 2006/01/03 12:30:01 yamt Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1989, 1993
|
||||
@ -35,7 +35,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: nfs_syscalls.c,v 1.85 2006/01/03 11:41:03 yamt Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: nfs_syscalls.c,v 1.86 2006/01/03 12:30:01 yamt Exp $");
|
||||
|
||||
#include "fs_nfs.h"
|
||||
#include "opt_nfs.h"
|
||||
@ -128,9 +128,9 @@ int nfs_niothreads = -1; /* == "0, and has never been set" */
|
||||
#endif
|
||||
|
||||
#ifdef NFSSERVER
|
||||
static void nfsd_rt __P((int, struct nfsrv_descript *, int));
|
||||
static struct nfssvc_sock *nfsrv_sockalloc __P((void));
|
||||
static void nfsrv_sockfree __P((struct nfssvc_sock *));
|
||||
static void nfsd_rt __P((int, struct nfsrv_descript *, int));
|
||||
#endif
|
||||
|
||||
/*
|
||||
@ -397,6 +397,8 @@ nfsrv_sockalloc()
|
||||
memset(slp, 0, sizeof (struct nfssvc_sock));
|
||||
simple_lock_init(&slp->ns_lock);
|
||||
TAILQ_INIT(&slp->ns_uidlruhead);
|
||||
LIST_INIT(&slp->ns_tq);
|
||||
SIMPLEQ_INIT(&slp->ns_sendq);
|
||||
s = splsoftnet();
|
||||
simple_lock(&nfsd_slock);
|
||||
TAILQ_INSERT_TAIL(&nfssvc_sockhead, slp, ns_chain);
|
||||
@ -526,8 +528,6 @@ nfssvc_nfsd(nsd, argp, l)
|
||||
struct mbuf *m;
|
||||
int siz;
|
||||
struct nfssvc_sock *slp;
|
||||
struct socket *so;
|
||||
int *solockp;
|
||||
struct nfsd *nfsd = nsd->nsd_nfsd;
|
||||
struct nfsrv_descript *nd = NULL;
|
||||
struct mbuf *mreq;
|
||||
@ -633,12 +633,7 @@ nfssvc_nfsd(nsd, argp, l)
|
||||
continue;
|
||||
}
|
||||
splx(s);
|
||||
so = slp->ns_so;
|
||||
sotype = so->so_type;
|
||||
if (so->so_proto->pr_flags & PR_CONNREQUIRED)
|
||||
solockp = &slp->ns_solock;
|
||||
else
|
||||
solockp = NULL;
|
||||
sotype = slp->ns_so->so_type;
|
||||
if (nd) {
|
||||
nd->nd_starttime = time;
|
||||
if (nd->nd_nam2)
|
||||
@ -791,27 +786,16 @@ nfssvc_nfsd(nsd, argp, l)
|
||||
*mtod(m, u_int32_t *) =
|
||||
htonl(0x80000000 | siz);
|
||||
}
|
||||
if (solockp)
|
||||
nfs_sndlock(solockp, NULL);
|
||||
if (slp->ns_flag & SLP_VALID) {
|
||||
error = nfs_send(so, nd->nd_nam2,
|
||||
m, NULL, l);
|
||||
} else {
|
||||
error = EPIPE;
|
||||
m_freem(m);
|
||||
nd->nd_mreq = m;
|
||||
if (nfsrtton) {
|
||||
nfsd_rt(slp->ns_so->so_type, nd,
|
||||
cacherep);
|
||||
}
|
||||
if (solockp)
|
||||
nfs_sndunlock(solockp);
|
||||
if (nfsrtton)
|
||||
nfsd_rt(sotype, nd, cacherep);
|
||||
if (nd->nd_nam2)
|
||||
m_free(nd->nd_nam2);
|
||||
if (nd->nd_mrep)
|
||||
m_freem(nd->nd_mrep);
|
||||
error = nfsdsock_sendreply(slp, nd);
|
||||
nd = NULL;
|
||||
if (error == EPIPE)
|
||||
nfsrv_zapsock(slp);
|
||||
if (error == EINTR || error == ERESTART) {
|
||||
pool_put(&nfs_srvdesc_pool, nd);
|
||||
nfsrv_slpderef(slp);
|
||||
s = splsoftnet();
|
||||
goto done;
|
||||
@ -916,7 +900,6 @@ nfsrv_zapsock(slp)
|
||||
LIST_REMOVE(nwp, nd_tq);
|
||||
pool_put(&nfs_srvdesc_pool, nwp);
|
||||
}
|
||||
LIST_INIT(&slp->ns_tq);
|
||||
splx(s);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user