prof: backtrace the interrupted context
authorBarret Rhoden <brho@cs.berkeley.edu>
Wed, 28 May 2014 19:18:26 +0000 (12:18 -0700)
committerBarret Rhoden <brho@cs.berkeley.edu>
Wed, 28 May 2014 19:18:26 +0000 (12:18 -0700)
Just calling backtrace on the current context just gave us the IRQ's BT,
which is just handle_irq, timer_interrupt, etc.  We actually want the
context that we interrupted, such as the kernel executing a syscall or
userspace.

kern/include/kdebug.h
kern/include/oprofile.h
kern/src/oprofile/cpu_buffer.c
kern/src/time.c

index 2c0dd11..4405b2b 100644 (file)
@@ -33,6 +33,6 @@ void hexdump(void *v, int length);
 void pahexdump(uintptr_t pa, int length);
 
 #include <oprofile.h>
-#define TRACEME() oprofile_add_backtrace(read_bp())
+#define TRACEME() oprofile_add_backtrace(read_pc(), read_bp())
 
 #endif /* ROS_KERN_KDEBUG_H */
index 479a9aa..4a4d33a 100644 (file)
@@ -107,7 +107,7 @@ void oprofile_add_ext_hw_sample(unsigned long pc, /*struct pt_regs*/void * const
 /* Use this instead when the PC value is not from the regs. Doesn't
  * backtrace. */
 void oprofile_add_pc(unsigned long pc, int is_kernel, unsigned long event);
-void oprofile_add_backtrace(uintptr_t ebp);
+void oprofile_add_backtrace(uintptr_t pc, uintptr_t fp);
 
 /* add a backtrace entry, to be called from the ->backtrace callback */
 void oprofile_add_trace(unsigned long eip);
index 4533d91..8f40616 100644 (file)
@@ -663,7 +663,7 @@ fail:
  * 
  * Third and following words are PCs, there must be at least one of them. 
  */
-void oprofile_add_backtrace(uintptr_t ebp)
+void oprofile_add_backtrace(uintptr_t pc, uintptr_t fp)
 {
        /* version 1. */
        uint64_t descriptor = 0xee01ULL<<48;
@@ -677,8 +677,6 @@ void oprofile_add_backtrace(uintptr_t ebp)
                return;
        }
 
-       uintptr_t eip = get_caller_pc();
-
        struct op_entry entry;
        struct op_sample *sample;
        struct block *b;
@@ -687,7 +685,7 @@ void oprofile_add_backtrace(uintptr_t ebp)
        uintptr_t bt_pcs[oprofile_backtrace_depth];
        
        int nr_pcs;
-       nr_pcs = backtrace_list(eip, ebp, bt_pcs, oprofile_backtrace_depth);
+       nr_pcs = backtrace_list(pc, fp, bt_pcs, oprofile_backtrace_depth);
 
        /* write_reserve always assumes passed-in-size + 2.
         * backtrace_depth should always be > 0.
index d69b56b..083ecfe 100644 (file)
@@ -56,7 +56,10 @@ void udelay_sched(uint64_t usec)
  * you want something to happen in the future, set an alarm. */
 void timer_interrupt(struct hw_trapframe *hw_tf, void *data)
 {
-       TRACEME();
+       if (in_kernel(hw_tf))
+               oprofile_add_backtrace(get_hwtf_pc(hw_tf), get_hwtf_fp(hw_tf));
+       // else add user_sample or something
+
        int coreid = core_id();
        /* run the alarms out of RKM context, so that event delivery works nicely
         * (keeps the proc lock and ksched lock non-irqsave) */