NFS - Fix unmounting blockages, fix tick interval, hack cpu assignments.
authorMatthew Dillon <dillon@apollo.backplane.com>
Fri, 17 Jul 2009 11:38:35 +0000 (04:38 -0700)
committerMatthew Dillon <dillon@apollo.backplane.com>
Fri, 17 Jul 2009 11:38:35 +0000 (04:38 -0700)
* Umount was having problems due to the way the helper threads were
  being shutdown.  Should be fixed.

* The NFS timer, which is responsible for handling retransmits and
  timeouts, did not need to be set to one tick (10ms).  200ms is
  just fine.

* Hack cpu assignments for the tx and rx helper threads.

sys/vfs/nfs/nfs.h
sys/vfs/nfs/nfs_iod.c
sys/vfs/nfs/nfs_kerb.c
sys/vfs/nfs/nfs_socket.c
sys/vfs/nfs/nfs_vfsops.c

index c2c7fb8..622cbf4 100644 (file)
@@ -53,7 +53,7 @@
  */
 
 #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 */
@@ -761,7 +761,8 @@ int nfs_clientd(struct nfsmount *nmp, struct ucred *cred,
                        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);
 
index c4de31b..7fd9169 100644 (file)
@@ -198,19 +198,26 @@ nfssvc_iod_writer(void *arg)
 }
 
 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)
 {
index 8efe9c2..2ac745f 100644 (file)
@@ -144,7 +144,6 @@ nfs_clientd(struct nfsmount *nmp, struct ucred *cred, struct nfsd_cargs *ncd,
                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;
index d5d4b6e..7166946 100644 (file)
@@ -796,9 +796,11 @@ nfs_reply(struct nfsmount *nmp, struct nfsreq *myrep)
                /*
                 * 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);
                }
index b33c5ee..030d1bb 100644 (file)
@@ -890,6 +890,8 @@ mountnfs(struct nfs_args *argp, struct mount *mp, struct sockaddr *nam,
        struct nfsmount *nmp;
        struct nfsnode *np;
        int error;
+       int rxcpu;
+       int txcpu;
 
        if (mp->mnt_flag & MNT_UPDATE) {
                nmp = VFSTONFS(mp);
@@ -1000,19 +1002,38 @@ mountnfs(struct nfs_args *argp, struct mount *mp, struct sockaddr *nam,
        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);
 }
 
@@ -1058,13 +1079,12 @@ nfs_unmount(struct mount *mp, int mntflags)
         */
        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);
@@ -1077,6 +1097,10 @@ nfs_free_mount(struct nfsmount *nmp)
                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);
 }