static void do_ia64_backtrace(struct unw_frame_info *info, void *vdata) { ia64_backtrace_t *bt = vdata; struct switch_stack *sw; int count = 0; u_long pc, sp; sw = (struct switch_stack *)(info+1); /* */ sw = (struct switch_stack *)(((unsigned long)sw + 15) & ~15); unw_init_frame_info(&bt->frame, current, sw); /* */ do { unw_get_sp(&bt->frame, &sp); if (sp >= (u_long)bt->regs) break; if (!next_frame(bt)) return; } while (count++ < 200); /* */ while (bt->depth-- && next_frame(bt)) { unw_get_ip(&bt->frame, &pc); oprofile_add_trace(pc); if (unw_is_intr_frame(&bt->frame)) { /* */ /* */ break; } } }
static void do_ia64_backtrace(struct unw_frame_info *info, void *vdata) { ia64_backtrace_t *bt = vdata; struct switch_stack *sw; int count = 0; u_long pc, sp; sw = (struct switch_stack *)(info+1); /* padding from unw_init_running */ sw = (struct switch_stack *)(((unsigned long)sw + 15) & ~15); unw_init_frame_info(&bt->frame, current, sw); /* skip over interrupt frame and oprofile calls */ do { unw_get_sp(&bt->frame, &sp); if (sp >= (u_long)bt->regs) break; if (!next_frame(bt)) return; } while (count++ < 200); /* finally, grab the actual sample */ while (bt->depth-- && next_frame(bt)) { unw_get_ip(&bt->frame, &pc); oprofile_add_trace(pc); if (unw_is_intr_frame(&bt->frame)) { /* * Interrupt received on kernel stack; this can * happen when timer interrupt fires while processing * a softirq from the tail end of a hardware interrupt * which interrupted a system call. Don't laugh, it * happens! Splice the backtrace into two parts to * avoid spurious cycles in the gprof output. */ /* TODO: split rather than drop the 2nd half */ break; } } }