[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH] Add SCHEDOP_block_on
This patch adds a facility to block on a particular event channel, for when a domain needs to block, but cannot enable interrupts. A domain uses the call something like this: while (1) { clear_evtchn_pending(evtchn); if (check_for_data(evtchn)) break; HYPERVISOR_block_on(evtchn); } The clear of the pending is needed to ensure that any subsequent calls to block_on() don't return immediately. regards, john # HG changeset patch # User john.levon@xxxxxxx # Node ID 15aea7d020cd13b1f13692518f10051e401962df # Parent fbeb0a5b7219630839986cf4cdb1b813618cbdce Add SCHEDOP_block_on. Signed-off-by: John Levon <john.levon@xxxxxxx> diff -r fbeb0a5b7219 -r 15aea7d020cd 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 21:55:15 2006 -0800 @@ -1721,13 +1721,17 @@ \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\_on} and +{\it SCHEDOP\_shutdown}. {\it yield} keeps the calling vcpu runnable +but may cause a reschedule if other vcpus are runnable. {\it block} +enables event delivery, removes the calling vcpu from the run queue, +and causes it to sleep until an event is delivered to it. +{\it block\_on} causes the calling vcpu to sleep until any event is +delivered. It takes an event channel argument, which is checked to +see if it's pending; if it is, then the vcpu does not sleep. +{\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 15aea7d020cd 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 21:55:15 2006 -0800 @@ -249,7 +249,7 @@ } /* Block the currently-executing domain until a pertinent event occurs. */ -static long do_block(void) +static void do_block(void) { struct vcpu *v = current; @@ -258,6 +258,32 @@ /* Check for events /after/ blocking: avoids wakeup waiting race. */ if ( event_pending(v) ) + { + clear_bit(_VCPUF_blocked, &v->vcpu_flags); + } + else + { + TRACE_2D(TRC_SCHED_BLOCK, v->domain->domain_id, v->vcpu_id); + __enter_scheduler(); + } +} + +/* + * Block the currently-executing domain without enabling interrupts, for a + * particular evtchn. Whilst we check for a particular evtchn, /any/ event + * will wake us up again. + */ +static long do_block_on(unsigned long evtchn) +{ + struct vcpu *v = current; + + if ( evtchn >= MAX_EVTCHNS ) + return -EINVAL; + + set_bit(_VCPUF_blocked, &v->vcpu_flags); + + /* Check for event /after/ blocking: avoids wakeup waiting race. */ + if ( evtchn_pending(v->domain->shared_info, evtchn) ) { clear_bit(_VCPUF_blocked, &v->vcpu_flags); } @@ -292,7 +318,13 @@ case SCHEDOP_block: { - ret = do_block(); + do_block(); + break; + } + + case SCHEDOP_block_on: + { + ret = do_block_on(arg); break; } diff -r fbeb0a5b7219 -r 15aea7d020cd 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 21:55:15 2006 -0800 @@ -38,6 +38,16 @@ #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. It takes one argument; that of + * a channel to check for pending events before sleeping. + * @arg == evtchn. + */ +#define SCHEDOP_block_on 3 + +/* * Reason codes for SCHEDOP_shutdown. These may be interpreted by controller * software to determine the appropriate action. For the most part, Xen does * not care about the shutdown code. diff -r fbeb0a5b7219 -r 15aea7d020cd 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 21:55:15 2006 -0800 @@ -14,6 +14,16 @@ #include <xen/smp.h> #include <asm/bitops.h> #include <asm/event.h> + +/* + * If the vcpu has events masked, 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); } } @@ -69,4 +83,7 @@ /* Bind a local event-channel port to the specified VCPU. */ extern long evtchn_bind_vcpu(unsigned int port, unsigned int vcpu_id); +#define evtchn_pending(s, e) \ + (test_bit((e), &(s)->evtchn_pending[0])) + #endif /* __XEN_EVENT_H__ */ _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |