diff --git a/sys/compat/linuxkpi/common/src/linux_compat.c b/sys/compat/linuxkpi/common/src/linux_compat.c index c205cc2d13d..8a4441d423d 100644 --- a/sys/compat/linuxkpi/common/src/linux_compat.c +++ b/sys/compat/linuxkpi/common/src/linux_compat.c @@ -1449,18 +1449,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; + int error, ret; if (SKIP_SLEEP()) return (0); + DROP_GIANT(); + if (flags != 0) flags = SLEEPQ_INTERRUPTIBLE | SLEEPQ_SLEEP; else flags = SLEEPQ_SLEEP; - for (;;) { - int ret; + end = jiffies + timeout; + error = ret = 0; + for (;;) { sleepq_lock(c); if (c->done) break; @@ -1473,16 +1477,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 out; } } c->done--; sleepq_release(c); +out: + PICKUP_GIANT(); + /* return how many jiffies are left */ - return (linux_timer_jiffies_until(end)); + return (ret != 0 ? error : linux_timer_jiffies_until(end)); } int