ia64/xen-unstable

changeset 10357:aced0ee216aa

[XEN] Fix SCHEDOP_poll to work even when event channels are
not bound to the polling VCPU.
Signed-off-by: Keir Fraser <keir@xensource.com>
author kaf24@firebug.cl.cam.ac.uk
date Sun Jun 11 19:23:31 2006 +0100 (2006-06-11)
parents d7543cff88ae
children 5b1bd9eab3b9
files xen/common/event_channel.c xen/common/schedule.c xen/include/xen/sched.h
line diff
     1.1 --- a/xen/common/event_channel.c	Sun Jun 11 14:33:16 2006 +0100
     1.2 +++ b/xen/common/event_channel.c	Sun Jun 11 19:23:31 2006 +0100
     1.3 @@ -498,14 +498,14 @@ void evtchn_set_pending(struct vcpu *v, 
     1.4      {
     1.5          evtchn_notify(v);
     1.6      }
     1.7 -    else if ( unlikely(test_bit(_VCPUF_blocked, &v->vcpu_flags) &&
     1.8 -                       !local_event_delivery_is_enabled()) )
     1.9 +    
    1.10 +    /* Check if some VCPU might be polling for this event. */
    1.11 +    if ( unlikely(test_bit(_DOMF_polling, &d->domain_flags)) &&
    1.12 +         likely(test_and_clear_bit(_DOMF_polling, &d->domain_flags)) )
    1.13      {
    1.14 -        /*
    1.15 -         * Blocked and masked will usually mean that the VCPU executed 
    1.16 -         * SCHEDOP_poll. Kick the VCPU in case this port is in its poll list.
    1.17 -         */
    1.18 -        vcpu_unblock(v);
    1.19 +        for_each_vcpu ( d, v )
    1.20 +            if ( test_and_clear_bit(_VCPUF_polling, &v->vcpu_flags) )
    1.21 +                vcpu_unblock(v);
    1.22      }
    1.23  }
    1.24  
    1.25 @@ -801,13 +801,6 @@ long do_event_channel_op(int cmd, XEN_GU
    1.26  }
    1.27  
    1.28  
    1.29 -void evtchn_notify_reserved_port(struct domain *d, int port)
    1.30 -{
    1.31 -    struct evtchn *chn = evtchn_from_port(d, port);
    1.32 -    evtchn_set_pending(d->vcpu[chn->notify_vcpu_id], port);
    1.33 -}
    1.34 -
    1.35 -
    1.36  int evtchn_init(struct domain *d)
    1.37  {
    1.38      spin_lock_init(&d->evtchn_lock);
     2.1 --- a/xen/common/schedule.c	Sun Jun 11 14:33:16 2006 +0100
     2.2 +++ b/xen/common/schedule.c	Sun Jun 11 19:23:31 2006 +0100
     2.3 @@ -230,13 +230,12 @@ static long do_poll(struct sched_poll *s
     2.4      if ( !guest_handle_okay(sched_poll->ports, sched_poll->nr_ports) )
     2.5          return -EFAULT;
     2.6  
     2.7 -    /* Ensure that events are disabled: tested by evtchn_set_pending(). */
     2.8 -    if ( local_event_delivery_is_enabled() )
     2.9 -        return -EINVAL;
    2.10 +    /* These operations must occur in order. */
    2.11 +    set_bit(_VCPUF_blocked, &v->vcpu_flags);
    2.12 +    set_bit(_VCPUF_polling, &v->vcpu_flags);
    2.13 +    set_bit(_DOMF_polling, &v->domain->domain_flags);
    2.14  
    2.15 -    set_bit(_VCPUF_blocked, &v->vcpu_flags);
    2.16 -
    2.17 -    /* Check for events /after/ blocking: avoids wakeup waiting race. */
    2.18 +    /* Check for events /after/ setting flags: avoids wakeup waiting race. */
    2.19      for ( i = 0; i < sched_poll->nr_ports; i++ )
    2.20      {
    2.21          rc = -EFAULT;
    2.22 @@ -261,6 +260,7 @@ static long do_poll(struct sched_poll *s
    2.23      stop_timer(&v->poll_timer);
    2.24  
    2.25   out:
    2.26 +    clear_bit(_VCPUF_polling, &v->vcpu_flags);
    2.27      clear_bit(_VCPUF_blocked, &v->vcpu_flags);
    2.28      return rc;
    2.29  }
    2.30 @@ -596,7 +596,8 @@ static void vcpu_timer_fn(void *data)
    2.31  static void poll_timer_fn(void *data)
    2.32  {
    2.33      struct vcpu *v = data;
    2.34 -    vcpu_unblock(v);
    2.35 +    if ( test_and_clear_bit(_VCPUF_polling, &v->vcpu_flags) )
    2.36 +        vcpu_unblock(v);
    2.37  }
    2.38  
    2.39  /* Initialise the data structures. */
     3.1 --- a/xen/include/xen/sched.h	Sun Jun 11 14:33:16 2006 +0100
     3.2 +++ b/xen/include/xen/sched.h	Sun Jun 11 19:23:31 2006 +0100
     3.3 @@ -355,7 +355,7 @@ extern struct domain *domain_list;
     3.4   /* Initialization completed. */
     3.5  #define _VCPUF_initialised     4
     3.6  #define VCPUF_initialised      (1UL<<_VCPUF_initialised)
     3.7 - /* VCPU is not-runnable */
     3.8 + /* VCPU is offline. */
     3.9  #define _VCPUF_down            5
    3.10  #define VCPUF_down             (1UL<<_VCPUF_down)
    3.11   /* NMI callback pending for this VCPU? */
    3.12 @@ -364,6 +364,9 @@ extern struct domain *domain_list;
    3.13   /* Avoid NMI reentry by allowing NMIs to be masked for short periods. */
    3.14  #define _VCPUF_nmi_masked      9
    3.15  #define VCPUF_nmi_masked       (1UL<<_VCPUF_nmi_masked)
    3.16 + /* VCPU is polling a set of event channels (SCHEDOP_poll). */
    3.17 +#define _VCPUF_polling         10
    3.18 +#define VCPUF_polling          (1UL<<_VCPUF_polling)
    3.19  
    3.20  /*
    3.21   * Per-domain flags (domain_flags).
    3.22 @@ -383,6 +386,9 @@ extern struct domain *domain_list;
    3.23   /* Domain is being debugged by controller software. */
    3.24  #define _DOMF_debugging        4
    3.25  #define DOMF_debugging         (1UL<<_DOMF_debugging)
    3.26 + /* Are any VCPUs polling event channels (SCHEDOP_poll)? */
    3.27 +#define _DOMF_polling          5
    3.28 +#define DOMF_polling           (1UL<<_DOMF_polling)
    3.29  
    3.30  static inline int vcpu_runnable(struct vcpu *v)
    3.31  {