# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID 5461e2e86e989375b707f25bf93d3d4074b80920
# Parent df221e310e2b4f162167147aa3d7656af3969417
[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-unstable changeset: 10319:aced0ee216aa474c7883efa56eb918d4fe7d6098
xen-unstable date: Sun Jun 11 19:23:31 2006 +0100
---
xen/common/event_channel.c | 16 ++++++++--------
xen/common/schedule.c | 15 ++++++++-------
xen/include/xen/sched.h | 8 +++++++-
3 files changed, 23 insertions(+), 16 deletions(-)
diff -r df221e310e2b -r 5461e2e86e98 xen/common/event_channel.c
--- a/xen/common/event_channel.c Sun Jun 11 10:10:59 2006 +0100
+++ b/xen/common/event_channel.c Sun Jun 11 19:28:57 2006 +0100
@@ -460,14 +460,14 @@ void evtchn_set_pending(struct vcpu *v,
{
evtchn_notify(v);
}
- else if ( unlikely(test_bit(_VCPUF_blocked, &v->vcpu_flags) &&
- v->vcpu_info->evtchn_upcall_mask) )
- {
- /*
- * 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);
}
}
diff -r df221e310e2b -r 5461e2e86e98 xen/common/schedule.c
--- a/xen/common/schedule.c Sun Jun 11 10:10:59 2006 +0100
+++ b/xen/common/schedule.c Sun Jun 11 19:28:57 2006 +0100
@@ -297,13 +297,12 @@ static long do_poll(struct sched_poll *s
if ( !guest_handle_okay(sched_poll->ports, sched_poll->nr_ports) )
return -EFAULT;
- /* Ensure that upcalls are disabled: tested by evtchn_set_pending(). */
- if ( !v->vcpu_info->evtchn_upcall_mask )
- 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;
@@ -328,6 +327,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;
}
@@ -637,7 +637,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 df221e310e2b -r 5461e2e86e98 xen/include/xen/sched.h
--- a/xen/include/xen/sched.h Sun Jun 11 10:10:59 2006 +0100
+++ b/xen/include/xen/sched.h Sun Jun 11 19:28:57 2006 +0100
@@ -356,7 +356,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? */
@@ -365,6 +365,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).
@@ -384,6 +387,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
|