diff options
author | Keir Fraser <keir@xen.org> | 2010-12-15 12:06:56 +0000 |
---|---|---|
committer | Keir Fraser <keir@xen.org> | 2010-12-15 12:06:56 +0000 |
commit | 0ab088ce6d79a2922fb246eb3266b157acf64ac9 (patch) | |
tree | 9df7624ee500a5c8c82de56d7d11a4c6a851a56b | |
parent | bb75b3bfdefd083a88cf2c041e4a7c0c8cc2777d (diff) | |
download | xen-0ab088ce6d79a2922fb246eb3266b157acf64ac9.tar.gz xen-0ab088ce6d79a2922fb246eb3266b157acf64ac9.tar.bz2 xen-0ab088ce6d79a2922fb246eb3266b157acf64ac9.zip |
Reduce side effects of handling '*' debug key
NMI watchdog should be suppressed when dumping IRQ handlers. Softirqs
should be handled periodically while processing non-IRQ handlers.
Signed-off-by: Jan Beulich <jbeulich@novell.com>
xen-unstable changeset: 22538:a3a29e67aa7e
xen-unstable date: Wed Dec 15 12:04:34 2010 +0000
-rw-r--r-- | xen/common/keyhandler.c | 9 | ||||
-rw-r--r-- | xen/common/softirq.c | 10 | ||||
-rw-r--r-- | xen/include/xen/softirq.h | 2 |
3 files changed, 17 insertions, 4 deletions
diff --git a/xen/common/keyhandler.c b/xen/common/keyhandler.c index 2419c74d01..5ddd489a0e 100644 --- a/xen/common/keyhandler.c +++ b/xen/common/keyhandler.c @@ -375,16 +375,15 @@ static void run_all_nonirq_keyhandlers(unsigned long unused) struct keyhandler *h; int k; - console_start_log_everything(); for ( k = 0; k < ARRAY_SIZE(key_table); k++ ) { + process_pending_softirqs_nested(); h = key_table[k]; if ( (h == NULL) || !h->diagnostic || h->irq_callback ) continue; printk("[%c: %s]\n", k, h->desc); (*h->u.fn)(k); } - console_end_log_everything(); } static DECLARE_TASKLET(run_all_keyhandlers_tasklet, @@ -395,10 +394,11 @@ static void run_all_keyhandlers(unsigned char key, struct cpu_user_regs *regs) struct keyhandler *h; int k; + watchdog_disable(); + printk("'%c' pressed -> firing all diagnostic keyhandlers\n", key); /* Fire all the IRQ-context diangostic keyhandlers now */ - console_start_log_everything(); for ( k = 0; k < ARRAY_SIZE(key_table); k++ ) { h = key_table[k]; @@ -407,7 +407,8 @@ static void run_all_keyhandlers(unsigned char key, struct cpu_user_regs *regs) printk("[%c: %s]\n", k, h->desc); (*h->u.irq_fn)(k, regs); } - console_end_log_everything(); + + watchdog_enable(); /* Trigger the others from a tasklet in non-IRQ context */ tasklet_schedule(&run_all_keyhandlers_tasklet); diff --git a/xen/common/softirq.c b/xen/common/softirq.c index 7b04f36f2d..906b51ea42 100644 --- a/xen/common/softirq.c +++ b/xen/common/softirq.c @@ -54,6 +54,16 @@ void process_pending_softirqs(void) __do_softirq(1ul<<SCHEDULE_SOFTIRQ); } +void process_pending_softirqs_nested(void) +{ + ASSERT(!in_irq() && local_irq_is_enabled()); + /* + * Do not enter scheduler as it can preempt the calling context, + * and do not run tasklets as we're running one currently. + */ + __do_softirq((1ul<<SCHEDULE_SOFTIRQ) | (1ul<<TASKLET_SOFTIRQ)); +} + asmlinkage void do_softirq(void) { __do_softirq(0); diff --git a/xen/include/xen/softirq.h b/xen/include/xen/softirq.h index b02c8e2509..2c9dba7cb1 100644 --- a/xen/include/xen/softirq.h +++ b/xen/include/xen/softirq.h @@ -39,6 +39,8 @@ void raise_softirq(unsigned int nr); * Use this instead of do_softirq() when you do not want to be preempted. */ void process_pending_softirqs(void); +/* ... and use this instead when running inside a tasklet. */ +void process_pending_softirqs_nested(void); /* * TASKLETS -- dynamically-allocatable tasks run in softirq context |