From owner-svn-src-stable@FreeBSD.ORG Mon Nov 8 10:23:39 2010 Return-Path: Delivered-To: svn-src-stable@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id D3874106564A; Mon, 8 Nov 2010 10:23:39 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id C09C18FC1D; Mon, 8 Nov 2010 10:23:39 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id oA8ANdCd024104; Mon, 8 Nov 2010 10:23:39 GMT (envelope-from kib@svn.freebsd.org) Received: (from kib@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id oA8ANdj9024099; Mon, 8 Nov 2010 10:23:39 GMT (envelope-from kib@svn.freebsd.org) Message-Id: <201011081023.oA8ANdj9024099@svn.freebsd.org> From: Konstantin Belousov Date: Mon, 8 Nov 2010 10:23:39 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org X-SVN-Group: stable-8 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r214977 - stable/8/sys/nfsclient X-BeenThere: svn-src-stable@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for all the -stable branches of the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 08 Nov 2010 10:23:40 -0000 Author: kib Date: Mon Nov 8 10:23:39 2010 New Revision: 214977 URL: http://svn.freebsd.org/changeset/base/214977 Log: MFC r214026: Do not synchronously start the nfsiod threads at all. The r212506 fixed the issues with file descriptor locks, but the same problems are present for vnode lock/user map lock. Modified: stable/8/sys/nfsclient/nfs.h stable/8/sys/nfsclient/nfs_bio.c stable/8/sys/nfsclient/nfs_nfsiod.c stable/8/sys/nfsclient/nfsnode.h 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 Mon Nov 8 10:18:01 2010 (r214976) +++ stable/8/sys/nfsclient/nfs.h Mon Nov 8 10:23:39 2010 (r214977) @@ -253,7 +253,7 @@ int nfs_writerpc(struct vnode *, struct int nfs_commit(struct vnode *vp, u_quad_t offset, int cnt, struct ucred *cred, struct thread *td); int nfs_readdirrpc(struct vnode *, struct uio *, struct ucred *); -int nfs_nfsiodnew(int); +void nfs_nfsiodnew(void); 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 *); Modified: stable/8/sys/nfsclient/nfs_bio.c ============================================================================== --- stable/8/sys/nfsclient/nfs_bio.c Mon Nov 8 10:18:01 2010 (r214976) +++ stable/8/sys/nfsclient/nfs_bio.c Mon Nov 8 10:23:39 2010 (r214977) @@ -1379,13 +1379,9 @@ again: /* * Try to create one if none are free. */ - if (!gotiod) { - iod = nfs_nfsiodnew(1); - if (iod != -1) - gotiod = TRUE; - } - - if (gotiod) { + if (!gotiod) + nfs_nfsiodnew(); + else { /* * Found one, so wake it up and tell it which * mount to process. @@ -1405,7 +1401,7 @@ again: if (!gotiod) { if (nmp->nm_bufqiods > 0) { NFS_DPF(ASYNCIO, - ("nfs_asyncio: %d iods are already processing mount %p\n", + ("nfs_asyncio: %d iods are already processing mount %p\n", nmp->nm_bufqiods, nmp)); gotiod = TRUE; } @@ -1420,9 +1416,9 @@ again: * Ensure that the queue never grows too large. We still want * to asynchronize so we block rather then return EIO. */ - while (nmp->nm_bufqlen >= 2*nfs_numasync) { + while (nmp->nm_bufqlen >= 2 * nfs_numasync) { NFS_DPF(ASYNCIO, - ("nfs_asyncio: waiting for mount %p queue to drain\n", nmp)); + ("nfs_asyncio: waiting for mount %p queue to drain\n", nmp)); nmp->nm_bufqwant = TRUE; error = nfs_msleep(td, &nmp->nm_bufq, &nfs_iod_mtx, slpflag | PRIBIO, @@ -1430,7 +1426,7 @@ again: if (error) { error2 = nfs_sigintr(nmp, td); if (error2) { - mtx_unlock(&nfs_iod_mtx); + mtx_unlock(&nfs_iod_mtx); return (error2); } if (slpflag == NFS_PCATCH) { @@ -1442,17 +1438,13 @@ again: * We might have lost our iod while sleeping, * so check and loop if nescessary. */ - if (nmp->nm_bufqiods == 0) { - NFS_DPF(ASYNCIO, - ("nfs_asyncio: no iods after mount %p queue was drained, looping\n", nmp)); - goto again; - } + goto again; } /* We might have lost our nfsiod */ if (nmp->nm_bufqiods == 0) { NFS_DPF(ASYNCIO, - ("nfs_asyncio: no iods after mount %p queue was drained, looping\n", nmp)); +("nfs_asyncio: no iods after mount %p queue was drained, looping\n", nmp)); goto again; } Modified: stable/8/sys/nfsclient/nfs_nfsiod.c ============================================================================== --- stable/8/sys/nfsclient/nfs_nfsiod.c Mon Nov 8 10:18:01 2010 (r214976) +++ stable/8/sys/nfsclient/nfs_nfsiod.c Mon Nov 8 10:23:39 2010 (r214977) @@ -76,16 +76,6 @@ 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); @@ -101,6 +91,8 @@ unsigned int nfs_iodmax = 20; /* Minimum number of nfsiod kthreads to keep as spares */ static unsigned int nfs_iodmin = 0; +static int nfs_nfsiodnew_sync(void); + static int sysctl_iodmin(SYSCTL_HANDLER_ARGS) { @@ -124,7 +116,7 @@ sysctl_iodmin(SYSCTL_HANDLER_ARGS) * than the new minimum, create some more. */ for (i = nfs_iodmin - nfs_numasync; i > 0; i--) - nfs_nfsiodnew(0); + nfs_nfsiodnew_sync(); out: mtx_unlock(&nfs_iod_mtx); return (0); @@ -170,68 +162,55 @@ SYSCTL_PROC(_vfs_nfs, OID_AUTO, iodmax, sizeof (nfs_iodmax), sysctl_iodmax, "IU", "Max number of nfsiod kthreads"); +static int +nfs_nfsiodnew_sync(void) +{ + int error, i; + + mtx_assert(&nfs_iod_mtx, MA_OWNED); + for (i = 0; i < nfs_iodmax; i++) { + if (nfs_asyncdaemon[i] == 0) { + nfs_asyncdaemon[i] = 1; + break; + } + } + if (i == nfs_iodmax) + return (0); + mtx_unlock(&nfs_iod_mtx); + error = kproc_create(nfssvc_iod, nfs_asyncdaemon + i, NULL, + RFHIGHPID, 0, "nfsiod %d", i); + mtx_lock(&nfs_iod_mtx); + if (error == 0) { + nfs_numasync++; + nfs_iodwant[i] = NFSIOD_AVAILABLE; + } else + nfs_asyncdaemon[i] = 0; + return (error); +} + 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); + while (pending > 0) { + pending--; + nfs_nfsiodnew_sync(); } mtx_unlock(&nfs_iod_mtx); } -int -nfs_nfsiodnew(int set_iodwant) +void +nfs_nfsiodnew(void) { - int error, i; - int newiod; - struct nfsiod_str *nip; - if (nfs_numasync >= nfs_iodmax) - return (-1); - newiod = -1; - for (i = 0; i < nfs_iodmax; i++) - if (nfs_asyncdaemon[i] == 0) { - nfs_asyncdaemon[i]++; - newiod = i; - break; - } - if (newiod == -1) - return (-1); - if (set_iodwant > 0) - nfs_iodwant[i] = NFSIOD_CREATED_FOR_NFS_ASYNCIO; - mtx_unlock(&nfs_iod_mtx); - 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); + mtx_assert(&nfs_iod_mtx, MA_OWNED); 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; - return (-1); - } - nfs_numasync++; - return (newiod); } static void nfsiod_setup(void *dummy) { - int i; int error; TUNABLE_INT_FETCH("vfs.nfs.iodmin", &nfs_iodmin); @@ -240,8 +219,8 @@ nfsiod_setup(void *dummy) if (nfs_iodmin > NFS_MAXASYNCDAEMON) nfs_iodmin = NFS_MAXASYNCDAEMON; - for (i = 0; i < nfs_iodmin; i++) { - error = nfs_nfsiodnew(0); + while (nfs_numasync < nfs_iodmin) { + error = nfs_nfsiodnew_sync(); if (error == -1) panic("nfsiod_setup: nfs_nfsiodnew failed"); } Modified: stable/8/sys/nfsclient/nfsnode.h ============================================================================== --- stable/8/sys/nfsclient/nfsnode.h Mon Nov 8 10:18:01 2010 (r214976) +++ stable/8/sys/nfsclient/nfsnode.h Mon Nov 8 10:23:39 2010 (r214977) @@ -175,16 +175,13 @@ struct nfsnode { #define NFS_TIMESPEC_COMPARE(T1, T2) (((T1)->tv_sec != (T2)->tv_sec) || ((T1)->tv_nsec != (T2)->tv_nsec)) /* - * NFS iod threads can be in one of these three states once spawned. + * NFS iod threads can be in one of these two states once spawned. * NFSIOD_NOT_AVAILABLE - Cannot be assigned an I/O operation at this time. * NFSIOD_AVAILABLE - Available to be assigned an I/O operation. - * NFSIOD_CREATED_FOR_NFS_ASYNCIO - Newly created for nfs_asyncio() and - * will be used by the thread that called nfs_asyncio(). */ enum nfsiod_state { NFSIOD_NOT_AVAILABLE = 0, NFSIOD_AVAILABLE = 1, - NFSIOD_CREATED_FOR_NFS_ASYNCIO = 2, }; /*