# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID aced0ee216aa474c7883efa56eb918d4fe7d6098
# Parent d7543cff88ae4b9eb8a561dc72e6e126223ef720
[XEN] Fix SCHEDOP_poll to work even when event channels are
not bound to the polling VCPU.
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
---
xen/common/event_channel.c | 23 ++++++++---------------
xen/common/schedule.c | 15 ++++++++-------
xen/include/xen/sched.h | 8 +++++++-
3 files changed, 23 insertions(+), 23 deletions(-)
diff -r d7543cff88ae -r aced0ee216aa xen/common/event_channel.c
--- a/xen/common/event_channel.c Sun Jun 11 14:33:16 2006 +0100
+++ b/xen/common/event_channel.c Sun Jun 11 19:23:31 2006 +0100
@@ -498,14 +498,14 @@ void evtchn_set_pending(struct vcpu *v,
{
evtchn_notify(v);
}
- else if ( unlikely(test_bit(_VCPUF_blocked, &v->vcpu_flags) &&
- !local_event_delivery_is_enabled()) )
- {
- /*
- * Blocked and masked will usually mean that the VCPU executed
- * SCHEDOP_poll. Kick the VCPU in case this port is in its poll list.
- */
- vcpu_unblock(v);
+
+ /* Check if some VCPU might be polling for this event. */
+ if ( unlikely(test_bit(_DOMF_polling, &d->domain_flags)) &&
+ likely(test_and_clear_bit(_DOMF_polling, &d->domain_flags)) )
+ {
+ for_each_vcpu ( d, v )
+ if ( test_and_clear_bit(_VCPUF_polling, &v->vcpu_flags) )
+ vcpu_unblock(v);
}
}
@@ -801,13 +801,6 @@ long do_event_channel_op(int cmd, XEN_GU
}
-void evtchn_notify_reserved_port(struct domain *d, int port)
-{
- struct evtchn *chn = evtchn_from_port(d, port);
- evtchn_set_pending(d->vcpu[chn->notify_vcpu_id], port);
-}
-
-
int evtchn_init(struct domain *d)
{
spin_lock_init(&d->evtchn_lock);
diff -r d7543cff88ae -r aced0ee216aa xen/common/schedule.c
--- a/xen/common/schedule.c Sun Jun 11 14:33:16 2006 +0100
+++ b/xen/common/schedule.c Sun Jun 11 19:23:31 2006 +0100
@@ -230,13 +230,12 @@ static long do_poll(struct sched_poll *s
if ( !guest_handle_okay(sched_poll->ports, sched_poll->nr_ports) )
return -EFAULT;
- /* Ensure that events are disabled: tested by evtchn_set_pending(). */
- if ( local_event_delivery_is_enabled() )
- return -EINVAL;
-
+ /* These operations must occur in order. */
set_bit(_VCPUF_blocked, &v->vcpu_flags);
-
- /* Check for events /after/ blocking: avoids wakeup waiting race. */
+ set_bit(_VCPUF_polling, &v->vcpu_flags);
+ set_bit(_DOMF_polling, &v->domain->domain_flags);
+
+ /* Check for events /after/ setting flags: avoids wakeup waiting race. */
for ( i = 0; i < sched_poll->nr_ports; i++ )
{
rc = -EFAULT;
@@ -261,6 +260,7 @@ static long do_poll(struct sched_poll *s
stop_timer(&v->poll_timer);
out:
+ clear_bit(_VCPUF_polling, &v->vcpu_flags);
clear_bit(_VCPUF_blocked, &v->vcpu_flags);
return rc;
}
@@ -596,7 +596,8 @@ static void poll_timer_fn(void *data)
static void poll_timer_fn(void *data)
{
struct vcpu *v = data;
- vcpu_unblock(v);
+ if ( test_and_clear_bit(_VCPUF_polling, &v->vcpu_flags) )
+ vcpu_unblock(v);
}
/* Initialise the data structures. */
diff -r d7543cff88ae -r aced0ee216aa xen/include/xen/sched.h
--- a/xen/include/xen/sched.h Sun Jun 11 14:33:16 2006 +0100
+++ b/xen/include/xen/sched.h Sun Jun 11 19:23:31 2006 +0100
@@ -355,7 +355,7 @@ extern struct domain *domain_list;
/* Initialization completed. */
#define _VCPUF_initialised 4
#define VCPUF_initialised (1UL<<_VCPUF_initialised)
- /* VCPU is not-runnable */
+ /* VCPU is offline. */
#define _VCPUF_down 5
#define VCPUF_down (1UL<<_VCPUF_down)
/* NMI callback pending for this VCPU? */
@@ -364,6 +364,9 @@ extern struct domain *domain_list;
/* Avoid NMI reentry by allowing NMIs to be masked for short periods. */
#define _VCPUF_nmi_masked 9
#define VCPUF_nmi_masked (1UL<<_VCPUF_nmi_masked)
+ /* VCPU is polling a set of event channels (SCHEDOP_poll). */
+#define _VCPUF_polling 10
+#define VCPUF_polling (1UL<<_VCPUF_polling)
/*
* Per-domain flags (domain_flags).
@@ -383,6 +386,9 @@ extern struct domain *domain_list;
/* Domain is being debugged by controller software. */
#define _DOMF_debugging 4
#define DOMF_debugging (1UL<<_DOMF_debugging)
+ /* Are any VCPUs polling event channels (SCHEDOP_poll)? */
+#define _DOMF_polling 5
+#define DOMF_polling (1UL<<_DOMF_polling)
static inline int vcpu_runnable(struct vcpu *v)
{
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|