aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2010-02-11 21:08:06 +0000
committerKeir Fraser <keir.fraser@citrix.com>2010-02-11 21:08:06 +0000
commitc23d905c387ff80a7409d4f66cf91b02fa4297f0 (patch)
tree1015a9d16525fd8e0210bda78bbaa88f317812a6
parent8eddd7f405d7120aaf284c222e119588275bed3f (diff)
downloadxen-c23d905c387ff80a7409d4f66cf91b02fa4297f0.tar.gz
xen-c23d905c387ff80a7409d4f66cf91b02fa4297f0.tar.bz2
xen-c23d905c387ff80a7409d4f66cf91b02fa4297f0.zip
keyhandler: global shared scratch space for temporary strings
Put one static definition in one place and we can make it as big as we think reasonable. Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
-rw-r--r--xen/common/keyhandler.c23
-rw-r--r--xen/common/sched_credit.c7
-rw-r--r--xen/include/xen/keyhandler.h3
3 files changed, 24 insertions, 9 deletions
diff --git a/xen/common/keyhandler.c b/xen/common/keyhandler.c
index 9b4d6b7f12..78daf45a3d 100644
--- a/xen/common/keyhandler.c
+++ b/xen/common/keyhandler.c
@@ -20,19 +20,18 @@
static struct keyhandler *key_table[256];
static unsigned char keypress_key;
+char keyhandler_scratch[100];
+
static void keypress_action(unsigned long unused)
{
- unsigned char key = keypress_key;
- console_start_log_everything();
- if ( key_table[key] != NULL )
- (*key_table[key]->u.fn)(key);
- console_end_log_everything();
+ handle_keypress(keypress_key, NULL);
}
static DECLARE_TASKLET(keypress_tasklet, keypress_action, 0);
void handle_keypress(unsigned char key, struct cpu_user_regs *regs)
{
+ static bool_t executing_handler;
struct keyhandler *h;
if ( (h = key_table[key]) == NULL )
@@ -40,9 +39,18 @@ void handle_keypress(unsigned char key, struct cpu_user_regs *regs)
if ( !in_irq() || h->irq_callback )
{
+ /*
+ * No concurrent handler execution: prevents garbled console and
+ * protects keyhandler_scratch[].
+ */
+ if ( test_and_set_bool(executing_handler) )
+ return;
+ wmb();
console_start_log_everything();
- (*h->u.irq_fn)(key, regs);
+ h->irq_callback ? (*h->u.irq_fn)(key, regs) : (*h->u.fn)(key);
console_end_log_everything();
+ wmb();
+ executing_handler = 0;
}
else
{
@@ -174,7 +182,7 @@ static void dump_domains(unsigned char key)
struct domain *d;
struct vcpu *v;
s_time_t now = NOW();
- char tmpstr[100];
+#define tmpstr keyhandler_scratch
printk("'%c' pressed -> dumping domain info (now=0x%X:%08X)\n", key,
(u32)(now>>32), (u32)now);
@@ -234,6 +242,7 @@ static void dump_domains(unsigned char key)
}
rcu_read_unlock(&domlist_read_lock);
+#undef tmpstr
}
static struct keyhandler dump_domains_keyhandler = {
diff --git a/xen/common/sched_credit.c b/xen/common/sched_credit.c
index 8059bf1312..b0ccb0ccac 100644
--- a/xen/common/sched_credit.c
+++ b/xen/common/sched_credit.c
@@ -21,6 +21,7 @@
#include <xen/softirq.h>
#include <asm/atomic.h>
#include <xen/errno.h>
+#include <xen/keyhandler.h>
/*
* CSCHED_STATS
@@ -1241,7 +1242,7 @@ csched_dump_pcpu(int cpu)
struct csched_pcpu *spc;
struct csched_vcpu *svc;
int loop;
- char cpustr[100];
+#define cpustr keyhandler_scratch
spc = CSCHED_PCPU(cpu);
runq = &spc->runq;
@@ -1269,6 +1270,7 @@ csched_dump_pcpu(int cpu)
csched_dump_vcpu(svc);
}
}
+#undef cpustr
}
static void
@@ -1276,7 +1278,7 @@ csched_dump(void)
{
struct list_head *iter_sdom, *iter_svc;
int loop;
- char idlers_buf[100];
+#define idlers_buf keyhandler_scratch
printk("info:\n"
"\tncpus = %u\n"
@@ -1323,6 +1325,7 @@ csched_dump(void)
csched_dump_vcpu(svc);
}
}
+#undef idlers_buf
}
static void
diff --git a/xen/include/xen/keyhandler.h b/xen/include/xen/keyhandler.h
index 71e6dbe11c..1670d7d7f9 100644
--- a/xen/include/xen/keyhandler.h
+++ b/xen/include/xen/keyhandler.h
@@ -52,4 +52,7 @@ extern void register_keyhandler(unsigned char key, struct keyhandler *handler);
/* Inject a keypress into the key-handling subsystem. */
extern void handle_keypress(unsigned char key, struct cpu_user_regs *regs);
+/* Scratch space is available for use of any keyhandler. */
+extern char keyhandler_scratch[100];
+
#endif /* __XEN_KEYHANDLER_H__ */