aboutsummaryrefslogtreecommitdiff
path: root/sys/compat/linuxkpi/common
diff options
context:
space:
mode:
authorHans Petter Selasky <hselasky@FreeBSD.org>2018-03-03 18:54:16 +0000
committerHans Petter Selasky <hselasky@FreeBSD.org>2018-03-03 18:54:16 +0000
commit7cf1c515882dadc9fac89f24a7061cd1aab683fa (patch)
tree3e0ba611552ff75890fbc9fcefe50cb0b863169d /sys/compat/linuxkpi/common
parent458915bfae50831d838d4cade3d24e84d1d24d2b (diff)
downloadsrc-7cf1c515882dadc9fac89f24a7061cd1aab683fa.tar.gz
src-7cf1c515882dadc9fac89f24a7061cd1aab683fa.zip
Implement msleep_interruptible() in the LinuxKPI. While at it use pause_sbt()
instead of pause() in the msleep() function to avoid rounding errors when converting delay values forth and back. Add a guard for a delay value of zero milliseconds which is undefined. MFC after: 1 week Requested by: Johannes Lundberg <johalun0@gmail.com> Sponsored by: Mellanox Technologies
Notes
Notes: svn path=/head/; revision=330352
Diffstat (limited to 'sys/compat/linuxkpi/common')
-rw-r--r--sys/compat/linuxkpi/common/include/linux/delay.h14
-rw-r--r--sys/compat/linuxkpi/common/src/linux_schedule.c20
2 files changed, 31 insertions, 3 deletions
diff --git a/sys/compat/linuxkpi/common/include/linux/delay.h b/sys/compat/linuxkpi/common/include/linux/delay.h
index da38662087e4..32997071c2ae 100644
--- a/sys/compat/linuxkpi/common/include/linux/delay.h
+++ b/sys/compat/linuxkpi/common/include/linux/delay.h
@@ -36,13 +36,19 @@
#include <sys/systm.h>
static inline void
-linux_msleep(int ms)
+linux_msleep(unsigned int ms)
{
- pause("lnxsleep", msecs_to_jiffies(ms));
+ /* guard against invalid values */
+ if (ms == 0)
+ ms = 1;
+ pause_sbt("lnxsleep", SBT_1MS * ms, 0, C_HARDCLOCK);
}
#undef msleep
-#define msleep linux_msleep
+#define msleep(ms) linux_msleep(ms)
+
+#undef msleep_interruptible
+#define msleep_interruptible(ms) linux_msleep_interruptible(ms)
#define udelay(t) DELAY(t)
@@ -65,4 +71,6 @@ usleep_range(unsigned long min, unsigned long max)
DELAY(min);
}
+extern unsigned int linux_msleep_interruptible(unsigned int ms);
+
#endif /* _LINUX_DELAY_H_ */
diff --git a/sys/compat/linuxkpi/common/src/linux_schedule.c b/sys/compat/linuxkpi/common/src/linux_schedule.c
index 0958b3a53ff2..b91164773c5b 100644
--- a/sys/compat/linuxkpi/common/src/linux_schedule.c
+++ b/sys/compat/linuxkpi/common/src/linux_schedule.c
@@ -33,6 +33,7 @@ __FBSDID("$FreeBSD$");
#include <sys/signalvar.h>
#include <sys/sleepqueue.h>
+#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/list.h>
@@ -74,6 +75,25 @@ linux_add_to_sleepqueue(void *wchan, struct task_struct *task,
return (ret);
}
+unsigned int
+linux_msleep_interruptible(unsigned int ms)
+{
+ int ret;
+
+ /* guard against invalid values */
+ if (ms == 0)
+ ms = 1;
+ ret = -pause_sbt("lnxsleep", SBT_1MS * ms, 0, C_HARDCLOCK | C_CATCH);
+
+ switch (ret) {
+ case -EWOULDBLOCK:
+ return (0);
+ default:
+ linux_schedule_save_interrupt_value(current, ret);
+ return (ms);
+ }
+}
+
static int
wake_up_task(struct task_struct *task, unsigned int state)
{