svn commit: r330865 - stable/11/sys/compat/linuxkpi/common/src
Hans Petter Selasky
hselasky at FreeBSD.org
Tue Mar 13 16:33:42 UTC 2018
Author: hselasky
Date: Tue Mar 13 16:33:41 2018
New Revision: 330865
URL: https://svnweb.freebsd.org/changeset/base/330865
Log:
MFC r330689:
Implement proper support for complete_all() in the LinuxKPI.
When complete_all() is called there might be multiple waiters. The
current implementation could only handle one waiter. Make sure the
completion is sticky when complete_all() is called to be compatible
with Linux.
Found by: Johannes Lundberg <johalun0 at gmail.com>
Sponsored by: Mellanox Technologies
Sponsored by: Limelight Networks
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 Tue Mar 13 16:33:00 2018 (r330864)
+++ stable/11/sys/compat/linuxkpi/common/src/linux_compat.c Tue Mar 13 16:33:41 2018 (r330865)
@@ -1779,11 +1779,14 @@ linux_complete_common(struct completion *c, int all)
int wakeup_swapper;
sleepq_lock(c);
- c->done++;
- if (all)
+ if (all) {
+ c->done = UINT_MAX;
wakeup_swapper = sleepq_broadcast(c, SLEEPQ_SLEEP, 0, 0);
- else
+ } else {
+ if (c->done != UINT_MAX)
+ c->done++;
wakeup_swapper = sleepq_signal(c, SLEEPQ_SLEEP, 0, 0);
+ }
sleepq_release(c);
if (wakeup_swapper)
kick_proc0();
@@ -1825,7 +1828,8 @@ linux_wait_for_common(struct completion *c, int flags)
} else
sleepq_wait(c, 0);
}
- c->done--;
+ if (c->done != UINT_MAX)
+ c->done--;
sleepq_release(c);
intr:
@@ -1878,7 +1882,8 @@ linux_wait_for_timeout_common(struct completion *c, in
goto done;
}
}
- c->done--;
+ if (c->done != UINT_MAX)
+ c->done--;
sleepq_release(c);
/* return how many jiffies are left */
@@ -1894,12 +1899,10 @@ linux_try_wait_for_completion(struct completion *c)
{
int isdone;
- isdone = 1;
sleepq_lock(c);
- if (c->done)
+ isdone = (c->done != 0);
+ if (c->done != 0 && c->done != UINT_MAX)
c->done--;
- else
- isdone = 0;
sleepq_release(c);
return (isdone);
}
@@ -1909,10 +1912,8 @@ linux_completion_done(struct completion *c)
{
int isdone;
- isdone = 1;
sleepq_lock(c);
- if (c->done == 0)
- isdone = 0;
+ isdone = (c->done != 0);
sleepq_release(c);
return (isdone);
}
More information about the svn-src-stable-11
mailing list