Hi!
Please consider attached patch:
Implement kpreempt_disable() on Linux by setting the scheduler to SCHED_FIFO
This seems to be the closest to no-preemption that unpatched Linux can
offer.
For details see:
http://linux.die.net/man/2/sched_setscheduler
Note: I suspect it might need #ifdef __linux__ wrap, but I'm not sure as the
interface is quite POSIXy. Anyone feel like testing?
Thanks
--
Robert Millan
diff --git a/lib/librumpuser/rumpuser.c b/lib/librumpuser/rumpuser.c
index a1e9068..0b5154c 100644
--- a/lib/librumpuser/rumpuser.c
+++ b/lib/librumpuser/rumpuser.c
@@ -47,6 +47,7 @@ __RCSID("$NetBSD: rumpuser.c,v 1.64 2014/11/05 00:43:55 pooka Exp $");
#include <string.h>
#include <time.h>
#include <unistd.h>
+#include <sched.h>
#include <rump/rumpuser.h>
@@ -76,6 +77,20 @@ rumpuser_init(int version, const struct rumpuser_hyperup *hyp)
return 0;
}
+/* Not quite, but hopefully close enough */
+int
+rumpuser_preempt_disable(void)
+{
+ struct sched_param param = {
+ .sched_priority = sched_get_priority_max(SCHED_FIFO),
+ };
+
+ if (sched_setscheduler(0, SCHED_FIFO, ¶m) != 0)
+ return errno;
+
+ return 0;
+}
+
int
rumpuser_clock_gettime(int enum_rumpclock, int64_t *sec, long *nsec)
{
diff --git a/sys/rump/include/rump/rumpuser.h b/sys/rump/include/rump/rumpuser.h
index 5bc9f8f..29d52dd 100644
--- a/sys/rump/include/rump/rumpuser.h
+++ b/sys/rump/include/rump/rumpuser.h
@@ -217,6 +217,8 @@ void rumpuser_cv_signal(struct rumpuser_cv *);
void rumpuser_cv_broadcast(struct rumpuser_cv *);
void rumpuser_cv_has_waiters(struct rumpuser_cv *, int *);
+int rumpuser_preempt_disable(void);
+
/*
* dynloader
*/
diff --git a/sys/rump/librump/rumpkern/scheduler.c b/sys/rump/librump/rumpkern/scheduler.c
index 8ebc82a..70cdd81 100644
--- a/sys/rump/librump/rumpkern/scheduler.c
+++ b/sys/rump/librump/rumpkern/scheduler.c
@@ -520,6 +520,7 @@ kpreempt(uintptr_t where)
void
kpreempt_disable(void)
{
+ (void) rumpuser_preempt_disable();
KPREEMPT_DISABLE(curlwp);
}