WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] Add a single trigger for all diagnostic k

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] Add a single trigger for all diagnostic keyhandlers
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Tue, 04 Aug 2009 08:50:26 -0700
Delivery-date: Tue, 04 Aug 2009 08:52:02 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1249216995 -3600
# Node ID 68e8b8379244e293c55875e7dc3692fc81d3d212
# Parent  a23057f52f147919ab99e9c8c327aa15c12c2510
Add a single trigger for all diagnostic keyhandlers

Add a new keyhandler that triggers all the side-effect-free
keyhandlers.  This lets automated tests (and users) log the full set
of keyhandlers without having to be aware of which ones might reboot
the host.

Signed-off-by: Tim Deegan <Tim.Deegan@xxxxxxxxxx>
Signed-off-by: Keir Fraser <keir.fraser@xxxxxxxxxx>
---
 xen/arch/x86/acpi/cpu_idle.c         |    9 +
 xen/arch/x86/hvm/svm/vmcb.c          |    8 +
 xen/arch/x86/hvm/vmx/vmcs.c          |    8 +
 xen/arch/x86/io_apic.c               |    9 +
 xen/arch/x86/irq.c                   |    8 +
 xen/arch/x86/mm/shadow/common.c      |   15 ++
 xen/arch/x86/nmi.c                   |   15 ++
 xen/arch/x86/numa.c                  |    8 +
 xen/common/event_channel.c           |    8 +
 xen/common/kexec.c                   |    7 +
 xen/common/keyhandler.c              |  203 +++++++++++++++++++++++------------
 xen/common/page_alloc.c              |   17 ++
 xen/common/timer.c                   |    7 +
 xen/drivers/char/console.c           |    8 +
 xen/drivers/passthrough/pci.c        |    8 +
 xen/drivers/passthrough/vtd/extern.h |    3 
 xen/drivers/passthrough/vtd/iommu.c  |    2 
 xen/drivers/passthrough/vtd/utils.c  |    8 +
 xen/include/xen/keyhandler.h         |   47 +++++---
 19 files changed, 293 insertions(+), 105 deletions(-)

diff -r a23057f52f14 -r 68e8b8379244 xen/arch/x86/acpi/cpu_idle.c
--- a/xen/arch/x86/acpi/cpu_idle.c      Sun Aug 02 12:29:25 2009 +0100
+++ b/xen/arch/x86/acpi/cpu_idle.c      Sun Aug 02 13:43:15 2009 +0100
@@ -108,10 +108,15 @@ static void dump_cx(unsigned char key)
             print_acpi_power(cpu, processor_powers[cpu]);
 }
 
+static struct keyhandler dump_cx_keyhandler = {
+    .diagnostic = 1,
+    .u.fn = dump_cx,
+    .desc = "dump ACPI Cx structures"
+};
+
 static int __init cpu_idle_key_init(void)
 {
-    register_keyhandler(
-        'c', dump_cx,        "dump ACPI Cx structures");
+    register_keyhandler('c', &dump_cx_keyhandler);
     return 0;
 }
 __initcall(cpu_idle_key_init);
diff -r a23057f52f14 -r 68e8b8379244 xen/arch/x86/hvm/svm/vmcb.c
--- a/xen/arch/x86/hvm/svm/vmcb.c       Sun Aug 02 12:29:25 2009 +0100
+++ b/xen/arch/x86/hvm/svm/vmcb.c       Sun Aug 02 13:43:15 2009 +0100
@@ -395,9 +395,15 @@ static void vmcb_dump(unsigned char ch)
     printk("**************************************\n");
 }
 
+static struct keyhandler vmcb_dump_keyhandler = {
+    .diagnostic = 1,
+    .u.fn = vmcb_dump,
+    .desc = "dump AMD-V VMCBs"
+};
+
 void setup_vmcb_dump(void)
 {
-    register_keyhandler('v', vmcb_dump, "dump AMD-V VMCBs");
+    register_keyhandler('v', &vmcb_dump_keyhandler);
 }
 
 /*
diff -r a23057f52f14 -r 68e8b8379244 xen/arch/x86/hvm/vmx/vmcs.c
--- a/xen/arch/x86/hvm/vmx/vmcs.c       Sun Aug 02 12:29:25 2009 +0100
+++ b/xen/arch/x86/hvm/vmx/vmcs.c       Sun Aug 02 13:43:15 2009 +0100
@@ -1143,9 +1143,15 @@ static void vmcs_dump(unsigned char ch)
     printk("**************************************\n");
 }
 
+static struct keyhandler vmcs_dump_keyhandler = {
+    .diagnostic = 1,
+    .u.fn = vmcs_dump,
+    .desc = "dump Intel's VMCS"
+};
+
 void setup_vmcs_dump(void)
 {
-    register_keyhandler('v', vmcs_dump, "dump Intel's VMCS");
+    register_keyhandler('v', &vmcs_dump_keyhandler);
 }
 
 
diff -r a23057f52f14 -r 68e8b8379244 xen/arch/x86/io_apic.c
--- a/xen/arch/x86/io_apic.c    Sun Aug 02 12:29:25 2009 +0100
+++ b/xen/arch/x86/io_apic.c    Sun Aug 02 13:43:15 2009 +0100
@@ -953,10 +953,15 @@ void print_IO_APIC(void)
         __print_IO_APIC();
 }
 
-void print_IO_APIC_keyhandler(unsigned char key)
+static void _print_IO_APIC_keyhandler(unsigned char key)
 {
     __print_IO_APIC();
 }
+static struct keyhandler print_IO_APIC_keyhandler = {
+    .diagnostic = 1,
+    .u.fn = _print_IO_APIC_keyhandler,
+    .desc = "print ioapic info"
+};
 
 static void __init enable_IO_APIC(void)
 {
@@ -1810,7 +1815,7 @@ void __init setup_IO_APIC(void)
     print_IO_APIC();
     ioapic_pm_state_alloc();
 
-    register_keyhandler('z', print_IO_APIC_keyhandler, "print ioapic info");
+    register_keyhandler('z', &print_IO_APIC_keyhandler);
 }
 
 void ioapic_suspend(void)
diff -r a23057f52f14 -r 68e8b8379244 xen/arch/x86/irq.c
--- a/xen/arch/x86/irq.c        Sun Aug 02 12:29:25 2009 +0100
+++ b/xen/arch/x86/irq.c        Sun Aug 02 13:43:15 2009 +0100
@@ -1139,9 +1139,15 @@ static void dump_irqs(unsigned char key)
     dump_ioapic_irq_info();
 }
 
+static struct keyhandler dump_irqs_keyhandler = {
+    .diagnostic = 1,
+    .u.fn = dump_irqs,
+    .desc = "dump interrupt bindings"
+};
+
 static int __init setup_dump_irqs(void)
 {
-    register_keyhandler('i', dump_irqs, "dump interrupt bindings");
+    register_keyhandler('i', &dump_irqs_keyhandler);
     return 0;
 }
 __initcall(setup_dump_irqs);
diff -r a23057f52f14 -r 68e8b8379244 xen/arch/x86/mm/shadow/common.c
--- a/xen/arch/x86/mm/shadow/common.c   Sun Aug 02 12:29:25 2009 +0100
+++ b/xen/arch/x86/mm/shadow/common.c   Sun Aug 02 13:43:15 2009 +0100
@@ -94,10 +94,14 @@ static void shadow_audit_key(unsigned ch
            __func__, shadow_audit_enable);
 }
 
+static struct keyhandler shadow_audit_keyhandler = {
+    .u.fn = shadow_audit_key,
+    .desc = "toggle shadow audits"
+};
+
 static int __init shadow_audit_key_init(void)
 {
-    register_keyhandler(
-        'O', shadow_audit_key,  "toggle shadow audits");
+    register_keyhandler('O', &shadow_audit_keyhandler);
     return 0;
 }
 __initcall(shadow_audit_key_init);
@@ -1482,10 +1486,15 @@ static void shadow_blow_all_tables(unsig
     rcu_read_unlock(&domlist_read_lock);
 }
 
+static struct keyhandler shadow_blow_all_tables_keyhandler = {
+    .u.fn = shadow_blow_all_tables,
+    .desc = "reset shadow pagetables"
+};
+
 /* Register this function in the Xen console keypress table */
 static __init int shadow_blow_tables_keyhandler_init(void)
 {
-    register_keyhandler('S', shadow_blow_all_tables,"reset shadow pagetables");
+    register_keyhandler('S', &shadow_blow_all_tables_keyhandler);
     return 0;
 }
 __initcall(shadow_blow_tables_keyhandler_init);
diff -r a23057f52f14 -r 68e8b8379244 xen/arch/x86/nmi.c
--- a/xen/arch/x86/nmi.c        Sun Aug 02 12:29:25 2009 +0100
+++ b/xen/arch/x86/nmi.c        Sun Aug 02 13:43:15 2009 +0100
@@ -453,6 +453,11 @@ static void do_nmi_trigger(unsigned char
     local_irq_enable();
 }
 
+static struct keyhandler nmi_trigger_keyhandler = {
+    .u.fn = do_nmi_trigger,
+    .desc = "trigger an NMI"
+};
+
 static void do_nmi_stats(unsigned char key)
 {
     int i;
@@ -475,10 +480,16 @@ static void do_nmi_stats(unsigned char k
         printk("dom0 vcpu0: NMI neither pending nor masked\n");
 }
 
+static struct keyhandler nmi_stats_keyhandler = {
+    .diagnostic = 1,
+    .u.fn = do_nmi_stats,
+    .desc = "NMI statistics"
+};
+
 static __init int register_nmi_trigger(void)
 {
-    register_keyhandler('n', do_nmi_trigger, "trigger an NMI");
-    register_keyhandler('N', do_nmi_stats,   "NMI statistics");
+    register_keyhandler('N', &nmi_trigger_keyhandler);
+    register_keyhandler('n', &nmi_stats_keyhandler);
     return 0;
 }
 __initcall(register_nmi_trigger);
diff -r a23057f52f14 -r 68e8b8379244 xen/arch/x86/numa.c
--- a/xen/arch/x86/numa.c       Sun Aug 02 12:29:25 2009 +0100
+++ b/xen/arch/x86/numa.c       Sun Aug 02 13:43:15 2009 +0100
@@ -325,9 +325,15 @@ static void dump_numa(unsigned char key)
        rcu_read_unlock(&domlist_read_lock);
 }
 
+static struct keyhandler dump_numa_keyhandler = {
+       .diagnostic = 1,
+       .u.fn = dump_numa,
+       .desc = "dump numa info"
+};
+
 static __init int register_numa_trigger(void)
 {
-       register_keyhandler('u', dump_numa, "dump numa info");
+       register_keyhandler('u', &dump_numa_keyhandler);
        return 0;
 }
 __initcall(register_numa_trigger);
diff -r a23057f52f14 -r 68e8b8379244 xen/common/event_channel.c
--- a/xen/common/event_channel.c        Sun Aug 02 12:29:25 2009 +0100
+++ b/xen/common/event_channel.c        Sun Aug 02 13:43:15 2009 +0100
@@ -1135,9 +1135,15 @@ static void dump_evtchn_info(unsigned ch
     rcu_read_unlock(&domlist_read_lock);
 }
 
+static struct keyhandler dump_evtchn_info_keyhandler = {
+    .diagnostic = 1,
+    .u.fn = dump_evtchn_info,
+    .desc = "dump evtchn info"
+};
+
 static int __init dump_evtchn_info_key_init(void)
 {
-    register_keyhandler('e', dump_evtchn_info, "dump evtchn info");
+    register_keyhandler('e', &dump_evtchn_info_keyhandler);
     return 0;
 }
 __initcall(dump_evtchn_info_key_init);
diff -r a23057f52f14 -r 68e8b8379244 xen/common/kexec.c
--- a/xen/common/kexec.c        Sun Aug 02 12:29:25 2009 +0100
+++ b/xen/common/kexec.c        Sun Aug 02 13:43:15 2009 +0100
@@ -133,9 +133,14 @@ static void do_crashdump_trigger(unsigne
     printk(" * no crash kernel loaded!\n");
 }
 
+static struct keyhandler crashdump_trigger_keyhandler = {
+    .u.fn = do_crashdump_trigger,
+    .desc = "trigger a crashdump"
+};
+
 static __init int register_crashdump_trigger(void)
 {
-    register_keyhandler('C', do_crashdump_trigger, "trigger a crashdump");
+    register_keyhandler('C', &crashdump_trigger_keyhandler);
     return 0;
 }
 __initcall(register_crashdump_trigger);
diff -r a23057f52f14 -r 68e8b8379244 xen/common/keyhandler.c
--- a/xen/common/keyhandler.c   Sun Aug 02 12:29:25 2009 +0100
+++ b/xen/common/keyhandler.c   Sun Aug 02 13:43:15 2009 +0100
@@ -13,32 +13,19 @@
 #include <xen/domain.h>
 #include <xen/rangeset.h>
 #include <xen/compat.h>
+#include <xen/ctype.h>
 #include <asm/debugger.h>
 #include <asm/div64.h>
 
-#define KEY_MAX 256
-#define STR_MAX  64
-
-static struct {
-    union {
-        keyhandler_t     *handler;
-        irq_keyhandler_t *irq_handler;
-    } u;
-    unsigned int flags;
-    char         desc[STR_MAX];
-} key_table[KEY_MAX];
-
-#define KEYHANDLER_IRQ_CALLBACK 0x1
-
+static struct keyhandler *key_table[256];
 static unsigned char keypress_key;
 
 static void keypress_action(unsigned long unused)
 {
-    keyhandler_t *h;
     unsigned char key = keypress_key;
     console_start_log_everything();
-    if ( (h = key_table[key].u.handler) != NULL )
-        (*h)(key);
+    if ( key_table[key] != NULL )
+        (*key_table[key]->u.fn)(key);
     console_end_log_everything();
 }
 
@@ -46,13 +33,15 @@ static DECLARE_TASKLET(keypress_tasklet,
 
 void handle_keypress(unsigned char key, struct cpu_user_regs *regs)
 {
-    irq_keyhandler_t *h;
-
-    if ( !in_irq() || (key_table[key].flags & KEYHANDLER_IRQ_CALLBACK) )
+    struct keyhandler *h;
+
+    if ( (h = key_table[key]) == NULL )
+        return;
+
+    if ( !in_irq() || h->irq_callback )
     {
         console_start_log_everything();
-        if ( (h = key_table[key].u.irq_handler) != NULL )
-            (*h)(key, regs);
+        (*h->u.irq_fn)(key, regs);
         console_end_log_everything();
     }
     else
@@ -62,34 +51,26 @@ void handle_keypress(unsigned char key, 
     }
 }
 
-void register_keyhandler(
-    unsigned char key, keyhandler_t *handler, char *desc)
-{
-    ASSERT(key_table[key].u.handler == NULL);
-    key_table[key].u.handler = handler;
-    key_table[key].flags     = 0;
-    safe_strcpy(key_table[key].desc, desc);
-}
-
-void register_irq_keyhandler(
-    unsigned char key, irq_keyhandler_t *handler, char *desc)
-{
-    ASSERT(key_table[key].u.irq_handler == NULL);
-    key_table[key].u.irq_handler = handler;
-    key_table[key].flags         = KEYHANDLER_IRQ_CALLBACK;
-    safe_strcpy(key_table[key].desc, desc);
+void register_keyhandler(unsigned char key, struct keyhandler *handler)
+{
+    ASSERT(key_table[key] == NULL);
+    key_table[key] = handler;
 }
 
 static void show_handlers(unsigned char key)
 {
     int i;
     printk("'%c' pressed -> showing installed handlers\n", key);
-    for ( i = 0; i < KEY_MAX; i++ ) 
-        if ( key_table[i].u.handler != NULL ) 
+    for ( i = 0; i < ARRAY_SIZE(key_table); i++ ) 
+        if ( key_table[i] != NULL ) 
             printk(" key '%c' (ascii '%02x') => %s\n", 
-                   (i<33 || i>126)?(' '):(i),i,
-                   key_table[i].desc);
-}
+                   isprint(i) ? i : ' ', i, key_table[i]->desc);
+}
+
+static struct keyhandler show_handlers_keyhandler = {
+    .u.fn = show_handlers,
+    .desc = "show this message"
+};
 
 static void __dump_execstate(void *unused)
 {
@@ -127,6 +108,13 @@ static void dump_registers(unsigned char
     console_end_sync();
 }
 
+static struct keyhandler dump_registers_keyhandler = {
+    .irq_callback = 1,
+    .diagnostic = 1,
+    .u.irq_fn = dump_registers,
+    .desc = "dump registers"
+};
+
 static void dump_dom0_registers(unsigned char key)
 {
     struct vcpu *v;
@@ -140,11 +128,23 @@ static void dump_dom0_registers(unsigned
         vcpu_show_execution_state(v);
 }
 
-static void halt_machine(unsigned char key, struct cpu_user_regs *regs)
+static struct keyhandler dump_dom0_registers_keyhandler = {
+    .diagnostic = 1,
+    .u.fn = dump_dom0_registers,
+    .desc = "dump Dom0 registers"
+};
+
+static void reboot_machine(unsigned char key, struct cpu_user_regs *regs)
 {
     printk("'%c' pressed -> rebooting machine\n", key);
     machine_restart(0);
 }
+
+static struct keyhandler reboot_machine_keyhandler = {
+    .irq_callback = 1,
+    .u.irq_fn = reboot_machine,
+    .desc = "reboot machine"
+};
 
 static void cpuset_print(char *set, int size, cpumask_t mask)
 {
@@ -236,6 +236,12 @@ static void dump_domains(unsigned char k
     rcu_read_unlock(&domlist_read_lock);
 }
 
+static struct keyhandler dump_domains_keyhandler = {
+    .diagnostic = 1,
+    .u.fn = dump_domains,
+    .desc = "dump domain (and guest debug) info"
+};
+
 static cpumask_t read_clocks_cpumask = CPU_MASK_NONE;
 static s_time_t read_clocks_time[NR_CPUS];
 static u64 read_cycles_time[NR_CPUS];
@@ -314,12 +320,82 @@ static void read_clocks(unsigned char ke
            maxdif_cycles, sumdif_cycles/count, count, dif_cycles);
 }
 
+static struct keyhandler read_clocks_keyhandler = {
+    .diagnostic = 1,
+    .u.fn = read_clocks,
+    .desc = "display multi-cpu clock info"
+};
+
 extern void dump_runq(unsigned char key);
+static struct keyhandler dump_runq_keyhandler = {
+    .diagnostic = 1,
+    .u.fn = dump_runq,
+    .desc = "dump run queues"
+};
 
 #ifdef PERF_COUNTERS
 extern void perfc_printall(unsigned char key);
+static struct keyhandler perfc_printall_keyhandler = {
+    .diagnostic = 1,
+    .u.fn = perfc_printall,
+    .desc = "print performance counters"
+};
 extern void perfc_reset(unsigned char key);
+static struct keyhandler perfc_reset_keyhandler = {
+    .u.fn = perfc_reset,
+    .desc = "reset performance counters"
+};
 #endif
+
+static void run_all_nonirq_keyhandlers(unsigned long unused)
+{
+    /* Fire all the non-IRQ-context diagnostic keyhandlers */
+    struct keyhandler *h;
+    int k;
+
+    console_start_log_everything();
+    for ( k = 0; k < ARRAY_SIZE(key_table); k++ )
+    {
+        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,
+                       run_all_nonirq_keyhandlers, 0);
+
+static void run_all_keyhandlers(unsigned char key, struct cpu_user_regs *regs)
+{
+    struct keyhandler *h;
+    int k;
+
+    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];
+        if ( (h == NULL) || !h->diagnostic || !h->irq_callback )
+            continue;
+        printk("[%c: %s]\n", k, h->desc);
+        (*h->u.irq_fn)(k, regs);
+    }
+    console_end_log_everything();
+
+    /* Trigger the others from a tasklet in non-IRQ context */
+    tasklet_schedule(&run_all_keyhandlers_tasklet);
+}
+
+static struct keyhandler run_all_keyhandlers_keyhandler = {
+    .irq_callback = 1,
+    .u.irq_fn = run_all_keyhandlers,
+    .desc = "print all diagnostics"
+};
 
 static void do_debug_key(unsigned char key, struct cpu_user_regs *regs)
 {
@@ -330,33 +406,28 @@ static void do_debug_key(unsigned char k
                              bit. */
 }
 
+static struct keyhandler do_debug_key_keyhandler = {
+    .irq_callback = 1,
+    .u.irq_fn = do_debug_key,
+    .desc = "trap to xendbg"
+};
+
 void __init initialize_keytable(void)
 {
-    register_irq_keyhandler(
-        'd', dump_registers, "dump registers");
-    register_keyhandler(
-        'h', show_handlers, "show this message");
-    register_keyhandler(
-        'q', dump_domains, "dump domain (and guest debug) info");
-    register_keyhandler(
-        'r', dump_runq,      "dump run queues");
-    register_irq_keyhandler(
-        'R', halt_machine,   "reboot machine");
-
-    register_keyhandler(
-        't', read_clocks, "display multi-cpu clock info");
+    register_keyhandler('d', &dump_registers_keyhandler);
+    register_keyhandler('h', &show_handlers_keyhandler);
+    register_keyhandler('q', &dump_domains_keyhandler);
+    register_keyhandler('r', &dump_runq_keyhandler);
+    register_keyhandler('R', &reboot_machine_keyhandler);
+    register_keyhandler('t', &read_clocks_keyhandler);
+    register_keyhandler('0', &dump_dom0_registers_keyhandler);
+    register_keyhandler('%', &do_debug_key_keyhandler);
+    register_keyhandler('*', &run_all_keyhandlers_keyhandler);
 
 #ifdef PERF_COUNTERS
-    register_keyhandler(
-        'p', perfc_printall, "print performance counters");
-    register_keyhandler(
-        'P', perfc_reset,    "reset performance counters");
+    register_keyhandler('p', &perfc_printall_keyhandler);
+    register_keyhandler('P', &perfc_reset_keyhandler);
 #endif
-
-    register_keyhandler(
-        '0', dump_dom0_registers, "dump Dom0 registers");
-
-    register_irq_keyhandler('%', do_debug_key,   "Trap to xendbg");
 }
 
 /*
diff -r a23057f52f14 -r 68e8b8379244 xen/common/page_alloc.c
--- a/xen/common/page_alloc.c   Sun Aug 02 12:29:25 2009 +0100
+++ b/xen/common/page_alloc.c   Sun Aug 02 13:43:15 2009 +0100
@@ -1192,7 +1192,7 @@ unsigned long avail_domheap_pages(void)
                             -1);
 }
 
-static void pagealloc_keyhandler(unsigned char key)
+static void pagealloc_info(unsigned char key)
 {
     unsigned int zone = MEMZONE_XEN;
     unsigned long n, total = 0;
@@ -1219,10 +1219,15 @@ static void pagealloc_keyhandler(unsigne
     printk("    Dom heap: %lukB free\n", total << (PAGE_SHIFT-10));
 }
 
+static struct keyhandler pagealloc_info_keyhandler = {
+    .diagnostic = 1,
+    .u.fn = pagealloc_info,
+    .desc = "memory info"
+};
 
 static __init int pagealloc_keyhandler_init(void)
 {
-    register_keyhandler('m', pagealloc_keyhandler, "memory info");
+    register_keyhandler('m', &pagealloc_info_keyhandler);
     return 0;
 }
 __initcall(pagealloc_keyhandler_init);
@@ -1261,9 +1266,15 @@ static void dump_heap(unsigned char key)
     }
 }
 
+static struct keyhandler dump_heap_keyhandler = {
+    .diagnostic = 1,
+    .u.fn = dump_heap,
+    .desc = "dump heap info"
+};
+
 static __init int register_heap_trigger(void)
 {
-    register_keyhandler('H', dump_heap, "dump heap info");
+    register_keyhandler('H', &dump_heap_keyhandler);
     return 0;
 }
 __initcall(register_heap_trigger);
diff -r a23057f52f14 -r 68e8b8379244 xen/common/timer.c
--- a/xen/common/timer.c        Sun Aug 02 12:29:25 2009 +0100
+++ b/xen/common/timer.c        Sun Aug 02 13:43:15 2009 +0100
@@ -514,6 +514,11 @@ static void dump_timerq(unsigned char ke
     }
 }
 
+static struct keyhandler dump_timerq_keyhandler = {
+    .diagnostic = 1,
+    .u.fn = dump_timerq,
+    .desc = "dump timer queues"
+};
 
 void __init timer_init(void)
 {
@@ -535,7 +540,7 @@ void __init timer_init(void)
         per_cpu(timers, i).heap = &dummy_heap;
     }
 
-    register_keyhandler('a', dump_timerq, "dump timer queues");
+    register_keyhandler('a', &dump_timerq_keyhandler);
 }
 
 /*
diff -r a23057f52f14 -r 68e8b8379244 xen/drivers/char/console.c
--- a/xen/drivers/char/console.c        Sun Aug 02 12:29:25 2009 +0100
+++ b/xen/drivers/char/console.c        Sun Aug 02 13:43:15 2009 +0100
@@ -921,6 +921,11 @@ static void debugtrace_key(unsigned char
     debugtrace_toggle();
 }
 
+static struct keyhandler debugtrace_keyhandler = {
+    .u.fn = debugtrace_key,
+    .desc = "toggle debugtrace to console/buffer"
+};
+
 static int __init debugtrace_init(void)
 {
     int order;
@@ -942,8 +947,7 @@ static int __init debugtrace_init(void)
 
     debugtrace_bytes = bytes;
 
-    register_keyhandler(
-        'T', debugtrace_key, "toggle debugtrace to console/buffer");
+    register_keyhandler('T', &debugtrace_keyhandler);
 
     return 0;
 }
diff -r a23057f52f14 -r 68e8b8379244 xen/drivers/passthrough/pci.c
--- a/xen/drivers/passthrough/pci.c     Sun Aug 02 12:29:25 2009 +0100
+++ b/xen/drivers/passthrough/pci.c     Sun Aug 02 13:43:15 2009 +0100
@@ -415,9 +415,15 @@ static void dump_pci_devices(unsigned ch
     spin_unlock(&pcidevs_lock);
 }
 
+struct keyhandler dump_pci_devices_keyhandler = {
+    .diagnostic = 1,
+    .u.fn = dump_pci_devices,
+    .desc = "dump PCI devices"
+};
+
 static int __init setup_dump_pcidevs(void)
 {
-    register_keyhandler('Q', dump_pci_devices, "dump PCI devices");
+    register_keyhandler('Q', &dump_pci_devices_keyhandler);
     return 0;
 }
 __initcall(setup_dump_pcidevs);
diff -r a23057f52f14 -r 68e8b8379244 xen/drivers/passthrough/vtd/extern.h
--- a/xen/drivers/passthrough/vtd/extern.h      Sun Aug 02 12:29:25 2009 +0100
+++ b/xen/drivers/passthrough/vtd/extern.h      Sun Aug 02 13:43:15 2009 +0100
@@ -22,13 +22,14 @@
 #define _VTD_EXTERN_H_
 
 #include "dmar.h"
+#include <xen/keyhandler.h>
 
 extern int qinval_enabled;
 extern int ats_enabled;
 
 void print_iommu_regs(struct acpi_drhd_unit *drhd);
 void print_vtd_entries(struct iommu *iommu, int bus, int devfn, u64 gmfn);
-void dump_iommu_info(unsigned char key);
+extern struct keyhandler dump_iommu_info_keyhandler;
 
 int enable_qinval(struct iommu *iommu);
 void disable_qinval(struct iommu *iommu);
diff -r a23057f52f14 -r 68e8b8379244 xen/drivers/passthrough/vtd/iommu.c
--- a/xen/drivers/passthrough/vtd/iommu.c       Sun Aug 02 12:29:25 2009 +0100
+++ b/xen/drivers/passthrough/vtd/iommu.c       Sun Aug 02 13:43:15 2009 +0100
@@ -1759,7 +1759,7 @@ int intel_vtd_setup(void)
     if ( init_vtd_hw() )
         goto error;
 
-    register_keyhandler('V', dump_iommu_info, "dump iommu info");
+    register_keyhandler('V', &dump_iommu_info_keyhandler);
 
     return 0;
 
diff -r a23057f52f14 -r 68e8b8379244 xen/drivers/passthrough/vtd/utils.c
--- a/xen/drivers/passthrough/vtd/utils.c       Sun Aug 02 12:29:25 2009 +0100
+++ b/xen/drivers/passthrough/vtd/utils.c       Sun Aug 02 13:43:15 2009 +0100
@@ -194,7 +194,7 @@ void print_vtd_entries(struct iommu *iom
     } while ( --level );
 }
 
-void dump_iommu_info(unsigned char key)
+static void dump_iommu_info(unsigned char key)
 {
 #if defined(__i386__) || defined(__x86_64__)
     struct acpi_drhd_unit *drhd;
@@ -304,6 +304,12 @@ void dump_iommu_info(unsigned char key)
 #endif
 }
 
+struct keyhandler dump_iommu_info_keyhandler = {
+    .diagnostic = 1,
+    .u.fn = dump_iommu_info,
+    .desc = "dump iommu info"
+};
+
 /*
  * Local variables:
  * mode: C
diff -r a23057f52f14 -r 68e8b8379244 xen/include/xen/keyhandler.h
--- a/xen/include/xen/keyhandler.h      Sun Aug 02 12:29:25 2009 +0100
+++ b/xen/include/xen/keyhandler.h      Sun Aug 02 13:43:15 2009 +0100
@@ -10,25 +10,44 @@
 #ifndef __XEN_KEYHANDLER_H__
 #define __XEN_KEYHANDLER_H__
 
+typedef void keyhandler_fn_t(
+    unsigned char key);
+typedef void irq_keyhandler_fn_t(
+    unsigned char key, struct cpu_user_regs *regs);
+
+struct keyhandler {
+    /*
+     * If TRUE then u.irq_fn is called in hardirq context with interrupts
+     * disabled. The @regs callback parameter points at the interrupted
+     * register context. 
+     * If FALSE then u.fn is called in softirq context with no locks held and
+     * interrupts enabled.
+     */
+    bool_t irq_callback;
+
+    /*
+     * If TRUE then the keyhandler will be included in the "dump everything"
+     * keyhandler, so must not have any side-effects.
+     */
+    bool_t diagnostic;
+
+    union {
+        keyhandler_fn_t *fn;
+        irq_keyhandler_fn_t *irq_fn;
+    } u;
+
+    /* The string is not copied by register_keyhandler(), so must persist. */
+    char *desc;
+};
+
 /* Initialize keytable with default handlers */
 extern void initialize_keytable(void);
 
 /*
- * Register a callback function for key @key. The callback occurs in
- * softirq context with no locks held and interrupts enabled.
+ * Register a callback handler for key @key. The keyhandler structure is not
+ * copied, so must persist.
  */
-typedef void keyhandler_t(unsigned char key);
-extern void register_keyhandler(
-    unsigned char key, keyhandler_t *handler, char *desc);
-
-/*
- * Register an IRQ callback function for key @key. The callback occurs
- * synchronously in hard-IRQ context with interrupts disabled. The @regs
- * callback parameter points at the interrupted register context.
- */
-typedef void irq_keyhandler_t(unsigned char key, struct cpu_user_regs *regs);
-extern void register_irq_keyhandler(
-    unsigned char key, irq_keyhandler_t *handler, char *desc);
+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);

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] Add a single trigger for all diagnostic keyhandlers, Xen patchbot-unstable <=