Introduce SCHEDOP_block_masked, which blocks a VCPU without enabling
interrupts.
We need this as there are circumstances where we cannot take interrupts,
and are polling in a tight loop. In particular in Solaris's kernel
debugger console input. We don't want to burn CPU in a domU, but we're
not in a situation where we can safely use SCHEDOP_block.
regards,
john
# HG changeset patch
# User john.levon@xxxxxxx
# Node ID 55b48bec29e44c93d14c3f51f5ef58bc216a3e4b
# Parent fbeb0a5b7219630839986cf4cdb1b813618cbdce
Introduce SCHEDOP_block_masked.
Signed-off-by: John Levon <john.levon@xxxxxxx>
diff -r fbeb0a5b7219 -r 55b48bec29e4 docs/src/interface.tex
--- a/docs/src/interface.tex Thu Mar 9 16:24:57 2006 +0000
+++ b/docs/src/interface.tex Thu Mar 9 18:23:21 2006 -0800
@@ -1721,13 +1721,15 @@
\hypercall{sched\_op(unsigned long op)}
Request scheduling operation from hypervisor. The options are: {\it
-SCHEDOP\_yield}, {\it SCHEDOP\_block}, and {\it SCHEDOP\_shutdown}.
-{\it yield} keeps the calling domain runnable but may cause a
-reschedule if other domains are runnable. {\it block} removes the
-calling domain from the run queue and cause is to sleeps until an
-event is delivered to it. {\it shutdown} is used to end the domain's
-execution; the caller can additionally specify whether the domain
-should reboot, halt or suspend.
+SCHEDOP\_yield}, {\it SCHEDOP\_block}, {\it SCHEDOP\_block\_masked}
+and {\it SCHEDOP\_shutdown}. {\it yield} keeps the calling vcpu
+runnable but may cause a reschedule if other vcpus are runnable.
+{\it block} removes the calling vcpu from the run queue, enables
+events, and causes it to sleep until an event is delivered to it.
+{\it block\_masked} does the same, without enabling events.
+{\it shutdown} is used to end the domain's execution; the caller
+can additionally specify whether the domain should reboot, halt
+or suspend.
\end{quote}
To aid the implementation of a process scheduler within a guest OS,
diff -r fbeb0a5b7219 -r 55b48bec29e4 xen/common/schedule.c
--- a/xen/common/schedule.c Thu Mar 9 16:24:57 2006 +0000
+++ b/xen/common/schedule.c Thu Mar 9 18:23:21 2006 -0800
@@ -249,11 +249,13 @@
}
/* Block the currently-executing domain until a pertinent event occurs. */
-static long do_block(void)
+static void do_block(int clear_event_mask)
{
struct vcpu *v = current;
- v->vcpu_info->evtchn_upcall_mask = 0;
+ if ( clear_event_mask )
+ v->vcpu_info->evtchn_upcall_mask = 0;
+
set_bit(_VCPUF_blocked, &v->vcpu_flags);
/* Check for events /after/ blocking: avoids wakeup waiting race. */
@@ -266,8 +268,6 @@
TRACE_2D(TRC_SCHED_BLOCK, v->domain->domain_id, v->vcpu_id);
__enter_scheduler();
}
-
- return 0;
}
/* Voluntarily yield the processor for this allocation. */
@@ -292,7 +292,13 @@
case SCHEDOP_block:
{
- ret = do_block();
+ do_block(1);
+ break;
+ }
+
+ case SCHEDOP_block_masked:
+ {
+ do_block(0);
break;
}
diff -r fbeb0a5b7219 -r 55b48bec29e4 xen/include/public/sched.h
--- a/xen/include/public/sched.h Thu Mar 9 16:24:57 2006 +0000
+++ b/xen/include/public/sched.h Thu Mar 9 18:23:21 2006 -0800
@@ -20,7 +20,7 @@
* Voluntarily yield the CPU.
* @arg == 0.
*/
-#define SCHEDOP_yield 0
+#define SCHEDOP_yield 0
/*
* Block execution of this VCPU until an event is received for processing.
@@ -29,13 +29,22 @@
* VCPU. This avoids a "wakeup waiting" race.
* @arg == 0.
*/
-#define SCHEDOP_block 1
+#define SCHEDOP_block 1
/*
* Halt execution of this domain (all VCPUs) and notify the system controller.
* @arg == SHUTDOWN_??? (reason for shutdown).
*/
-#define SCHEDOP_shutdown 2
+#define SCHEDOP_shutdown 2
+
+/*
+ * Block execution of this VCPU until an event is received for processing,
+ * without clearing the upcall mask; a subsequent pending event will not be
+ * delivered, but will still wake up the domain. This is intended for use in
+ * polling loops when "interrupts" are disabled.
+ * @arg == 0.
+ */
+#define SCHEDOP_block_masked 3
/*
* Reason codes for SCHEDOP_shutdown. These may be interpreted by controller
diff -r fbeb0a5b7219 -r 55b48bec29e4 xen/include/xen/event.h
--- a/xen/include/xen/event.h Thu Mar 9 16:24:57 2006 +0000
+++ b/xen/include/xen/event.h Thu Mar 9 18:23:21 2006 -0800
@@ -14,6 +14,16 @@
#include <xen/smp.h>
#include <asm/bitops.h>
#include <asm/event.h>
+
+/*
+ * Is the domain under SCHEDOP_block_masked? If so, then we should unblock
+ * it even if the event channel is already pending.
+ */
+static inline void evtchn_check_unblock(struct vcpu *v)
+{
+ if ( v->vcpu_info->evtchn_upcall_mask && (v->vcpu_flags & VCPUF_blocked) )
+ vcpu_unblock(v);
+}
/*
* EVENT-CHANNEL NOTIFICATIONS
@@ -35,6 +45,10 @@
!test_and_set_bit(0, &v->vcpu_info->evtchn_upcall_pending) )
{
evtchn_notify(v);
+ }
+ else
+ {
+ evtchn_check_unblock(v);
}
}
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|