svn commit: r317780 - stable/11/sys/compat/linuxkpi/common/src
Mark Johnston
markj at FreeBSD.org
Wed May 3 23:41:11 UTC 2017
Author: markj
Date: Wed May 3 23:41:09 2017
New Revision: 317780
URL: https://svnweb.freebsd.org/changeset/base/317780
Log:
MFC r317148:
Drop Giant before sleeping in linux_wait_for_{timeout_,}common().
Modified:
stable/11/sys/compat/linuxkpi/common/src/linux_compat.c
Directory Properties:
stable/11/ (props changed)
Modified: stable/11/sys/compat/linuxkpi/common/src/linux_compat.c
==============================================================================
--- stable/11/sys/compat/linuxkpi/common/src/linux_compat.c Wed May 3 22:35:41 2017 (r317779)
+++ stable/11/sys/compat/linuxkpi/common/src/linux_compat.c Wed May 3 23:41:09 2017 (r317780)
@@ -1096,28 +1096,38 @@ linux_complete_common(struct completion
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);
}
/*
@@ -1126,18 +1136,22 @@ linux_wait_for_common(struct completion
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;
@@ -1150,16 +1164,20 @@ linux_wait_for_timeout_common(struct com
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
More information about the svn-src-all
mailing list