svn commit: r213380 - stable/8/sys/nfsclient
Konstantin Belousov
kib at FreeBSD.org
Sun Oct 3 08:57:03 UTC 2010
Author: kib
Date: Sun Oct 3 08:57:02 2010
New Revision: 213380
URL: http://svn.freebsd.org/changeset/base/213380
Log:
MFC r212506:
Do not fork nfsiod directly from the vop methods.
Schedule the task that performs fork to be executed in
the taskqueue context.
Modified:
stable/8/sys/nfsclient/nfs.h
stable/8/sys/nfsclient/nfs_nfsiod.c
stable/8/sys/nfsclient/nfs_subs.c
Directory Properties:
stable/8/sys/ (props changed)
stable/8/sys/amd64/include/xen/ (props changed)
stable/8/sys/cddl/contrib/opensolaris/ (props changed)
stable/8/sys/contrib/dev/acpica/ (props changed)
stable/8/sys/contrib/pf/ (props changed)
stable/8/sys/dev/xen/xenpci/ (props changed)
Modified: stable/8/sys/nfsclient/nfs.h
==============================================================================
--- stable/8/sys/nfsclient/nfs.h Sun Oct 3 08:12:17 2010 (r213379)
+++ stable/8/sys/nfsclient/nfs.h Sun Oct 3 08:57:02 2010 (r213380)
@@ -125,6 +125,7 @@ extern struct uma_zone *nfsmount_zone;
extern struct nfsstats nfsstats;
extern struct mtx nfs_iod_mtx;
+extern struct task nfs_nfsiodnew_task;
extern int nfs_numasync;
extern unsigned int nfs_iodmax;
@@ -253,6 +254,7 @@ int nfs_commit(struct vnode *vp, u_quad_
struct ucred *cred, struct thread *td);
int nfs_readdirrpc(struct vnode *, struct uio *, struct ucred *);
int nfs_nfsiodnew(int);
+void nfs_nfsiodnew_tq(__unused void *, int);
int nfs_asyncio(struct nfsmount *, struct buf *, struct ucred *, struct thread *);
int nfs_doio(struct vnode *, struct buf *, struct ucred *, struct thread *);
void nfs_doio_directwrite (struct buf *);
Modified: stable/8/sys/nfsclient/nfs_nfsiod.c
==============================================================================
--- stable/8/sys/nfsclient/nfs_nfsiod.c Sun Oct 3 08:12:17 2010 (r213379)
+++ stable/8/sys/nfsclient/nfs_nfsiod.c Sun Oct 3 08:57:02 2010 (r213380)
@@ -59,6 +59,7 @@ __FBSDID("$FreeBSD$");
#include <sys/fcntl.h>
#include <sys/lockf.h>
#include <sys/mutex.h>
+#include <sys/taskqueue.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
@@ -75,6 +76,16 @@ static MALLOC_DEFINE(M_NFSSVC, "nfsclien
static void nfssvc_iod(void *);
+struct nfsiod_str {
+ STAILQ_ENTRY(nfsiod_str) ni_links;
+ int *ni_inst;
+ int ni_iod;
+ int ni_error;
+ int ni_done;
+};
+static STAILQ_HEAD(, nfsiod_str) nfsiodhead =
+ STAILQ_HEAD_INITIALIZER(nfsiodhead);
+
static int nfs_asyncdaemon[NFS_MAXASYNCDAEMON];
SYSCTL_DECL(_vfs_nfs);
@@ -159,11 +170,30 @@ SYSCTL_PROC(_vfs_nfs, OID_AUTO, iodmax,
sizeof (nfs_iodmax), sysctl_iodmax, "IU",
"Max number of nfsiod kthreads");
+void
+nfs_nfsiodnew_tq(__unused void *arg, int pending)
+{
+ struct nfsiod_str *nip;
+
+ mtx_lock(&nfs_iod_mtx);
+ while ((nip = STAILQ_FIRST(&nfsiodhead)) != NULL) {
+ STAILQ_REMOVE_HEAD(&nfsiodhead, ni_links);
+ mtx_unlock(&nfs_iod_mtx);
+ nip->ni_error = kproc_create(nfssvc_iod, nip->ni_inst, NULL,
+ RFHIGHPID, 0, "nfsiod %d", nip->ni_iod);
+ nip->ni_done = 1;
+ mtx_lock(&nfs_iod_mtx);
+ wakeup(nip);
+ }
+ mtx_unlock(&nfs_iod_mtx);
+}
+
int
nfs_nfsiodnew(int set_iodwant)
{
int error, i;
int newiod;
+ struct nfsiod_str *nip;
if (nfs_numasync >= nfs_iodmax)
return (-1);
@@ -179,9 +209,16 @@ nfs_nfsiodnew(int set_iodwant)
if (set_iodwant > 0)
nfs_iodwant[i] = NFSIOD_CREATED_FOR_NFS_ASYNCIO;
mtx_unlock(&nfs_iod_mtx);
- error = kproc_create(nfssvc_iod, nfs_asyncdaemon + i, NULL, RFHIGHPID,
- 0, "nfsiod %d", newiod);
+ nip = malloc(sizeof(*nip), M_TEMP, M_WAITOK | M_ZERO);
+ nip->ni_inst = nfs_asyncdaemon + i;
+ nip->ni_iod = newiod;
mtx_lock(&nfs_iod_mtx);
+ STAILQ_INSERT_TAIL(&nfsiodhead, nip, ni_links);
+ taskqueue_enqueue(taskqueue_thread, &nfs_nfsiodnew_task);
+ while (!nip->ni_done)
+ mtx_sleep(nip, &nfs_iod_mtx, 0, "niwt", 0);
+ error = nip->ni_error;
+ free(nip, M_TEMP);
if (error) {
if (set_iodwant > 0)
nfs_iodwant[i] = NFSIOD_NOT_AVAILABLE;
Modified: stable/8/sys/nfsclient/nfs_subs.c
==============================================================================
--- stable/8/sys/nfsclient/nfs_subs.c Sun Oct 3 08:12:17 2010 (r213379)
+++ stable/8/sys/nfsclient/nfs_subs.c Sun Oct 3 08:57:02 2010 (r213380)
@@ -59,6 +59,7 @@ __FBSDID("$FreeBSD$");
#include <sys/sysent.h>
#include <sys/syscall.h>
#include <sys/sysproto.h>
+#include <sys/taskqueue.h>
#include <vm/vm.h>
#include <vm/vm_object.h>
@@ -117,6 +118,7 @@ int nfs_pbuf_freecnt = -1; /* start out
struct nfs_bufq nfs_bufq;
static struct mtx nfs_xid_mtx;
+struct task nfs_nfsiodnew_task;
/*
* and the reverse mapping from generic to Version 2 procedure numbers
@@ -354,6 +356,7 @@ nfs_init(struct vfsconf *vfsp)
*/
mtx_init(&nfs_iod_mtx, "NFS iod lock", NULL, MTX_DEF);
mtx_init(&nfs_xid_mtx, "NFS xid lock", NULL, MTX_DEF);
+ TASK_INIT(&nfs_nfsiodnew_task, 0, nfs_nfsiodnew_tq, NULL);
nfs_pbuf_freecnt = nswbuf / 2 + 1;
@@ -368,9 +371,13 @@ nfs_uninit(struct vfsconf *vfsp)
/*
* Tell all nfsiod processes to exit. Clear nfs_iodmax, and wakeup
* any sleeping nfsiods so they check nfs_iodmax and exit.
+ * Drain nfsiodnew task before we wait for them to finish.
*/
mtx_lock(&nfs_iod_mtx);
nfs_iodmax = 0;
+ mtx_unlock(&nfs_iod_mtx);
+ taskqueue_drain(taskqueue_thread, &nfs_nfsiodnew_task);
+ mtx_lock(&nfs_iod_mtx);
for (i = 0; i < nfs_numasync; i++)
if (nfs_iodwant[i] == NFSIOD_AVAILABLE)
wakeup(&nfs_iodwant[i]);
More information about the svn-src-all
mailing list