Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 26 Jun 2016 20:08:42 +0000 (UTC)
From:      Konstantin Belousov <kib@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r302216 - in head/sys: kern nlm
Message-ID:  <201606262008.u5QK8gTx042729@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
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) {
 		/*



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201606262008.u5QK8gTx042729>