diff options
author | kaf24@freefall.cl.cam.ac.uk <kaf24@freefall.cl.cam.ac.uk> | 2004-11-01 14:33:53 +0000 |
---|---|---|
committer | kaf24@freefall.cl.cam.ac.uk <kaf24@freefall.cl.cam.ac.uk> | 2004-11-01 14:33:53 +0000 |
commit | b73cc6b15c701015848ed3556d20066a315f3e38 (patch) | |
tree | 4a9a20aa3b10dfded84ac1ae3cf1bf56985e1019 | |
parent | 1b354ce174983eab7c4885325b7e04c45edcd0c3 (diff) | |
download | xen-b73cc6b15c701015848ed3556d20066a315f3e38.tar.gz xen-b73cc6b15c701015848ed3556d20066a315f3e38.tar.bz2 xen-b73cc6b15c701015848ed3556d20066a315f3e38.zip |
bitkeeper revision 1.1159.1.320 (4186495166A8XLekEbNixl7hWUA08w)
Clean up softirq handling. All debug keypresses are now deferred to
a softirq handler.
-rw-r--r-- | xen/arch/x86/irq.c | 7 | ||||
-rw-r--r-- | xen/arch/x86/memory.c | 6 | ||||
-rw-r--r-- | xen/arch/x86/pdb-stub.c | 8 | ||||
-rw-r--r-- | xen/common/ac_timer.c | 2 | ||||
-rw-r--r-- | xen/common/keyhandler.c | 55 | ||||
-rw-r--r-- | xen/common/perfc.c | 6 | ||||
-rw-r--r-- | xen/common/schedule.c | 14 | ||||
-rw-r--r-- | xen/common/softirq.c | 16 | ||||
-rw-r--r-- | xen/drivers/char/console.c | 12 | ||||
-rw-r--r-- | xen/include/asm-x86/bitops.h | 21 | ||||
-rw-r--r-- | xen/include/xen/keyhandler.h | 5 | ||||
-rw-r--r-- | xen/include/xen/softirq.h | 12 |
12 files changed, 85 insertions, 79 deletions
diff --git a/xen/arch/x86/irq.c b/xen/arch/x86/irq.c index 2ed656549c..b3534c0df5 100644 --- a/xen/arch/x86/irq.c +++ b/xen/arch/x86/irq.c @@ -210,16 +210,17 @@ static void __do_IRQ_guest(int irq) int pirq_guest_unmask(struct domain *d) { irq_desc_t *desc; - int i, j, pirq; + unsigned int i, j, pirq; u32 m; shared_info_t *s = d->shared_info; for ( i = 0; i < ARRAY_SIZE(d->pirq_mask); i++ ) { m = d->pirq_mask[i]; - while ( (j = ffs(m)) != 0 ) + while ( m != 0 ) { - m &= ~(1 << --j); + j = find_first_set_bit(m); + m &= ~(1 << j); pirq = (i << 5) + j; desc = &irq_desc[pirq]; spin_lock_irq(&desc->lock); diff --git a/xen/arch/x86/memory.c b/xen/arch/x86/memory.c index 410829cc72..39345ed7a3 100644 --- a/xen/arch/x86/memory.c +++ b/xen/arch/x86/memory.c @@ -2261,11 +2261,9 @@ void audit_domains(void) audit_domain(d); } -void audit_domains_key(unsigned char key, void *dev_id, - struct pt_regs *regs) +void audit_domains_key(unsigned char key) { - open_softirq(MEMAUDIT_SOFTIRQ, audit_domains); - raise_softirq(MEMAUDIT_SOFTIRQ); + audit_domains(); } #endif diff --git a/xen/arch/x86/pdb-stub.c b/xen/arch/x86/pdb-stub.c index 774167c88b..a1eb36b0f2 100644 --- a/xen/arch/x86/pdb-stub.c +++ b/xen/arch/x86/pdb-stub.c @@ -1213,17 +1213,12 @@ int pdb_handle_exception(int exceptionVector, return 0; } -void __pdb_key_pressed(void) +void pdb_key_pressed(unsigned char key) { struct pt_regs *regs = (struct pt_regs *)get_execution_context(); pdb_handle_exception(KEYPRESS_EXCEPTION, regs); } -void pdb_key_pressed(u_char key, void *dev_id, struct pt_regs *regs) -{ - raise_softirq(DEBUGGER_SOFTIRQ); -} - void initialize_pdb() { extern char opt_pdb[]; @@ -1254,7 +1249,6 @@ void initialize_pdb() /* Acknowledge any spurious GDB packets. */ pdb_put_char('+'); - open_softirq(DEBUGGER_SOFTIRQ, __pdb_key_pressed); add_key_handler('D', pdb_key_pressed, "enter pervasive debugger"); pdb_initialized = 1; diff --git a/xen/common/ac_timer.c b/xen/common/ac_timer.c index 658fea3457..ddef6d33c3 100644 --- a/xen/common/ac_timer.c +++ b/xen/common/ac_timer.c @@ -244,7 +244,7 @@ static void ac_timer_softirq_action(void) } -static void dump_timerq(u_char key, void *dev_id, struct pt_regs *regs) +static void dump_timerq(unsigned char key) { struct ac_timer *t; unsigned long flags; diff --git a/xen/common/keyhandler.c b/xen/common/keyhandler.c index 48860e43c9..96ac0d6bd6 100644 --- a/xen/common/keyhandler.c +++ b/xen/common/keyhandler.c @@ -5,6 +5,7 @@ #include <xen/console.h> #include <xen/serial.h> #include <xen/sched.h> +#include <xen/softirq.h> #define KEY_MAX 256 #define STR_MAX 64 @@ -14,6 +15,22 @@ static struct { char desc[STR_MAX]; } key_table[KEY_MAX]; +static unsigned char keypress_key; + +void keypress_softirq(void) +{ + key_handler *h; + unsigned char key = keypress_key; + if ( (h = key_table[key].handler) != NULL ) + (*h)(key); +} + +void handle_keypress(unsigned char key) +{ + keypress_key = key; + raise_softirq(KEYPRESS_SOFTIRQ); +} + void add_key_handler(unsigned char key, key_handler *handler, char *desc) { key_table[key].handler = handler; @@ -21,13 +38,7 @@ void add_key_handler(unsigned char key, key_handler *handler, char *desc) key_table[key].desc[STR_MAX-1] = '\0'; } -key_handler *get_key_handler(unsigned char key) -{ - return key_table[key].handler; -} - -static void show_handlers(unsigned char key, void *dev_id, - struct pt_regs *regs) +static void show_handlers(unsigned char key) { int i; printk("'%c' pressed -> showing installed handlers\n", key); @@ -39,23 +50,21 @@ static void show_handlers(unsigned char key, void *dev_id, } -static void dump_registers(unsigned char key, void *dev_id, - struct pt_regs *regs) +static void dump_registers(unsigned char key) { + struct pt_regs *regs = (struct pt_regs *)get_execution_context(); extern void show_registers(struct pt_regs *regs); printk("'%c' pressed -> dumping registers\n", key); show_registers(regs); } -static void halt_machine(unsigned char key, void *dev_id, - struct pt_regs *regs) +static void halt_machine(unsigned char key) { printk("'%c' pressed -> rebooting machine\n", key); machine_restart(NULL); } -void do_task_queues(unsigned char key, void *dev_id, - struct pt_regs *regs) +void do_task_queues(unsigned char key) { unsigned long flags; struct domain *d; @@ -102,26 +111,22 @@ void do_task_queues(unsigned char key, void *dev_id, read_unlock_irqrestore(&tasklist_lock, flags); } -extern void dump_runq(unsigned char key, void *dev_id, - struct pt_regs *regs); -extern void print_sched_histo(unsigned char key, void *dev_id, - struct pt_regs *regs); -extern void reset_sched_histo(unsigned char key, void *dev_id, - struct pt_regs *regs); +extern void dump_runq(unsigned char key); +extern void print_sched_histo(unsigned char key); +extern void reset_sched_histo(unsigned char key); #ifndef NDEBUG -extern void audit_domains_key(unsigned char key, void *dev_id, - struct pt_regs *regs); +extern void audit_domains_key(unsigned char key); #endif #ifdef PERF_COUNTERS -extern void perfc_printall(unsigned char key, void *dev_id, - struct pt_regs *regs); -extern void perfc_reset(unsigned char key, void *dev_id, - struct pt_regs *regs); +extern void perfc_printall(unsigned char key); +extern void perfc_reset(unsigned char key); #endif void initialize_keytable(void) { + open_softirq(KEYPRESS_SOFTIRQ, keypress_softirq); + add_key_handler('d', dump_registers, "dump registers"); add_key_handler('h', show_handlers, "show this message"); add_key_handler('l', print_sched_histo, "print sched latency histogram"); diff --git a/xen/common/perfc.c b/xen/common/perfc.c index 631e81787c..3a05c2e071 100644 --- a/xen/common/perfc.c +++ b/xen/common/perfc.c @@ -31,7 +31,7 @@ static struct { struct perfcounter_t perfcounters; -void perfc_printall(u_char key, void *dev_id, struct pt_regs *regs) +void perfc_printall(unsigned char key) { int i, j, sum; s_time_t now = NOW(); @@ -73,7 +73,7 @@ void perfc_printall(u_char key, void *dev_id, struct pt_regs *regs) } } -void perfc_reset(u_char key, void *dev_id, struct pt_regs *regs) +void perfc_reset(unsigned char key) { int i, j, sum; s_time_t now = NOW(); @@ -82,7 +82,7 @@ void perfc_reset(u_char key, void *dev_id, struct pt_regs *regs) printk("Xen performance counters RESET (now = 0x%08X:%08X)\n", (u32)(now>>32), (u32)now); - // leave STATUS counters alone -- don't reset + /* leave STATUS counters alone -- don't reset */ for ( i = 0; i < NR_PERFCTRS; i++ ) { diff --git a/xen/common/schedule.c b/xen/common/schedule.c index 138234104d..c037c9e177 100644 --- a/xen/common/schedule.c +++ b/xen/common/schedule.c @@ -544,7 +544,7 @@ void schedulers_start(void) } -void dump_runq(u_char key, void *dev_id, struct pt_regs *regs) +void dump_runq(unsigned char key) { s_time_t now = NOW(); int i; @@ -568,7 +568,7 @@ void dump_runq(u_char key, void *dev_id, struct pt_regs *regs) } #if defined(WAKE_HISTO) || defined(BLOCKTIME_HISTO) -void print_sched_histo(u_char key, void *dev_id, struct pt_regs *regs) +void print_sched_histo(unsigned char key) { int i, j, k; for ( k = 0; k < smp_num_cpus; k++ ) @@ -591,7 +591,7 @@ void print_sched_histo(u_char key, void *dev_id, struct pt_regs *regs) } } -void reset_sched_histo(u_char key, void *dev_id, struct pt_regs *regs) +void reset_sched_histo(unsigned char key) { int i, j; for ( j = 0; j < smp_num_cpus; j++ ) @@ -599,10 +599,6 @@ void reset_sched_histo(u_char key, void *dev_id, struct pt_regs *regs) schedule_data[j].hist[i] = 0; } #else -void print_sched_histo(u_char key, void *dev_id, struct pt_regs *regs) -{ -} -void reset_sched_histo(u_char key, void *dev_id, struct pt_regs *regs) -{ -} +void print_sched_histo(unsigned char key) { } +void reset_sched_histo(unsigned char key) { } #endif diff --git a/xen/common/softirq.c b/xen/common/softirq.c index 3e1472e94a..166a8163c1 100644 --- a/xen/common/softirq.c +++ b/xen/common/softirq.c @@ -21,19 +21,13 @@ static softirq_handler softirq_handlers[NR_SOFTIRQS] __cacheline_aligned; asmlinkage void do_softirq() { - unsigned int pending, cpu = smp_processor_id(); - softirq_handler *h; + unsigned int i, pending, cpu = smp_processor_id(); - while ( (pending = xchg(&softirq_pending(cpu), 0)) != 0 ) + while ( (pending = softirq_pending(cpu)) != 0 ) { - h = softirq_handlers; - while ( pending ) - { - if ( pending & 1 ) - (*h)(); - h++; - pending >>= 1; - } + i = find_first_set_bit(pending); + clear_bit(i, &softirq_pending(cpu)); + (*softirq_handlers[i])(); } } diff --git a/xen/drivers/char/console.c b/xen/drivers/char/console.c index 350cf09cbd..a6a979284c 100644 --- a/xen/drivers/char/console.c +++ b/xen/drivers/char/console.c @@ -245,22 +245,20 @@ static void switch_serial_input(void) static void __serial_rx(unsigned char c, struct pt_regs *regs) { - key_handler *handler; - struct domain *p; + struct domain *d; if ( xen_rx ) { - if ( (handler = get_key_handler(c)) != NULL ) - (*handler)(c, NULL, regs); + handle_keypress(c); } else if ( (serial_rx_prod-serial_rx_cons) != SERIAL_RX_SIZE ) { serial_rx_ring[SERIAL_RX_MASK(serial_rx_prod)] = c; if ( serial_rx_prod++ == serial_rx_cons ) { - p = find_domain_by_id(0); /* only DOM0 reads the serial buffer */ - send_guest_virq(p, VIRQ_CONSOLE); - put_domain(p); + d = find_domain_by_id(0); /* only DOM0 reads the serial buffer */ + send_guest_virq(d, VIRQ_CONSOLE); + put_domain(d); } } } diff --git a/xen/include/asm-x86/bitops.h b/xen/include/asm-x86/bitops.h index 58ae424e54..cf98f2e118 100644 --- a/xen/include/asm-x86/bitops.h +++ b/xen/include/asm-x86/bitops.h @@ -340,6 +340,27 @@ static __inline__ int ffs(int x) return r+1; } +/* + * These are the preferred 'find first' functions in Xen. + * Both return the appropriate bit index, with the l.s.b. having index 0. + * If an appropriate bit is not found then the result is undefined. + */ +static __inline__ unsigned long find_first_clear_bit(unsigned long word) +{ + __asm__("bsf"__OS" %1,%0" + :"=r" (word) + :"r" (~word)); + return word; +} + +static __inline__ unsigned long find_first_set_bit(unsigned long word) +{ + __asm__("bsf"__OS" %1,%0" + :"=r" (word) + :"r" (word)); + return word; +} + /** * hweightN - returns the hamming weight of a N-bit word * @x: the word to weigh diff --git a/xen/include/xen/keyhandler.h b/xen/include/xen/keyhandler.h index 03aa53bab5..d12621ef33 100644 --- a/xen/include/xen/keyhandler.h +++ b/xen/include/xen/keyhandler.h @@ -6,11 +6,10 @@ */ #include <xen/sched.h> -typedef void key_handler(unsigned char key, void *dev_id, - struct pt_regs *regs); +typedef void key_handler(unsigned char key); extern void add_key_handler(unsigned char key, key_handler *handler, char *desc); -extern key_handler *get_key_handler(unsigned char key); +extern void handle_keypress(unsigned char key); diff --git a/xen/include/xen/softirq.h b/xen/include/xen/softirq.h index 7bf05b9f46..6180dae775 100644 --- a/xen/include/xen/softirq.h +++ b/xen/include/xen/softirq.h @@ -1,13 +1,13 @@ #ifndef __XEN_SOFTIRQ_H__ #define __XEN_SOFTIRQ_H__ +/* Common softirqs come first in the following list. */ #define AC_TIMER_SOFTIRQ 0 -#define NEW_TLBFLUSH_CLOCK_PERIOD_SOFTIRQ 1 -#define DEBUGGER_SOFTIRQ 2 -#define NMI_SOFTIRQ 3 -#define SCHEDULE_SOFTIRQ 4 -#define MEMAUDIT_SOFTIRQ 5 -#define NR_SOFTIRQS 6 +#define SCHEDULE_SOFTIRQ 1 +#define NEW_TLBFLUSH_CLOCK_PERIOD_SOFTIRQ 2 +#define KEYPRESS_SOFTIRQ 3 +#define NMI_SOFTIRQ 4 +#define NR_SOFTIRQS 5 #ifndef __ASSEMBLY__ |