*/
#define NFS_MAXIOVEC 34
-#define NFS_TICKINTVL 5 /* Desired time for a tick (msec) */
+#define NFS_TICKINTVL 200 /* Desired time for a tick (msec) */
#define NFS_HZ (hz / nfs_ticks) /* Ticks/sec */
#define NFS_TIMEO (1 * NFS_HZ) /* Default timeout = 1 second */
#define NFS_MINTIMEO (1 * NFS_HZ) /* Min timeout to use */
struct thread *td);
void nfssvc_iod_reader(void *arg);
void nfssvc_iod_writer(void *arg);
-void nfssvc_iod_stop(struct nfsmount *nmp);
+void nfssvc_iod_stop1(struct nfsmount *nmp);
+void nfssvc_iod_stop2(struct nfsmount *nmp);
void nfssvc_iod_writer_wakeup(struct nfsmount *nmp);
void nfssvc_iod_reader_wakeup(struct nfsmount *nmp);
}
void
-nfssvc_iod_stop(struct nfsmount *nmp)
+nfssvc_iod_stop1(struct nfsmount *nmp)
{
+ crit_enter();
nmp->nm_txstate = NFSSVC_STOPPING;
+ nmp->nm_rxstate = NFSSVC_STOPPING;
+ crit_exit();
+}
+
+void
+nfssvc_iod_stop2(struct nfsmount *nmp)
+{
wakeup(&nmp->nm_txstate);
while (nmp->nm_txthread)
tsleep(&nmp->nm_txthread, 0, "nfssttx", 0);
-
- nmp->nm_rxstate = NFSSVC_STOPPING;
wakeup(&nmp->nm_rxstate);
while (nmp->nm_rxthread)
tsleep(&nmp->nm_rxthread, 0, "nfsstrx", 0);
}
+
void
nfssvc_iod_writer_wakeup(struct nfsmount *nmp)
{
TAILQ_REMOVE(&nmp->nm_uidlruhead, nuidp, nu_lru);
kfree((caddr_t)nuidp, M_NFSUID);
}
- nfssvc_iod_stop(nmp);
nfs_free_mount(nmp);
if (error == EWOULDBLOCK)
error = 0;
/*
* If myrep is NULL we are the receiver helper thread.
* Stop waiting for incoming replies if there are
- * replies sitting on reqrxq.
+ * messages sitting on reqrxq that we need to process,
+ * or if a shutdown request is pending.
*/
- if (myrep == NULL && TAILQ_FIRST(&nmp->nm_reqrxq)) {
+ if (myrep == NULL && (TAILQ_FIRST(&nmp->nm_reqrxq) ||
+ nmp->nm_rxstate > NFSSVC_PENDING)) {
nfs_rcvunlock(nmp);
return(EWOULDBLOCK);
}
struct nfsmount *nmp;
struct nfsnode *np;
int error;
+ int rxcpu;
+ int txcpu;
if (mp->mnt_flag & MNT_UPDATE) {
nmp = VFSTONFS(mp);
vn_unlock(*vpp);
TAILQ_INSERT_TAIL(&nfs_mountq, nmp, nm_entry);
+#ifdef SMP
+ switch(ncpus) {
+ case 0:
+ rxcpu = 0;
+ txcpu = 0;
+ break;
+ case 1:
+ rxcpu = 0;
+ txcpu = 1;
+ break;
+ default:
+ rxcpu = 1;
+ txcpu = 2;
+ break;
+ }
+#else
+ rxcpu = 0;
+ txcpu = 0;
+#endif
+
/*
* Start the reader and writer threads.
*/
lwkt_create(nfssvc_iod_reader, nmp, &nmp->nm_rxthread,
- NULL, 0, -1, "nfsiod_rx");
+ NULL, 0, rxcpu, "nfsiod_rx");
lwkt_create(nfssvc_iod_writer, nmp, &nmp->nm_txthread,
- NULL, 0, -1, "nfsiod_tx");
+ NULL, 0, txcpu, "nfsiod_tx");
return (0);
bad:
nfs_disconnect(nmp);
nfs_free_mount(nmp);
- FREE(nam, M_SONAME);
return (error);
}
*/
if (nmp->nm_flag & NFSMNT_KERB)
nmp->nm_state |= NFSSTA_DISMNT;
-
+ nfssvc_iod_stop1(nmp);
nfs_disconnect(nmp);
- FREE(nmp->nm_nam, M_SONAME);
+ nfssvc_iod_stop2(nmp);
TAILQ_REMOVE(&nfs_mountq, nmp, nm_entry);
if ((nmp->nm_flag & NFSMNT_KERB) == 0) {
- nfssvc_iod_stop(nmp);
nfs_free_mount(nmp);
}
return (0);
crfree(nmp->nm_cred);
nmp->nm_cred = NULL;
}
+ if (nmp->nm_nam) {
+ FREE(nmp->nm_nam, M_SONAME);
+ nmp->nm_nam = NULL;
+ }
zfree(nfsmount_zone, nmp);
}