return delta;
}
-extern char _stext;
-
-static inline void ppc_do_profile (struct pt_regs *regs)
+#ifdef CONFIG_SMP
+unsigned long profile_pc(struct pt_regs *regs)
{
- unsigned long nip;
- extern unsigned long prof_cpu_mask;
-
- profile_hook(regs);
-
- if (user_mode(regs))
- return;
-
- if (!prof_buffer)
- return;
+ unsigned long pc = instruction_pointer(regs);
- nip = instruction_pointer(regs);
+ if (in_lock_functions(pc))
+ return regs->link;
- /*
- * Only measure the CPUs specified by /proc/irq/prof_cpu_mask.
- * (default is all CPUs.)
- */
- if (!((1<<smp_processor_id()) & prof_cpu_mask))
- return;
-
- nip -= (unsigned long) &_stext;
- nip >>= prof_shift;
- /*
- * Don't ignore out-of-bounds EIP values silently,
- * put them into the last histogram slot, so if
- * present, they will show up as a sharp peak.
- */
- if (nip > prof_len-1)
- nip = prof_len-1;
- atomic_inc((atomic_t *)&prof_buffer[nip]);
+ return pc;
}
+EXPORT_SYMBOL(profile_pc);
+#endif
/*
* timer_interrupt - gets called when the decrementer overflows,
irq_enter();
- while ((next_dec = tb_ticks_per_jiffy - tb_delta(&jiffy_stamp)) < 0) {
+ while ((next_dec = tb_ticks_per_jiffy - tb_delta(&jiffy_stamp)) <= 0) {
jiffy_stamp += tb_ticks_per_jiffy;
- ppc_do_profile(regs);
+ profile_tick(CPU_PROFILING, regs);
if (smp_processor_id())
continue;