Index: sys/nfsclient/nfs_vnops.c =================================================================== --- sys/nfsclient/nfs_vnops.c (revision 211279) +++ sys/nfsclient/nfs_vnops.c (working copy) @@ -212,6 +212,7 @@ * Global variables */ struct mtx nfs_iod_mtx; +struct mtx shep_mtx; 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) @@ -354,6 +354,7 @@ */ mtx_init(&nfs_iod_mtx, "NFS iod lock", NULL, MTX_DEF); mtx_init(&nfs_xid_mtx, "NFS xid lock", NULL, MTX_DEF); + mtx_init(&shep_mtx, "NFS shep_thread lock", NULL, MTX_DEF); 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) @@ -75,6 +75,13 @@ static void nfssvc_iod(void *); +struct shepherd_str { + int *shep_inst; + int shep_niod; + int shep_error; + int shep_done; +} shep_chan; + static int nfs_asyncdaemon[NFS_MAXASYNCDAEMON]; SYSCTL_DECL(_vfs_nfs); @@ -159,10 +166,32 @@ sizeof (nfs_iodmax), sysctl_iodmax, "IU", "Max number of nfsiod kthreads"); +static void +shep_thread(void *dummy) +{ + int err = 0; + +// mtx_lock(&shep_mtx); + for (;;) { +// err = msleep(&shep_chan, &shep_mtx, PWAIT | PCATCH, "shpwt", 0); + err = tsleep(&shep_chan, PWAIT | PCATCH, "shpwt", 0); + if (err) + continue; +// mtx_unlock(&shep_mtx); + shep_chan.shep_error = kproc_create(nfssvc_iod, + &shep_chan.shep_inst, NULL, RFHIGHPID, 0, "nfsiod %d", + shep_chan.shep_niod); + shep_chan.shep_done = 1; +// mtx_lock(&shep_mtx); + } +// mtx_unlock(&shep_mtx); +} +SYSINIT(shepherd, SI_SUB_KTHREAD_IDLE, SI_ORDER_ANY, shep_thread, NULL); + int nfs_nfsiodnew(int set_iodwant) { - int error, i; + int i; int newiod; if (nfs_numasync >= nfs_iodmax) @@ -178,11 +207,16 @@ 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); + wakeup(&shep_chan); mtx_lock(&nfs_iod_mtx); - if (error) { + while (shep_chan.shep_done) + continue; + shep_chan.shep_done = 0; + 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 mtx shep_mtx; extern int nfs_numasync; extern unsigned int nfs_iodmax;