Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 18 Aug 2010 14:43:19 +0400
From:      pluknet <pluknet@gmail.com>
To:        Kostik Belousov <kostikbel@gmail.com>
Cc:        FreeBSD Current <freebsd-current@freebsd.org>
Subject:   Re: LOR on nfs: vfs_vnops.c:301 kern_descrip.c:1580
Message-ID:  <AANLkTimXxF0US60NsbOV_HvRrib7SJWmrLqpEpznPTxB@mail.gmail.com>
In-Reply-To: <AANLkTimyk0ZUnHpxxJuJtTya2U3npj_5Bm8brmwHfzr3@mail.gmail.com>
References:  <AANLkTimJ=d06D2z24QyRQ98zEa1Pemk4=vkNGLNiX90N@mail.gmail.com> <AANLkTi=22WWy8Z5VWqri1p70iRzyocD9bWvNHwJavZ%2Bj@mail.gmail.com> <20100816185456.GU2396@deviant.kiev.zoral.com.ua> <AANLkTimfZ=UCiX9eo9XCwcROwViFCxJoB-rD1JxdAt2B@mail.gmail.com> <20100817160445.GO2396@deviant.kiev.zoral.com.ua> <AANLkTimyk0ZUnHpxxJuJtTya2U3npj_5Bm8brmwHfzr3@mail.gmail.com>

index | next in thread | previous in thread | raw e-mail

[-- Attachment #1 --]
On 18 August 2010 12:07, pluknet <pluknet@gmail.com> wrote:
> On 17 August 2010 20:04, Kostik Belousov <kostikbel@gmail.com> wrote:
>
>>
>> Also please take a note of the John' suggestion to use the taskqueue.
>
> I decided to go this road. Thank you both.
> Now I do nfs buildkernel survive and prepare some benchmark results.
>

So, I modified the patch to defer proc_create() with taskqueue(9).
Below is `time make -j5 buildkernel WITHOUT_MODULES=yes` perf. evaluation.
Done on 4-way CPU on clean /usr/obj with /usr/src & /usr/obj both
nfs-mounted over 1Gbit LAN.

clean old
1137.985u 239.411s 7:42.15 298.0%       6538+2133k 87+43388io 226pf+0w

clean new
1134.755u 240.032s 7:41.25 298.0%       6553+2133k 87+43367io 224pf+0w

Patch needs polishing, though it generally works.
Not sure if shep_chan (or whatever name it will get) needs locking.

-- 
wbr,
pluknet

[-- Attachment #2 --]
Index: sys/nfsclient/nfs_vnops.c
===================================================================
--- sys/nfsclient/nfs_vnops.c	(revision 211279)
+++ sys/nfsclient/nfs_vnops.c	(working copy)
@@ -62,6 +62,7 @@
 #include <sys/stat.h>
 #include <sys/sysctl.h>
 #include <sys/signalvar.h>
+#include <sys/taskqueue.h>
 
 #include <vm/vm.h>
 #include <vm/vm_object.h>
@@ -212,6 +213,7 @@
  * Global variables
  */
 struct mtx 	nfs_iod_mtx;
+struct task	nfs_nfsiodnew_task;
 enum nfsiod_state nfs_iodwant[NFS_MAXASYNCDAEMON];
 struct nfsmount *nfs_iodmount[NFS_MAXASYNCDAEMON];
 int		 nfs_numasync = 0;
Index: sys/nfsclient/nfs_subs.c
===================================================================
--- sys/nfsclient/nfs_subs.c	(revision 211279)
+++ sys/nfsclient/nfs_subs.c	(working copy)
@@ -59,6 +59,7 @@
 #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>
@@ -354,6 +355,7 @@
 	 */
 	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;
 
Index: sys/nfsclient/nfs_nfsiod.c
===================================================================
--- sys/nfsclient/nfs_nfsiod.c	(revision 211279)
+++ sys/nfsclient/nfs_nfsiod.c	(working copy)
@@ -59,6 +59,7 @@
 #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,12 @@
 
 static void	nfssvc_iod(void *);
 
+struct shepherd_str {
+	int *shep_inst;
+	int shep_niod;
+	int shep_error;
+} shep_chan;
+
 static int nfs_asyncdaemon[NFS_MAXASYNCDAEMON];
 
 SYSCTL_DECL(_vfs_nfs);
@@ -159,10 +166,19 @@
     sizeof (nfs_iodmax), sysctl_iodmax, "IU",
     "Max number of nfsiod kthreads");
 
+void
+nfs_nfsiodnew_tq(__unused void *arg, int pending)
+{
+
+	shep_chan.shep_error = kproc_create(nfssvc_iod,
+	    shep_chan.shep_inst, NULL, RFHIGHPID, 0, "nfsiod %d",
+	    shep_chan.shep_niod);
+}
+
 int
 nfs_nfsiodnew(int set_iodwant)
 {
-	int error, i;
+	int i;
 	int newiod;
 
 	if (nfs_numasync >= nfs_iodmax)
@@ -178,11 +194,13 @@
 		return (-1);
 	if (set_iodwant > 0)
 		nfs_iodwant[i] = NFSIOD_CREATED_FOR_NFS_ASYNCIO;
+	bzero(&shep_chan, sizeof(shep_chan));
+	shep_chan.shep_inst = nfs_asyncdaemon + i;
+	shep_chan.shep_niod = newiod;
 	mtx_unlock(&nfs_iod_mtx);
-	error = kproc_create(nfssvc_iod, nfs_asyncdaemon + i, NULL, RFHIGHPID,
-	    0, "nfsiod %d", newiod);
+	taskqueue_enqueue(taskqueue_thread, &nfs_nfsiodnew_task);
 	mtx_lock(&nfs_iod_mtx);
-	if (error) {
+	if (shep_chan.shep_error) {
 		if (set_iodwant > 0)
 			nfs_iodwant[i] = NFSIOD_NOT_AVAILABLE;
 		return (-1);
Index: sys/nfsclient/nfs.h
===================================================================
--- sys/nfsclient/nfs.h	(revision 211279)
+++ sys/nfsclient/nfs.h	(working copy)
@@ -125,6 +125,7 @@
 
 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 @@
 	    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 *);
help

Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?AANLkTimXxF0US60NsbOV_HvRrib7SJWmrLqpEpznPTxB>