[PARISC] Take into account nullified insn and lock functions for profiling
authorRandolph Chung <tausq@parisc-linux.org>
Sat, 22 Oct 2005 02:42:18 +0000 (22:42 -0400)
committerKyle McMartin <kyle@parisc-linux.org>
Sat, 22 Oct 2005 02:42:18 +0000 (22:42 -0400)
export profile_pc() symbol - oprofile needs it when built as a module.

Signed-off-by: Grant Grundler <grundler@parisc-linux.org>
Take into account nullified insn and lock functions for profiling

This is needed at the end of functions; it is typical that the return
branch nullifies the next insn, which is in the next function. This
causes profiling data to show up against the "wrong" function.

We also count lock times against the locker. This is consistent with
other architectures.

Signed-off-by: Randolph Chung <tausq@parisc-linux.org>
Signed-off-by: Kyle McMartin <kyle@parisc-linux.org>
arch/parisc/kernel/time.c
include/asm-parisc/ptrace.h

index 7ff67f8e9f8c019bd2132cef0e3cabf6768859d9..163cdf39be20fb4f9a65258eab346e42f352a21f 100644 (file)
@@ -104,6 +104,24 @@ irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
        return IRQ_HANDLED;
 }
 
        return IRQ_HANDLED;
 }
 
+
+unsigned long profile_pc(struct pt_regs *regs)
+{
+       unsigned long pc = instruction_pointer(regs);
+
+       if (regs->gr[0] & PSW_N)
+               pc -= 4;
+
+#ifdef CONFIG_SMP
+       if (in_lock_functions(pc))
+               pc = regs->gr[2];
+#endif
+
+       return pc;
+}
+EXPORT_SYMBOL(profile_pc);
+
+
 /*** converted from ia64 ***/
 /*
  * Return the number of micro-seconds that elapsed since the last
 /*** converted from ia64 ***/
 /*
  * Return the number of micro-seconds that elapsed since the last
index 3f428aa371a46f0a26cbe7ad131286abdd8cb2cc..93f990e418f1cd989e001bdeeec8b9ae60afe9a3 100644 (file)
@@ -49,7 +49,7 @@ struct pt_regs {
 #define user_mode(regs)                        (((regs)->iaoq[0] & 3) ? 1 : 0)
 #define user_space(regs)               (((regs)->iasq[1] != 0) ? 1 : 0)
 #define instruction_pointer(regs)      ((regs)->iaoq[0] & ~3)
 #define user_mode(regs)                        (((regs)->iaoq[0] & 3) ? 1 : 0)
 #define user_space(regs)               (((regs)->iasq[1] != 0) ? 1 : 0)
 #define instruction_pointer(regs)      ((regs)->iaoq[0] & ~3)
-#define profile_pc(regs) instruction_pointer(regs)
+unsigned long profile_pc(struct pt_regs *);
 extern void show_regs(struct pt_regs *);
 #endif
 
 extern void show_regs(struct pt_regs *);
 #endif