mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-22 11:17:19 +00:00
Drop Giant before sleeping in linux_wait_for_{timeout_,}common().
Reported and tested by: Pete Wright <pete@nomadlogic.org> Reviewed by: hselasky (previous version) MFC after: 2 weeks Differential Revision: https://reviews.freebsd.org/D10414
This commit is contained in:
parent
2452e16e5b
commit
b602c283b3
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=317148
@ -1321,28 +1321,38 @@ linux_complete_common(struct completion *c, int all)
|
||||
long
|
||||
linux_wait_for_common(struct completion *c, int flags)
|
||||
{
|
||||
long error;
|
||||
|
||||
if (SCHEDULER_STOPPED())
|
||||
return (0);
|
||||
|
||||
DROP_GIANT();
|
||||
|
||||
if (flags != 0)
|
||||
flags = SLEEPQ_INTERRUPTIBLE | SLEEPQ_SLEEP;
|
||||
else
|
||||
flags = SLEEPQ_SLEEP;
|
||||
error = 0;
|
||||
for (;;) {
|
||||
sleepq_lock(c);
|
||||
if (c->done)
|
||||
break;
|
||||
sleepq_add(c, NULL, "completion", flags, 0);
|
||||
if (flags & SLEEPQ_INTERRUPTIBLE) {
|
||||
if (sleepq_wait_sig(c, 0) != 0)
|
||||
return (-ERESTARTSYS);
|
||||
if (sleepq_wait_sig(c, 0) != 0) {
|
||||
error = -ERESTARTSYS;
|
||||
goto intr;
|
||||
}
|
||||
} else
|
||||
sleepq_wait(c, 0);
|
||||
}
|
||||
c->done--;
|
||||
sleepq_release(c);
|
||||
|
||||
return (0);
|
||||
intr:
|
||||
PICKUP_GIANT();
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1351,18 +1361,22 @@ linux_wait_for_common(struct completion *c, int flags)
|
||||
long
|
||||
linux_wait_for_timeout_common(struct completion *c, long timeout, int flags)
|
||||
{
|
||||
long end = jiffies + timeout;
|
||||
long end = jiffies + timeout, error;
|
||||
int ret;
|
||||
|
||||
if (SCHEDULER_STOPPED())
|
||||
return (0);
|
||||
|
||||
DROP_GIANT();
|
||||
|
||||
if (flags != 0)
|
||||
flags = SLEEPQ_INTERRUPTIBLE | SLEEPQ_SLEEP;
|
||||
else
|
||||
flags = SLEEPQ_SLEEP;
|
||||
for (;;) {
|
||||
int ret;
|
||||
|
||||
error = 0;
|
||||
ret = 0;
|
||||
for (;;) {
|
||||
sleepq_lock(c);
|
||||
if (c->done)
|
||||
break;
|
||||
@ -1375,16 +1389,20 @@ linux_wait_for_timeout_common(struct completion *c, long timeout, int flags)
|
||||
if (ret != 0) {
|
||||
/* check for timeout or signal */
|
||||
if (ret == EWOULDBLOCK)
|
||||
return (0);
|
||||
error = 0;
|
||||
else
|
||||
return (-ERESTARTSYS);
|
||||
error = -ERESTARTSYS;
|
||||
goto intr;
|
||||
}
|
||||
}
|
||||
c->done--;
|
||||
sleepq_release(c);
|
||||
|
||||
intr:
|
||||
PICKUP_GIANT();
|
||||
|
||||
/* return how many jiffies are left */
|
||||
return (linux_timer_jiffies_until(end));
|
||||
return (ret != 0 ? error : linux_timer_jiffies_until(end));
|
||||
}
|
||||
|
||||
int
|
||||
|
Loading…
Reference in New Issue
Block a user