From 13ddc89513d7d229d92707032ce077664acb0899 Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Fri, 17 Jul 2009 04:38:35 -0700 Subject: [PATCH] NFS - Fix unmounting blockages, fix tick interval, hack cpu assignments. * 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 | 5 +++-- sys/vfs/nfs/nfs_iod.c | 13 ++++++++++--- sys/vfs/nfs/nfs_kerb.c | 1 - sys/vfs/nfs/nfs_socket.c | 6 ++++-- sys/vfs/nfs/nfs_vfsops.c | 36 ++++++++++++++++++++++++++++++------ 5 files changed, 47 insertions(+), 14 deletions(-) diff --git a/sys/vfs/nfs/nfs.h b/sys/vfs/nfs/nfs.h index c2c7fb8f3a..622cbf44b1 100644 --- a/sys/vfs/nfs/nfs.h +++ b/sys/vfs/nfs/nfs.h @@ -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); diff --git a/sys/vfs/nfs/nfs_iod.c b/sys/vfs/nfs/nfs_iod.c index c4de31b3d3..7fd9169ddf 100644 --- a/sys/vfs/nfs/nfs_iod.c +++ b/sys/vfs/nfs/nfs_iod.c @@ -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) { diff --git a/sys/vfs/nfs/nfs_kerb.c b/sys/vfs/nfs/nfs_kerb.c index 8efe9c2e3e..2ac745ff54 100644 --- a/sys/vfs/nfs/nfs_kerb.c +++ b/sys/vfs/nfs/nfs_kerb.c @@ -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; diff --git a/sys/vfs/nfs/nfs_socket.c b/sys/vfs/nfs/nfs_socket.c index d5d4b6e451..7166946f42 100644 --- a/sys/vfs/nfs/nfs_socket.c +++ b/sys/vfs/nfs/nfs_socket.c @@ -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); } diff --git a/sys/vfs/nfs/nfs_vfsops.c b/sys/vfs/nfs/nfs_vfsops.c index b33c5eea24..030d1bb3a9 100644 --- a/sys/vfs/nfs/nfs_vfsops.c +++ b/sys/vfs/nfs/nfs_vfsops.c @@ -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); } -- 2.41.0