aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKeir Fraser <keir@xen.org>2010-12-15 12:06:56 +0000
committerKeir Fraser <keir@xen.org>2010-12-15 12:06:56 +0000
commit0ab088ce6d79a2922fb246eb3266b157acf64ac9 (patch)
tree9df7624ee500a5c8c82de56d7d11a4c6a851a56b
parentbb75b3bfdefd083a88cf2c041e4a7c0c8cc2777d (diff)
downloadxen-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.c9
-rw-r--r--xen/common/softirq.c10
-rw-r--r--xen/include/xen/softirq.h2
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