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 #include #include +#include #include #include @@ -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 #include #include +#include #include #include @@ -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 #include #include +#include #include #include @@ -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 *);