Author: kib
Date: Sun Jun 26 20:08:42 2016
New Revision: 302216
URL: https://svnweb.freebsd.org/changeset/base/302216

Log:
  When sleeping waiting for either local or remote advisory lock,
  interrupt sleeps with the ERESTART on the suspension attempts.
  Otherwise, single-threading requests are deferred until the locks are
  granted for NFS files, which causes hangs.
  
  When retrying local registration of the remotely-granted adv lock,
  allow full suspension and check for suspension, for usual reasons.
  
  Reported by:  markj, pho
  Reviewed by:  jilles
  Tested by:    pho
  Sponsored by: The FreeBSD Foundation
  MFC after:    2 weeks
  Approved by:  re (gjb)

Modified:
  head/sys/kern/kern_lockf.c
  head/sys/nlm/nlm_advlock.c
  head/sys/nlm/nlm_prot_impl.c

Modified: head/sys/kern/kern_lockf.c
==============================================================================
--- head/sys/kern/kern_lockf.c  Sun Jun 26 20:07:24 2016        (r302215)
+++ head/sys/kern/kern_lockf.c  Sun Jun 26 20:08:42 2016        (r302216)
@@ -1378,7 +1378,7 @@ lf_setlock(struct lockf *state, struct l
     void **cookiep)
 {
        static char lockstr[] = "lockf";
-       int priority, error;
+       int error, priority, stops_deferred;
 
 #ifdef LOCKF_DEBUG
        if (lockf_debug & 1)
@@ -1466,7 +1466,9 @@ lf_setlock(struct lockf *state, struct l
                }
 
                lock->lf_refs++;
+               stops_deferred = sigdeferstop(SIGDEFERSTOP_ERESTART);
                error = sx_sleep(lock, &state->ls_lock, priority, lockstr, 0);
+               sigallowstop(stops_deferred);
                if (lf_free_lock(lock)) {
                        error = EDOOFUS;
                        goto out;

Modified: head/sys/nlm/nlm_advlock.c
==============================================================================
--- head/sys/nlm/nlm_advlock.c  Sun Jun 26 20:07:24 2016        (r302215)
+++ head/sys/nlm/nlm_advlock.c  Sun Jun 26 20:08:42 2016        (r302216)
@@ -697,7 +697,8 @@ nlm_record_lock(struct vnode *vp, int op
 {
        struct vop_advlockasync_args a;
        struct flock newfl;
-       int error;
+       struct proc *p;
+       int error, stops_deferred;
 
        a.a_vp = vp;
        a.a_id = NULL;
@@ -730,7 +731,12 @@ nlm_record_lock(struct vnode *vp, int op
                         * return EDEADLK.
                        */
                        pause("nlmdlk", 1);
-                       /* XXXKIB allow suspend */
+                       p = curproc;
+                       stops_deferred = sigdeferstop(SIGDEFERSTOP_OFF);
+                       PROC_LOCK(p);
+                       thread_suspend_check(0);
+                       PROC_UNLOCK(p);
+                       sigallowstop(stops_deferred);
                } else if (error == EINTR) {
                        /*
                         * lf_purgelocks() might wake up the lock

Modified: head/sys/nlm/nlm_prot_impl.c
==============================================================================
--- head/sys/nlm/nlm_prot_impl.c        Sun Jun 26 20:07:24 2016        
(r302215)
+++ head/sys/nlm/nlm_prot_impl.c        Sun Jun 26 20:08:42 2016        
(r302216)
@@ -1356,7 +1356,7 @@ int
 nlm_wait_lock(void *handle, int timo)
 {
        struct nlm_waiting_lock *nw = handle;
-       int error;
+       int error, stops_deferred;
 
        /*
         * If the granted message arrived before we got here,
@@ -1364,8 +1364,11 @@ nlm_wait_lock(void *handle, int timo)
         */
        mtx_lock(&nlm_global_lock);
        error = 0;
-       if (nw->nw_waiting)
+       if (nw->nw_waiting) {
+               stops_deferred = sigdeferstop(SIGDEFERSTOP_ERESTART);
                error = msleep(nw, &nlm_global_lock, PCATCH, "nlmlock", timo);
+               sigallowstop(stops_deferred);
+       }
        TAILQ_REMOVE(&nlm_waiting_locks, nw, nw_link);
        if (error) {
                /*
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to