The monitor's trace coretf can query all cores
authorBarret Rhoden <brho@cs.berkeley.edu>
Thu, 8 Aug 2013 20:37:17 +0000 (13:37 -0700)
committerBarret Rhoden <brho@cs.berkeley.edu>
Thu, 8 Aug 2013 20:37:17 +0000 (13:37 -0700)
You can pass -1 for the COREID, and we'll NMI all cores, instead of just one.

Due to this, the NMI handler doesn't print the trapframe by default.  To get
the trapframe, toggle the trace's verbosity to 'on' with "trace verbose".

kern/arch/x86/trap.c
kern/src/monitor.c

index 63d4b11..6013f19 100644 (file)
@@ -230,7 +230,10 @@ static void trap_dispatch(struct hw_trapframe *hw_tf)
                         * deadlock if we were printing when we NMIed. */
                        pcpui = &per_cpu_info[core_id()];
                        pcpui->__lock_depth_disabled++;
-                       print_trapframe(hw_tf);
+                       /* This is a bit hacky, but we don't have a decent API yet */
+                       extern bool mon_verbose_trace;
+                       if (mon_verbose_trace)
+                               print_trapframe(hw_tf);
                        char *fn_name = get_fn_name(x86_get_ip_hw(hw_tf));
                        printk("Core %d is at %p (%s)\n", core_id(), x86_get_ip_hw(hw_tf),
                               fn_name);
index 2169b65..75d65bc 100644 (file)
@@ -646,16 +646,20 @@ int mon_measure(int argc, char **argv, struct hw_trapframe *hw_tf)
        return 0;
 }
 
+/* Used in various debug locations.  Not a kernel API or anything. */
+bool mon_verbose_trace = FALSE;
+
 int mon_trace(int argc, char **argv, struct hw_trapframe *hw_tf)
 {
-       uint32_t core;
+       int core;
        if (argc < 2) {
                printk("Usage: trace OPTION\n");
                printk("\tsyscall start [silent] [pid]: starts tracing\n");
                printk("\tsyscall stop: stops tracing, prints if it was silent\n");
-               printk("\tcoretf COREID: cause the other core to print its TF (NMI)\n");
+               printk("\tcoretf COREID: prints PC, -1 for all cores, verbose => TF\n");
                printk("\tpcpui [type [coreid]]: runs pcpui trace ring handlers\n");
                printk("\tpcpui-reset [noclear]: resets/clears pcpui trace ring\n");
+               printk("\tverbose: toggles verbosity, depends on trace command\n");
                return 1;
        }
        if (!strcmp(argv[1], "syscall")) {
@@ -693,11 +697,18 @@ int mon_trace(int argc, char **argv, struct hw_trapframe *hw_tf)
                        return 1;
                }
                core = strtol(argv[2], 0, 0);
-               if (core >= num_cpus) {
-                       printk("No such core!  Maybe it's in another cell...\n");
-                       return 1;
+               if (core < 0) {
+                       printk("Sending NMIs to all cores:\n");
+                       for (int i = 0; i < num_cpus; i++)
+                               send_nmi(i);
+               } else {
+                       printk("Sending NMI core %d:\n", core);
+                       if (core >= num_cpus) {
+                               printk("No such core!  Maybe it's in another cell...\n");
+                               return 1;
+                       }
+                       send_nmi(core);
                }
-               send_nmi(core);
                udelay(1000000);
        } else if (!strcmp(argv[1], "pcpui")) {
                int pcpui_type, pcpui_coreid;
@@ -720,6 +731,14 @@ int mon_trace(int argc, char **argv, struct hw_trapframe *hw_tf)
                        printk("\nResetting and clearing all PCPUI Trace Rings\n");
                        pcpui_tr_reset_and_clear_all();
                }
+       } else if (!strcmp(argv[1], "verbose")) {
+               if (mon_verbose_trace) {
+                       printk("Turning trace verbosity off\n");
+                       mon_verbose_trace = FALSE;
+               } else {
+                       printk("Turning trace verbosity on\n");
+                       mon_verbose_trace = TRUE;
+               }
        } else if (!strcmp(argv[1], "opt2")) {
                if (argc != 3) {
                        printk("ERRRRRRRRRR.\n");