}
EXPORT_SYMBOL(monotonic_clock);
+#if defined(CONFIG_SMP) && defined(CONFIG_FRAME_POINTER)
+unsigned long profile_pc(struct pt_regs *regs)
+{
+ unsigned long pc = instruction_pointer(regs);
+
+ if (pc >= (unsigned long)&__lock_text_start &&
+ pc <= (unsigned long)&__lock_text_end)
+ return *(unsigned long *)(regs->ebp + 4);
+
+ return pc;
+}
+EXPORT_SYMBOL(profile_pc);
+#endif
/*
* timer_interrupt() needs to keep up the real-time clock,
.text : {
*(.text)
SCHED_TEXT
+ LOCK_TEXT
*(.fixup)
*(.gnu.warning)
} = 0x9090
{
unsigned int low, high;
int i;
- unsigned long eip = instruction_pointer(regs);
+ unsigned long eip = profile_pc(regs);
int is_kernel = !user_mode(regs);
for (i = 0 ; i < NUM_COUNTERS; ++i) {
{
unsigned long ctr, low, high, stag, real;
int i;
- unsigned long eip = instruction_pointer(regs);
+ unsigned long eip = profile_pc(regs);
int is_kernel = !user_mode(regs);
stag = get_stagger();
{
unsigned int low, high;
int i;
- unsigned long eip = instruction_pointer(regs);
+ unsigned long eip = profile_pc(regs);
int is_kernel = !user_mode(regs);
for (i = 0 ; i < NUM_COUNTERS; ++i) {
#ifdef __KERNEL__
#define user_mode(regs) ((VM_MASK & (regs)->eflags) || (3 & (regs)->xcs))
#define instruction_pointer(regs) ((regs)->eip)
+#if defined(CONFIG_SMP) && defined(CONFIG_FRAME_POINTER)
+extern unsigned long profile_pc(struct pt_regs *regs);
+#else
#define profile_pc(regs) instruction_pointer(regs)
#endif
+#endif
#endif
#define __build_read_lock_ptr(rw, helper) \
asm volatile(LOCK "subl $1,(%0)\n\t" \
- "js 2f\n" \
+ "jns 1f\n" \
+ "call " helper "\n\t" \
"1:\n" \
- LOCK_SECTION_START("") \
- "2:\tcall " helper "\n\t" \
- "jmp 1b\n" \
- LOCK_SECTION_END \
::"a" (rw) : "memory")
#define __build_read_lock_const(rw, helper) \
asm volatile(LOCK "subl $1,%0\n\t" \
- "js 2f\n" \
- "1:\n" \
- LOCK_SECTION_START("") \
- "2:\tpushl %%eax\n\t" \
+ "jns 1f\n" \
+ "pushl %%eax\n\t" \
"leal %0,%%eax\n\t" \
"call " helper "\n\t" \
"popl %%eax\n\t" \
- "jmp 1b\n" \
- LOCK_SECTION_END \
+ "1:\n" \
:"=m" (*(volatile int *)rw) : : "memory")
#define __build_read_lock(rw, helper) do { \
#define __build_write_lock_ptr(rw, helper) \
asm volatile(LOCK "subl $" RW_LOCK_BIAS_STR ",(%0)\n\t" \
- "jnz 2f\n" \
+ "jz 1f\n" \
+ "call " helper "\n\t" \
"1:\n" \
- LOCK_SECTION_START("") \
- "2:\tcall " helper "\n\t" \
- "jmp 1b\n" \
- LOCK_SECTION_END \
::"a" (rw) : "memory")
#define __build_write_lock_const(rw, helper) \
asm volatile(LOCK "subl $" RW_LOCK_BIAS_STR ",%0\n\t" \
- "jnz 2f\n" \
- "1:\n" \
- LOCK_SECTION_START("") \
- "2:\tpushl %%eax\n\t" \
+ "jz 1f\n" \
+ "pushl %%eax\n\t" \
"leal %0,%%eax\n\t" \
"call " helper "\n\t" \
"popl %%eax\n\t" \
- "jmp 1b\n" \
- LOCK_SECTION_END \
+ "1:\n" \
:"=m" (*(volatile int *)rw) : : "memory")
#define __build_write_lock(rw, helper) do { \
#define spin_lock_string \
"\n1:\t" \
"lock ; decb %0\n\t" \
- "js 2f\n" \
- LOCK_SECTION_START("") \
+ "jns 3f\n" \
"2:\t" \
"rep;nop\n\t" \
"cmpb $0,%0\n\t" \
"jle 2b\n\t" \
"jmp 1b\n" \
- LOCK_SECTION_END
+ "3:\n\t"
#define spin_lock_string_flags \
"\n1:\t" \
"lock ; decb %0\n\t" \
- "js 2f\n\t" \
- LOCK_SECTION_START("") \
+ "jns 4f\n\t" \
"2:\t" \
"testl $0x200, %1\n\t" \
"jz 3f\n\t" \
"jle 3b\n\t" \
"cli\n\t" \
"jmp 1b\n" \
- LOCK_SECTION_END
+ "4:\n\t"
/*
* This works. Despite all the confusion.