ia64/xen-unstable

changeset 6110:9d0120a5aa45

Clean up event-channel notification code in Xen.
Signed-off-by: Keir Fraser <keir@xensource.com>
author kaf24@firebug.cl.cam.ac.uk
date Thu Aug 11 16:48:36 2005 +0000 (2005-08-11)
parents 37ac3cf33506
children 2f75dac09365
files xen/arch/ia64/vcpu.c xen/arch/x86/mm.c xen/include/asm-x86/event.h xen/include/xen/event.h xen/include/xen/sched.h
line diff
     1.1 --- a/xen/arch/ia64/vcpu.c	Thu Aug 11 16:23:54 2005 +0000
     1.2 +++ b/xen/arch/ia64/vcpu.c	Thu Aug 11 16:48:36 2005 +0000
     1.3 @@ -587,6 +587,14 @@ void vcpu_pend_interrupt(VCPU *vcpu, UIN
     1.4  	set_bit(vector,PSCBX(vcpu,irr));
     1.5  	PSCB(vcpu,pending_interruption) = 1;
     1.6      }
     1.7 +
     1.8 +    /* Keir: I think you should unblock when an interrupt is pending. */
     1.9 +    {
    1.10 +        int running = test_bit(_VCPUF_running, &vcpu->vcpu_flags);
    1.11 +        vcpu_unblock(vcpu);
    1.12 +        if ( running )
    1.13 +            smp_send_event_check_cpu(vcpu->processor);
    1.14 +    }
    1.15  }
    1.16  
    1.17  void early_tick(VCPU *vcpu)
     2.1 --- a/xen/arch/x86/mm.c	Thu Aug 11 16:23:54 2005 +0000
     2.2 +++ b/xen/arch/x86/mm.c	Thu Aug 11 16:48:36 2005 +0000
     2.3 @@ -95,6 +95,7 @@
     2.4  #include <xen/irq.h>
     2.5  #include <xen/softirq.h>
     2.6  #include <xen/domain_page.h>
     2.7 +#include <xen/event.h>
     2.8  #include <asm/shadow.h>
     2.9  #include <asm/page.h>
    2.10  #include <asm/flushtlb.h>
     3.1 --- a/xen/include/asm-x86/event.h	Thu Aug 11 16:23:54 2005 +0000
     3.2 +++ b/xen/include/asm-x86/event.h	Thu Aug 11 16:48:36 2005 +0000
     3.3 @@ -11,6 +11,19 @@
     3.4  
     3.5  static inline void evtchn_notify(struct vcpu *v)
     3.6  {
     3.7 +    /*
     3.8 +     * NB1. 'vcpu_flags' and 'processor' must be checked /after/ update of
     3.9 +     * pending flag. These values may fluctuate (after all, we hold no
    3.10 +     * locks) but the key insight is that each change will cause
    3.11 +     * evtchn_upcall_pending to be polled.
    3.12 +     * 
    3.13 +     * NB2. We save VCPUF_running across the unblock to avoid a needless
    3.14 +     * IPI for domains that we IPI'd to unblock.
    3.15 +     */
    3.16 +    int running = test_bit(_VCPUF_running, &v->vcpu_flags);
    3.17 +    vcpu_unblock(v);
    3.18 +    if ( running )
    3.19 +        smp_send_event_check_cpu(v->processor);
    3.20  }
    3.21  
    3.22  #endif
     4.1 --- a/xen/include/xen/event.h	Thu Aug 11 16:23:54 2005 +0000
     4.2 +++ b/xen/include/xen/event.h	Thu Aug 11 16:48:36 2005 +0000
     4.3 @@ -26,30 +26,14 @@ static inline void evtchn_set_pending(st
     4.4  {
     4.5      struct domain *d = v->domain;
     4.6      shared_info_t *s = d->shared_info;
     4.7 -    int            running;
     4.8  
     4.9 -    /* These three operations must happen in strict order. */
    4.10 +    /* These four operations must happen in strict order. */
    4.11      if ( !test_and_set_bit(port,    &s->evtchn_pending[0]) &&
    4.12           !test_bit        (port,    &s->evtchn_mask[0])    &&
    4.13 -         !test_and_set_bit(port>>5, &v->vcpu_info->evtchn_pending_sel) )
    4.14 +         !test_and_set_bit(port>>5, &v->vcpu_info->evtchn_pending_sel) &&
    4.15 +         !test_and_set_bit(0,       &v->vcpu_info->evtchn_upcall_pending) )
    4.16      {
    4.17 -        /* The VCPU pending flag must be set /after/ update to evtchn-pend. */
    4.18 -        set_bit(0, &v->vcpu_info->evtchn_upcall_pending);
    4.19          evtchn_notify(v);
    4.20 -
    4.21 -        /*
    4.22 -         * NB1. 'vcpu_flags' and 'processor' must be checked /after/ update of
    4.23 -         * pending flag. These values may fluctuate (after all, we hold no
    4.24 -         * locks) but the key insight is that each change will cause
    4.25 -         * evtchn_upcall_pending to be polled.
    4.26 -         * 
    4.27 -         * NB2. We save VCPUF_running across the unblock to avoid a needless
    4.28 -         * IPI for domains that we IPI'd to unblock.
    4.29 -         */
    4.30 -        running = test_bit(_VCPUF_running, &v->vcpu_flags);
    4.31 -        vcpu_unblock(v);
    4.32 -        if ( running )
    4.33 -            smp_send_event_check_cpu(v->processor);
    4.34      }
    4.35  }
    4.36  
    4.37 @@ -73,8 +57,9 @@ static inline void send_guest_virq(struc
    4.38   */
    4.39  extern void send_guest_pirq(struct domain *d, int pirq);
    4.40  
    4.41 -#define event_pending(_d)                                     \
    4.42 -    ((_d)->vcpu_info->evtchn_upcall_pending && \
    4.43 -     !(_d)->vcpu_info->evtchn_upcall_mask)
    4.44 +/* Note: Bitwise operations result in fast code with no branches. */
    4.45 +#define event_pending(v)                        \
    4.46 +    ((v)->vcpu_info->evtchn_upcall_pending &    \
    4.47 +     ~(v)->vcpu_info->evtchn_upcall_mask)
    4.48  
    4.49  #endif /* __XEN_EVENT_H__ */
     5.1 --- a/xen/include/xen/sched.h	Thu Aug 11 16:23:54 2005 +0000
     5.2 +++ b/xen/include/xen/sched.h	Thu Aug 11 16:48:36 2005 +0000
     5.3 @@ -297,10 +297,9 @@ unsigned long __hypercall_create_continu
     5.4          (unsigned long)(_a1), (unsigned long)(_a2), (unsigned long)(_a3), \
     5.5          (unsigned long)(_a4), (unsigned long)(_a5), (unsigned long)(_a6))
     5.6  
     5.7 -#define hypercall_preempt_check() (unlikely(            \
     5.8 -        softirq_pending(smp_processor_id()) |           \
     5.9 -        (!!current->vcpu_info->evtchn_upcall_pending &  \
    5.10 -          !current->vcpu_info->evtchn_upcall_mask)      \
    5.11 +#define hypercall_preempt_check() (unlikely(    \
    5.12 +        softirq_pending(smp_processor_id()) |   \
    5.13 +        event_pending(current)                  \
    5.14      ))
    5.15  
    5.16  /* This domain_hash and domain_list are protected by the domlist_lock. */