svn commit: r302216 - in head/sys: kern nlm
Konstantin Belousov
kib at FreeBSD.org
Sun Jun 26 20:08:43 UTC 2016
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) {
/*
More information about the svn-src-all
mailing list