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
This commit is contained in:
Hans Petter Selasky 2018-03-03 18:54:16 +00:00
parent 458915bfae
commit 7cf1c51588
2 changed files with 31 additions and 3 deletions

View File

@ -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_ */

View File

@ -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)
{