ia64/xen-unstable

changeset 2804:d301dd777023

bitkeeper revision 1.1159.1.320 (4186495166A8XLekEbNixl7hWUA08w)

Clean up softirq handling. All debug keypresses are now deferred to
a softirq handler.
author kaf24@freefall.cl.cam.ac.uk
date Mon Nov 01 14:33:53 2004 +0000 (2004-11-01)
parents 2c7a372de2d0
children b7f0cff13881 a5beee8013f5 667064cbe09d
files xen/arch/x86/irq.c xen/arch/x86/memory.c xen/arch/x86/pdb-stub.c xen/common/ac_timer.c xen/common/keyhandler.c xen/common/perfc.c xen/common/schedule.c xen/common/softirq.c xen/drivers/char/console.c xen/include/asm-x86/bitops.h xen/include/xen/keyhandler.h xen/include/xen/softirq.h
line diff
     1.1 --- a/xen/arch/x86/irq.c	Mon Nov 01 10:00:03 2004 +0000
     1.2 +++ b/xen/arch/x86/irq.c	Mon Nov 01 14:33:53 2004 +0000
     1.3 @@ -210,16 +210,17 @@ static void __do_IRQ_guest(int irq)
     1.4  int pirq_guest_unmask(struct domain *d)
     1.5  {
     1.6      irq_desc_t    *desc;
     1.7 -    int            i, j, pirq;
     1.8 +    unsigned int   i, j, pirq;
     1.9      u32            m;
    1.10      shared_info_t *s = d->shared_info;
    1.11  
    1.12      for ( i = 0; i < ARRAY_SIZE(d->pirq_mask); i++ )
    1.13      {
    1.14          m = d->pirq_mask[i];
    1.15 -        while ( (j = ffs(m)) != 0 )
    1.16 +        while ( m != 0 )
    1.17          {
    1.18 -            m &= ~(1 << --j);
    1.19 +            j = find_first_set_bit(m);
    1.20 +            m &= ~(1 << j);
    1.21              pirq = (i << 5) + j;
    1.22              desc = &irq_desc[pirq];
    1.23              spin_lock_irq(&desc->lock);
     2.1 --- a/xen/arch/x86/memory.c	Mon Nov 01 10:00:03 2004 +0000
     2.2 +++ b/xen/arch/x86/memory.c	Mon Nov 01 14:33:53 2004 +0000
     2.3 @@ -2261,11 +2261,9 @@ void audit_domains(void)
     2.4          audit_domain(d);
     2.5  }
     2.6  
     2.7 -void audit_domains_key(unsigned char key, void *dev_id,
     2.8 -                       struct pt_regs *regs)
     2.9 +void audit_domains_key(unsigned char key)
    2.10  {
    2.11 -    open_softirq(MEMAUDIT_SOFTIRQ, audit_domains);
    2.12 -    raise_softirq(MEMAUDIT_SOFTIRQ);
    2.13 +    audit_domains();
    2.14  }
    2.15  
    2.16  #endif
     3.1 --- a/xen/arch/x86/pdb-stub.c	Mon Nov 01 10:00:03 2004 +0000
     3.2 +++ b/xen/arch/x86/pdb-stub.c	Mon Nov 01 14:33:53 2004 +0000
     3.3 @@ -1213,17 +1213,12 @@ int pdb_handle_exception(int exceptionVe
     3.4      return 0;
     3.5  }
     3.6  
     3.7 -void __pdb_key_pressed(void)
     3.8 +void pdb_key_pressed(unsigned char key)
     3.9  {
    3.10      struct pt_regs *regs = (struct pt_regs *)get_execution_context();
    3.11      pdb_handle_exception(KEYPRESS_EXCEPTION, regs);
    3.12  }
    3.13  
    3.14 -void pdb_key_pressed(u_char key, void *dev_id, struct pt_regs *regs) 
    3.15 -{
    3.16 -    raise_softirq(DEBUGGER_SOFTIRQ);
    3.17 -}
    3.18 -
    3.19  void initialize_pdb()
    3.20  {
    3.21      extern char opt_pdb[];
    3.22 @@ -1254,7 +1249,6 @@ void initialize_pdb()
    3.23      /* Acknowledge any spurious GDB packets. */
    3.24      pdb_put_char('+');
    3.25  
    3.26 -    open_softirq(DEBUGGER_SOFTIRQ, __pdb_key_pressed);
    3.27      add_key_handler('D', pdb_key_pressed, "enter pervasive debugger");
    3.28  
    3.29      pdb_initialized = 1;
     4.1 --- a/xen/common/ac_timer.c	Mon Nov 01 10:00:03 2004 +0000
     4.2 +++ b/xen/common/ac_timer.c	Mon Nov 01 14:33:53 2004 +0000
     4.3 @@ -244,7 +244,7 @@ static void ac_timer_softirq_action(void
     4.4  }
     4.5  
     4.6  
     4.7 -static void dump_timerq(u_char key, void *dev_id, struct pt_regs *regs)
     4.8 +static void dump_timerq(unsigned char key)
     4.9  {
    4.10      struct ac_timer *t;
    4.11      unsigned long    flags; 
     5.1 --- a/xen/common/keyhandler.c	Mon Nov 01 10:00:03 2004 +0000
     5.2 +++ b/xen/common/keyhandler.c	Mon Nov 01 14:33:53 2004 +0000
     5.3 @@ -5,6 +5,7 @@
     5.4  #include <xen/console.h>
     5.5  #include <xen/serial.h>
     5.6  #include <xen/sched.h>
     5.7 +#include <xen/softirq.h>
     5.8  
     5.9  #define KEY_MAX 256
    5.10  #define STR_MAX  64
    5.11 @@ -14,6 +15,22 @@ static struct {
    5.12      char         desc[STR_MAX]; 
    5.13  } key_table[KEY_MAX]; 
    5.14  
    5.15 +static unsigned char keypress_key;
    5.16 +
    5.17 +void keypress_softirq(void)
    5.18 +{
    5.19 +    key_handler  *h;
    5.20 +    unsigned char key = keypress_key;
    5.21 +    if ( (h = key_table[key].handler) != NULL )
    5.22 +        (*h)(key);
    5.23 +}
    5.24 +
    5.25 +void handle_keypress(unsigned char key)
    5.26 +{
    5.27 +    keypress_key = key;
    5.28 +    raise_softirq(KEYPRESS_SOFTIRQ);
    5.29 +}
    5.30 +
    5.31  void add_key_handler(unsigned char key, key_handler *handler, char *desc)
    5.32  {
    5.33      key_table[key].handler = handler; 
    5.34 @@ -21,13 +38,7 @@ void add_key_handler(unsigned char key, 
    5.35      key_table[key].desc[STR_MAX-1] = '\0'; 
    5.36  }
    5.37  
    5.38 -key_handler *get_key_handler(unsigned char key)
    5.39 -{
    5.40 -    return key_table[key].handler; 
    5.41 -}
    5.42 -
    5.43 -static void show_handlers(unsigned char key, void *dev_id,
    5.44 -                          struct pt_regs *regs)
    5.45 +static void show_handlers(unsigned char key)
    5.46  {
    5.47      int i; 
    5.48      printk("'%c' pressed -> showing installed handlers\n", key);
    5.49 @@ -39,23 +50,21 @@ static void show_handlers(unsigned char 
    5.50  }
    5.51  
    5.52  
    5.53 -static void dump_registers(unsigned char key, void *dev_id,
    5.54 -                           struct pt_regs *regs)
    5.55 +static void dump_registers(unsigned char key)
    5.56  {
    5.57 +    struct pt_regs *regs = (struct pt_regs *)get_execution_context();
    5.58      extern void show_registers(struct pt_regs *regs); 
    5.59      printk("'%c' pressed -> dumping registers\n", key); 
    5.60      show_registers(regs); 
    5.61  }
    5.62  
    5.63 -static void halt_machine(unsigned char key, void *dev_id,
    5.64 -                         struct pt_regs *regs) 
    5.65 +static void halt_machine(unsigned char key)
    5.66  {
    5.67      printk("'%c' pressed -> rebooting machine\n", key); 
    5.68      machine_restart(NULL); 
    5.69  }
    5.70  
    5.71 -void do_task_queues(unsigned char key, void *dev_id,
    5.72 -                    struct pt_regs *regs) 
    5.73 +void do_task_queues(unsigned char key)
    5.74  {
    5.75      unsigned long  flags;
    5.76      struct domain *d;
    5.77 @@ -102,26 +111,22 @@ void do_task_queues(unsigned char key, v
    5.78      read_unlock_irqrestore(&tasklist_lock, flags); 
    5.79  }
    5.80  
    5.81 -extern void dump_runq(unsigned char key, void *dev_id, 
    5.82 -                      struct pt_regs *regs);
    5.83 -extern void print_sched_histo(unsigned char key, void *dev_id, 
    5.84 -                              struct pt_regs *regs);
    5.85 -extern void reset_sched_histo(unsigned char key, void *dev_id, 
    5.86 -                              struct pt_regs *regs);
    5.87 +extern void dump_runq(unsigned char key);
    5.88 +extern void print_sched_histo(unsigned char key);
    5.89 +extern void reset_sched_histo(unsigned char key);
    5.90  #ifndef NDEBUG
    5.91 -extern void audit_domains_key(unsigned char key, void *dev_id,
    5.92 -                           struct pt_regs *regs);
    5.93 +extern void audit_domains_key(unsigned char key);
    5.94  #endif
    5.95  
    5.96  #ifdef PERF_COUNTERS
    5.97 -extern void perfc_printall(unsigned char key, void *dev_id,
    5.98 -                           struct pt_regs *regs);
    5.99 -extern void perfc_reset(unsigned char key, void *dev_id,
   5.100 -                        struct pt_regs *regs);
   5.101 +extern void perfc_printall(unsigned char key);
   5.102 +extern void perfc_reset(unsigned char key);
   5.103  #endif
   5.104  
   5.105  void initialize_keytable(void)
   5.106  {
   5.107 +    open_softirq(KEYPRESS_SOFTIRQ, keypress_softirq);
   5.108 +
   5.109      add_key_handler('d', dump_registers, "dump registers"); 
   5.110      add_key_handler('h', show_handlers, "show this message");
   5.111      add_key_handler('l', print_sched_histo, "print sched latency histogram");
     6.1 --- a/xen/common/perfc.c	Mon Nov 01 10:00:03 2004 +0000
     6.2 +++ b/xen/common/perfc.c	Mon Nov 01 14:33:53 2004 +0000
     6.3 @@ -31,7 +31,7 @@ static struct {
     6.4  
     6.5  struct perfcounter_t perfcounters;
     6.6  
     6.7 -void perfc_printall(u_char key, void *dev_id, struct pt_regs *regs)
     6.8 +void perfc_printall(unsigned char key)
     6.9  {
    6.10      int i, j, sum;
    6.11      s_time_t now = NOW();
    6.12 @@ -73,7 +73,7 @@ void perfc_printall(u_char key, void *de
    6.13      }
    6.14  }
    6.15  
    6.16 -void perfc_reset(u_char key, void *dev_id, struct pt_regs *regs)
    6.17 +void perfc_reset(unsigned char key)
    6.18  {
    6.19      int i, j, sum;
    6.20      s_time_t now = NOW();
    6.21 @@ -82,7 +82,7 @@ void perfc_reset(u_char key, void *dev_i
    6.22      printk("Xen performance counters RESET (now = 0x%08X:%08X)\n",
    6.23             (u32)(now>>32), (u32)now);
    6.24  
    6.25 -    // leave STATUS counters alone -- don't reset
    6.26 +    /* leave STATUS counters alone -- don't reset */
    6.27  
    6.28      for ( i = 0; i < NR_PERFCTRS; i++ ) 
    6.29      {
     7.1 --- a/xen/common/schedule.c	Mon Nov 01 10:00:03 2004 +0000
     7.2 +++ b/xen/common/schedule.c	Mon Nov 01 14:33:53 2004 +0000
     7.3 @@ -544,7 +544,7 @@ void schedulers_start(void)
     7.4  }
     7.5  
     7.6  
     7.7 -void dump_runq(u_char key, void *dev_id, struct pt_regs *regs)
     7.8 +void dump_runq(unsigned char key)
     7.9  {
    7.10      s_time_t      now = NOW();
    7.11      int           i;
    7.12 @@ -568,7 +568,7 @@ void dump_runq(u_char key, void *dev_id,
    7.13  }
    7.14  
    7.15  #if defined(WAKE_HISTO) || defined(BLOCKTIME_HISTO)
    7.16 -void print_sched_histo(u_char key, void *dev_id, struct pt_regs *regs)
    7.17 +void print_sched_histo(unsigned char key)
    7.18  {
    7.19      int i, j, k;
    7.20      for ( k = 0; k < smp_num_cpus; k++ )
    7.21 @@ -591,7 +591,7 @@ void print_sched_histo(u_char key, void 
    7.22      }
    7.23        
    7.24  }
    7.25 -void reset_sched_histo(u_char key, void *dev_id, struct pt_regs *regs)
    7.26 +void reset_sched_histo(unsigned char key)
    7.27  {
    7.28      int i, j;
    7.29      for ( j = 0; j < smp_num_cpus; j++ )
    7.30 @@ -599,10 +599,6 @@ void reset_sched_histo(u_char key, void 
    7.31              schedule_data[j].hist[i] = 0;
    7.32  }
    7.33  #else
    7.34 -void print_sched_histo(u_char key, void *dev_id, struct pt_regs *regs)
    7.35 -{
    7.36 -}
    7.37 -void reset_sched_histo(u_char key, void *dev_id, struct pt_regs *regs)
    7.38 -{
    7.39 -}
    7.40 +void print_sched_histo(unsigned char key) { }
    7.41 +void reset_sched_histo(unsigned char key) { }
    7.42  #endif
     8.1 --- a/xen/common/softirq.c	Mon Nov 01 10:00:03 2004 +0000
     8.2 +++ b/xen/common/softirq.c	Mon Nov 01 14:33:53 2004 +0000
     8.3 @@ -21,19 +21,13 @@ static softirq_handler softirq_handlers[
     8.4  
     8.5  asmlinkage void do_softirq()
     8.6  {
     8.7 -    unsigned int pending, cpu = smp_processor_id();
     8.8 -    softirq_handler *h;
     8.9 +    unsigned int i, pending, cpu = smp_processor_id();
    8.10  
    8.11 -    while ( (pending = xchg(&softirq_pending(cpu), 0)) != 0 )
    8.12 +    while ( (pending = softirq_pending(cpu)) != 0 )
    8.13      {
    8.14 -        h = softirq_handlers;
    8.15 -        while ( pending )
    8.16 -        {
    8.17 -            if ( pending & 1 )
    8.18 -                (*h)();
    8.19 -            h++;
    8.20 -            pending >>= 1;
    8.21 -        }
    8.22 +        i = find_first_set_bit(pending);
    8.23 +        clear_bit(i, &softirq_pending(cpu));
    8.24 +        (*softirq_handlers[i])();
    8.25      }
    8.26  }
    8.27  
     9.1 --- a/xen/drivers/char/console.c	Mon Nov 01 10:00:03 2004 +0000
     9.2 +++ b/xen/drivers/char/console.c	Mon Nov 01 14:33:53 2004 +0000
     9.3 @@ -245,22 +245,20 @@ static void switch_serial_input(void)
     9.4  
     9.5  static void __serial_rx(unsigned char c, struct pt_regs *regs)
     9.6  {
     9.7 -    key_handler *handler;
     9.8 -    struct domain *p;
     9.9 +    struct domain *d;
    9.10  
    9.11      if ( xen_rx )
    9.12      {
    9.13 -        if ( (handler = get_key_handler(c)) != NULL )
    9.14 -            (*handler)(c, NULL, regs);
    9.15 +        handle_keypress(c);
    9.16      }
    9.17      else if ( (serial_rx_prod-serial_rx_cons) != SERIAL_RX_SIZE )
    9.18      {
    9.19          serial_rx_ring[SERIAL_RX_MASK(serial_rx_prod)] = c;
    9.20          if ( serial_rx_prod++ == serial_rx_cons )
    9.21          {
    9.22 -            p = find_domain_by_id(0); /* only DOM0 reads the serial buffer */
    9.23 -            send_guest_virq(p, VIRQ_CONSOLE);
    9.24 -            put_domain(p);
    9.25 +            d = find_domain_by_id(0); /* only DOM0 reads the serial buffer */
    9.26 +            send_guest_virq(d, VIRQ_CONSOLE);
    9.27 +            put_domain(d);
    9.28          }
    9.29      }
    9.30  }
    10.1 --- a/xen/include/asm-x86/bitops.h	Mon Nov 01 10:00:03 2004 +0000
    10.2 +++ b/xen/include/asm-x86/bitops.h	Mon Nov 01 14:33:53 2004 +0000
    10.3 @@ -340,6 +340,27 @@ static __inline__ int ffs(int x)
    10.4  	return r+1;
    10.5  }
    10.6  
    10.7 +/*
    10.8 + * These are the preferred 'find first' functions in Xen.
    10.9 + * Both return the appropriate bit index, with the l.s.b. having index 0.
   10.10 + * If an appropriate bit is not found then the result is undefined.
   10.11 + */
   10.12 +static __inline__ unsigned long find_first_clear_bit(unsigned long word)
   10.13 +{
   10.14 +	__asm__("bsf"__OS" %1,%0"
   10.15 +		:"=r" (word)
   10.16 +		:"r" (~word));
   10.17 +	return word;
   10.18 +}
   10.19 +
   10.20 +static __inline__ unsigned long find_first_set_bit(unsigned long word)
   10.21 +{
   10.22 +	__asm__("bsf"__OS" %1,%0"
   10.23 +		:"=r" (word)
   10.24 +		:"r" (word));
   10.25 +	return word;
   10.26 +}
   10.27 +
   10.28  /**
   10.29   * hweightN - returns the hamming weight of a N-bit word
   10.30   * @x: the word to weigh
    11.1 --- a/xen/include/xen/keyhandler.h	Mon Nov 01 10:00:03 2004 +0000
    11.2 +++ b/xen/include/xen/keyhandler.h	Mon Nov 01 14:33:53 2004 +0000
    11.3 @@ -6,11 +6,10 @@
    11.4  */
    11.5  #include <xen/sched.h>
    11.6  
    11.7 -typedef void key_handler(unsigned char key, void *dev_id, 
    11.8 -			 struct pt_regs *regs); 
    11.9 +typedef void key_handler(unsigned char key);
   11.10  
   11.11  extern void add_key_handler(unsigned char key, 
   11.12  			    key_handler *handler, char *desc); 
   11.13  
   11.14 -extern key_handler *get_key_handler(unsigned char key); 
   11.15 +extern void handle_keypress(unsigned char key);
   11.16  
    12.1 --- a/xen/include/xen/softirq.h	Mon Nov 01 10:00:03 2004 +0000
    12.2 +++ b/xen/include/xen/softirq.h	Mon Nov 01 14:33:53 2004 +0000
    12.3 @@ -1,13 +1,13 @@
    12.4  #ifndef __XEN_SOFTIRQ_H__
    12.5  #define __XEN_SOFTIRQ_H__
    12.6  
    12.7 +/* Common softirqs come first in the following list. */
    12.8  #define AC_TIMER_SOFTIRQ                  0
    12.9 -#define NEW_TLBFLUSH_CLOCK_PERIOD_SOFTIRQ 1
   12.10 -#define DEBUGGER_SOFTIRQ                  2
   12.11 -#define NMI_SOFTIRQ                       3
   12.12 -#define SCHEDULE_SOFTIRQ                  4
   12.13 -#define MEMAUDIT_SOFTIRQ                  5
   12.14 -#define NR_SOFTIRQS                       6
   12.15 +#define SCHEDULE_SOFTIRQ                  1
   12.16 +#define NEW_TLBFLUSH_CLOCK_PERIOD_SOFTIRQ 2
   12.17 +#define KEYPRESS_SOFTIRQ                  3
   12.18 +#define NMI_SOFTIRQ                       4
   12.19 +#define NR_SOFTIRQS                       5
   12.20  
   12.21  #ifndef __ASSEMBLY__
   12.22