Author: rmacklem
Date: Mon Jul  4 00:45:21 2011
New Revision: 223749
URL: http://svn.freebsd.org/changeset/base/223749

Log:
  MFC: r223312
  Fix a number of places where the new NFS server did not
  lock the mutex when manipulating rc_flag in the DRC cache.
  This is believed to fix a hung server that was reported
  to the freebsd-fs@ list on June 9 under the subject heading
  "New NFS server stress test hang", where all the threads
  were waiting for the RC_LOCKED flag to clear.

Modified:
  stable/8/sys/fs/nfsserver/nfs_nfsdcache.c
Directory Properties:
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)

Modified: stable/8/sys/fs/nfsserver/nfs_nfsdcache.c
==============================================================================
--- stable/8/sys/fs/nfsserver/nfs_nfsdcache.c   Mon Jul  4 00:24:59 2011        
(r223748)
+++ stable/8/sys/fs/nfsserver/nfs_nfsdcache.c   Mon Jul  4 00:45:21 2011        
(r223749)
@@ -405,6 +405,7 @@ nfsrvd_updatecache(struct nfsrv_descript
 {
        struct nfsrvcache *rp;
        struct nfsrvcache *retrp = NULL;
+       mbuf_t m;
 
        rp = nd->nd_rp;
        if (!rp)
@@ -457,9 +458,9 @@ nfsrvd_updatecache(struct nfsrv_descript
                }
                if ((nd->nd_flag & ND_NFSV2) &&
                    nfsv2_repstat[newnfsv2_procid[nd->nd_procnum]]) {
-                       NFSUNLOCKCACHE();
                        rp->rc_status = nd->nd_repstat;
                        rp->rc_flag |= RC_REPSTATUS;
+                       NFSUNLOCKCACHE();
                } else {
                        if (!(rp->rc_flag & RC_UDP)) {
                            nfsrc_tcpsavedreplies++;
@@ -469,9 +470,11 @@ nfsrvd_updatecache(struct nfsrv_descript
                                    nfsrc_tcpsavedreplies;
                        }
                        NFSUNLOCKCACHE();
-                       rp->rc_reply = m_copym(nd->nd_mreq, 0, M_COPYALL,
-                           M_WAIT);
+                       m = m_copym(nd->nd_mreq, 0, M_COPYALL, M_WAIT);
+                       NFSLOCKCACHE();
+                       rp->rc_reply = m;
                        rp->rc_flag |= RC_REPMBUF;
+                       NFSUNLOCKCACHE();
                }
                if (rp->rc_flag & RC_UDP) {
                        rp->rc_timestamp = NFSD_MONOSEC +
@@ -518,6 +521,7 @@ nfsrvd_delcache(struct nfsrvcache *rp)
 APPLESTATIC void
 nfsrvd_sentcache(struct nfsrvcache *rp, struct socket *so, int err)
 {
+       tcp_seq tmp_seq;
 
        if (!(rp->rc_flag & RC_LOCKED))
                panic("nfsrvd_sentcache not locked");
@@ -526,8 +530,12 @@ nfsrvd_sentcache(struct nfsrvcache *rp, 
                     so->so_proto->pr_domain->dom_family != AF_INET6) ||
                     so->so_proto->pr_protocol != IPPROTO_TCP)
                        panic("nfs sent cache");
-               if (nfsrv_getsockseqnum(so, &rp->rc_tcpseq))
+               if (nfsrv_getsockseqnum(so, &tmp_seq)) {
+                       NFSLOCKCACHE();
+                       rp->rc_tcpseq = tmp_seq;
                        rp->rc_flag |= RC_TCPSEQ;
+                       NFSUNLOCKCACHE();
+               }
        }
        nfsrc_unlock(rp);
 }
@@ -687,8 +695,11 @@ nfsrc_lock(struct nfsrvcache *rp)
 static void
 nfsrc_unlock(struct nfsrvcache *rp)
 {
+
+       NFSLOCKCACHE();
        rp->rc_flag &= ~RC_LOCKED;
        nfsrc_wanted(rp);
+       NFSUNLOCKCACHE();
 }
 
 /*
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to