From c10bac25f6ddc8667071fc8373fc82d644dfd0e7 Mon Sep 17 00:00:00 2001 From: Paul Saab Date: Tue, 7 Dec 2004 03:39:52 +0000 Subject: [PATCH] Always issue wakeups() to the NFS requestors under the mutex to close all potential cases of missed wakeups. Submitted by: Mohan Srinivasan mohans at yahoo-inc dot com --- sys/nfsclient/nfs_socket.c | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/sys/nfsclient/nfs_socket.c b/sys/nfsclient/nfs_socket.c index 80029087f02..8a25ce18cb7 100644 --- a/sys/nfsclient/nfs_socket.c +++ b/sys/nfsclient/nfs_socket.c @@ -149,6 +149,7 @@ static void nfs_softterm(struct nfsreq *rep); static int nfs_reconnect(struct nfsreq *rep); static void nfs_clnt_tcp_soupcall(struct socket *so, void *arg, int waitflag); static void nfs_clnt_udp_soupcall(struct socket *so, void *arg, int waitflag); +static void wakeup_nfsreq(struct nfsreq *req); extern struct mtx nfs_reqq_mtx; extern struct mtx nfs_reply_mtx; @@ -721,14 +722,23 @@ nfsmout: if (rep == 0) { nfsstats.rpcunexpected++; m_freem(mrep); - } else { - mtx_lock(&nfs_reply_mtx); - wakeup((caddr_t)rep); - mtx_unlock(&nfs_reply_mtx); - } + } else + wakeup_nfsreq(rep); mtx_unlock(&nfs_reqq_mtx); } +/* + * The wakeup of the requestor should be done under the mutex + * to avoid potential missed wakeups. + */ +static void +wakeup_nfsreq(struct nfsreq *req) +{ + mtx_lock(&nfs_reply_mtx); + wakeup((caddr_t)req); + mtx_unlock(&nfs_reply_mtx); +} + static void nfs_mark_for_reconnect(struct nfsmount *nmp) { @@ -744,7 +754,7 @@ nfs_mark_for_reconnect(struct nfsmount *nmp) mtx_lock(&nfs_reqq_mtx); TAILQ_FOREACH(rp, &nfs_reqq, r_chain) { if (rp->r_nmp == nmp) - wakeup(rp); + wakeup_nfsreq(rp); } mtx_unlock(&nfs_reqq_mtx); } @@ -1343,7 +1353,7 @@ nfs_softterm(struct nfsreq *rep) * Request terminated, wakeup the blocked process, so that we * can return EINTR back. */ - wakeup((caddr_t)rep); + wakeup_nfsreq(rep); } /*