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)
This commit is contained in:
Konstantin Belousov 2016-06-26 20:08:42 +00:00
parent 3a1e5dd8e6
commit 883a5a4a6a
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=302216
3 changed files with 16 additions and 5 deletions

View File

@ -1378,7 +1378,7 @@ lf_setlock(struct lockf *state, struct lockf_entry *lock, struct vnode *vp,
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 lockf_entry *lock, struct vnode *vp,
}
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;

View File

@ -697,7 +697,8 @@ nlm_record_lock(struct vnode *vp, int op, struct flock *fl,
{
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, struct flock *fl,
* 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

View File

@ -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) {
/*