ia64/xen-unstable

changeset 947:c7dc2e589f8f

bitkeeper revision 1.603 (3fb3bacevrb8jueJUVr6_fTdAFNH3A)

ac_timer.h, schedule.c, network.c, ac_timer.c:
Cleaned up ac_timer interface, and fixed a bug in the softirq handler.
author kaf24@scramble.cl.cam.ac.uk
date Thu Nov 13 17:09:34 2003 +0000 (2003-11-13)
parents 7a554cbf0f58
children 7272f4d3fafe
files xen/common/ac_timer.c xen/common/network.c xen/common/schedule.c xen/include/xeno/ac_timer.h
line diff
     1.1 --- a/xen/common/ac_timer.c	Thu Nov 13 16:41:09 2003 +0000
     1.2 +++ b/xen/common/ac_timer.c	Thu Nov 13 17:09:34 2003 +0000
     1.3 @@ -246,6 +246,7 @@ static void ac_timer_softirq_action(stru
     1.4      int              cpu = smp_processor_id();
     1.5      struct ac_timer *t, **heap;
     1.6      s_time_t         now;
     1.7 +    void             (*fn)(unsigned long);
     1.8  
     1.9      spin_lock_irq(&ac_timers[cpu].lock);
    1.10      
    1.11 @@ -257,12 +258,15 @@ static void ac_timer_softirq_action(stru
    1.12                  ((t = heap[1])->expires < (now + TIMER_SLOP)) )
    1.13          {
    1.14              remove_entry(heap, t);
    1.15 -                        
    1.16 -            spin_unlock_irq(&ac_timers[cpu].lock);
    1.17 -            if ( t->function != NULL ) 
    1.18 -                t->function(t->data);
    1.19 -            spin_lock_irq(&ac_timers[cpu].lock);
    1.20 -            
    1.21 +
    1.22 +            if ( (fn = t->function) != NULL )
    1.23 +            {
    1.24 +                unsigned long data = t->data;
    1.25 +                spin_unlock_irq(&ac_timers[cpu].lock);
    1.26 +                (*fn)(data);
    1.27 +                spin_lock_irq(&ac_timers[cpu].lock);
    1.28 +            }
    1.29 +
    1.30              /* Heap may have grown while the lock was released. */
    1.31              heap = ac_timers[cpu].heap;
    1.32          }
     2.1 --- a/xen/common/network.c	Thu Nov 13 16:41:09 2003 +0000
     2.2 +++ b/xen/common/network.c	Thu Nov 13 17:09:34 2003 +0000
     2.3 @@ -107,7 +107,7 @@ net_vif_t *create_net_vif(int domain)
     2.4  
     2.5      new_vif->credit_bytes = new_vif->remaining_credit = ~0UL;
     2.6      new_vif->credit_usec  = 0UL;
     2.7 -    init_ac_timer(&new_vif->credit_timeout, 0);
     2.8 +    init_ac_timer(&new_vif->credit_timeout);
     2.9  
    2.10      if ( (p->domain == 0) && (dom_vif_idx == 0) )
    2.11      {
     3.1 --- a/xen/common/schedule.c	Thu Nov 13 16:41:09 2003 +0000
     3.2 +++ b/xen/common/schedule.c	Thu Nov 13 17:09:34 2003 +0000
     3.3 @@ -613,18 +613,21 @@ void __init scheduler_init(void)
     3.4          spin_lock_init(&schedule_data[i].lock);
     3.5          schedule_data[i].curr = &idle0_task;
     3.6          
     3.7 -        init_ac_timer(&schedule_data[i].s_timer, i);
     3.8 +        init_ac_timer(&schedule_data[i].s_timer);
     3.9 +        schedule_data[i].s_timer.cpu      = i;
    3.10          schedule_data[i].s_timer.data     = 2;
    3.11          schedule_data[i].s_timer.function = &sched_timer;
    3.12  
    3.13 -        init_ac_timer(&fallback_timer[i], i);
    3.14 +        init_ac_timer(&fallback_timer[i]);
    3.15 +        fallback_timer[i].cpu      = i;
    3.16          fallback_timer[i].data     = 0;
    3.17          fallback_timer[i].function = &fallback_timer_fn;
    3.18      }
    3.19  
    3.20      schedule_data[0].idle = &idle0_task;
    3.21  
    3.22 -    init_ac_timer(&v_timer, 0);
    3.23 +    init_ac_timer(&v_timer);
    3.24 +    v_timer.cpu      = 0;
    3.25      v_timer.data     = 0;
    3.26      v_timer.function = &virt_timer;
    3.27  }
     4.1 --- a/xen/include/xeno/ac_timer.h	Thu Nov 13 16:41:09 2003 +0000
     4.2 +++ b/xen/include/xeno/ac_timer.h	Thu Nov 13 17:09:34 2003 +0000
     4.3 @@ -20,52 +20,72 @@
     4.4  #ifndef _AC_TIMER_H_
     4.5  #define _AC_TIMER_H_
     4.6  
     4.7 -#include <xeno/time.h> /* include notion of time */
     4.8 -
     4.9 -/*
    4.10 - * The Xen Hypervisor provides two types of timers:
    4.11 - *
    4.12 - * - Linux style, jiffy based timers for legacy code and coarse grain timeouts
    4.13 - *   These are defined in ./include/xeno/timer.h and implemented in
    4.14 - *   ./common/timer.c. Unlike in Linux they are executed not on a periodic
    4.15 - *   timer interrupt but "occasionally" with somewhat lesser accuracy.
    4.16 - *  
    4.17 - * - accurate timers defined in this file and implemented in
    4.18 - *   ./common/ac_timer.c. These are implemented using a programmable timer
    4.19 - *   interrupt and are thus as accurate as the hardware allows. Where possible
    4.20 - *   we use the local APIC for this purpose. However, this fact is hidden
    4.21 - *   behind a architecture independent layer.
    4.22 - *   accurate timers are programmed using system time.
    4.23 - * 
    4.24 - * The interface to accurate timers is very similar to Linux timers with the
    4.25 - * exception that the expires value is not expressed in jiffies but in ns from
    4.26 - * boot time.  Its implementation however, is entirely different.
    4.27 - */
    4.28 +#include <xeno/time.h>
    4.29  
    4.30  struct ac_timer {
    4.31 -    s_time_t         expires;   /* system time time out value */
    4.32 +    /*
    4.33 +     * PUBLIC FIELDS
    4.34 +     */
    4.35 +    /* System time expiry value (nanoseconds since boot). */
    4.36 +    s_time_t         expires;
    4.37 +    /* CPU on which this timer will be installed and executed. */
    4.38 +    unsigned int     cpu;
    4.39 +    /* On expiry, '(*function)(data)' will be executed in softirq context. */
    4.40      unsigned long    data;
    4.41      void             (*function)(unsigned long);
    4.42 -    unsigned int     cpu;
    4.43 +
    4.44 +    /*
    4.45 +     * PRIVATE FIELDS
    4.46 +     */
    4.47      unsigned int     heap_offset;
    4.48  };
    4.49  
    4.50 -/* interface for "clients" */
    4.51 -extern void add_ac_timer(struct ac_timer *timer);
    4.52 -extern void rem_ac_timer(struct ac_timer *timer);
    4.53 -extern void mod_ac_timer(struct ac_timer *timer, s_time_t new_time);
    4.54 -static __inline__ void init_ac_timer(struct ac_timer *timer, int cpu)
    4.55 +/*
    4.56 + * This function can be called for any CPU from any CPU in any context.
    4.57 + * It initialises the private fields of the ac_timer structure.
    4.58 + */
    4.59 +static __inline__ void init_ac_timer(struct ac_timer *timer)
    4.60  {
    4.61 -    timer->cpu = cpu;
    4.62      timer->heap_offset = 0;
    4.63  }
    4.64 -/* check if ac_timer is active, i.e., on the list */
    4.65 +
    4.66 +/*
    4.67 + * This function can be called for any CPU from any CPU in any context.
    4.68 + * It returns TRUE if the given timer is on a timer list.
    4.69 + */
    4.70  static __inline__ int active_ac_timer(struct ac_timer *timer)
    4.71  {
    4.72      return (timer->heap_offset != 0);
    4.73  }
    4.74  
    4.75 -/* interface used by programmable timer, implemented hardware dependent */
    4.76 -extern int  reprogram_ac_timer(s_time_t timeout);
    4.77 +/*
    4.78 + * This function can be called for any CPU from any CPU in any context, BUT:
    4.79 + *  -- The private fields must have been initialised (ac_timer_init).
    4.80 + *  -- All public fields must be initialised.
    4.81 + *  -- The timer must not currently be on a timer list.
    4.82 + */
    4.83 +extern void add_ac_timer(struct ac_timer *timer);
    4.84 +
    4.85 +/*
    4.86 + * This function can be called for any CPU from any CPU in any context, BUT:
    4.87 + *  -- The private fields must have been initialised (ac_timer_init).
    4.88 + *  -- All public fields must be initialised.
    4.89 + *  -- The timer must currently be on a timer list.
    4.90 + */
    4.91 +extern void rem_ac_timer(struct ac_timer *timer);
    4.92 +
    4.93 +/*
    4.94 + * This function can be called for any CPU from any CPU in any context, BUT:
    4.95 + *  -- The private fields must have been initialised (ac_timer_init).
    4.96 + *  -- All public fields must be initialised.
    4.97 + */
    4.98 +extern void mod_ac_timer(struct ac_timer *timer, s_time_t new_time);
    4.99 +
   4.100 +
   4.101 +/*
   4.102 + * PRIVATE DEFINITIONS
   4.103 + */
   4.104 +
   4.105 +extern int reprogram_ac_timer(s_time_t timeout);
   4.106  
   4.107  #endif /* _AC_TIMER_H_ */