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"