diff options
author | Hans Petter Selasky <hselasky@FreeBSD.org> | 2018-03-03 18:54:16 +0000 |
---|---|---|
committer | Hans Petter Selasky <hselasky@FreeBSD.org> | 2018-03-03 18:54:16 +0000 |
commit | 7cf1c515882dadc9fac89f24a7061cd1aab683fa (patch) | |
tree | 3e0ba611552ff75890fbc9fcefe50cb0b863169d /sys/compat/linuxkpi/common | |
parent | 458915bfae50831d838d4cade3d24e84d1d24d2b (diff) | |
download | src-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.h | 14 | ||||
-rw-r--r-- | sys/compat/linuxkpi/common/src/linux_schedule.c | 20 |
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) { |