+static unsigned long check_spinlock_pc(struct pt_regs *regs,
+ unsigned long profile_pc)
+{
+ unsigned long pc = instruction_pointer(regs);
+
+ /*
+ * If both the SIAR (sampled instruction) and the perfmon exception
+ * occurred in a spinlock region then we account the sample to the
+ * calling function. This isnt 100% correct, we really need soft
+ * IRQ disable so we always get the perfmon exception at the
+ * point at which the SIAR is set.
+ */
+ if (backtrace_spinlocks && in_lock_functions(pc) &&
+ in_lock_functions(profile_pc))
+ return regs->link;
+ else
+ return profile_pc;
+}
+