[PATCH] Simplify profile_pc on x86-64

Use knowledge about EFLAGS layout (bits 22:63 are always 0) to distingush
EFLAGS word and kernel address in the spin lock stack frame.

Signed-off-by: Andi Kleen <ak@suse.de>
This commit is contained in:
Andi Kleen 2006-09-26 10:52:28 +02:00 committed by Andi Kleen
parent 0cb91a2293
commit 31679f38d8

View File

@ -189,20 +189,15 @@ unsigned long profile_pc(struct pt_regs *regs)
{ {
unsigned long pc = instruction_pointer(regs); unsigned long pc = instruction_pointer(regs);
/* Assume the lock function has either no stack frame or only a single /* Assume the lock function has either no stack frame or a copy
word. This checks if the address on the stack looks like a kernel of eflags from PUSHF
text address. Eflags always has bits 22 and up cleared unlike kernel addresses. */
There is a small window for false hits, but in that case the tick
is just accounted to the spinlock function.
Better would be to write these functions in assembler again
and check exactly. */
if (!user_mode(regs) && in_lock_functions(pc)) { if (!user_mode(regs) && in_lock_functions(pc)) {
char *v = *(char **)regs->rsp; unsigned long *sp = (unsigned long *)regs->rsp;
if ((v >= _stext && v <= _etext) || if (sp[0] >> 22)
(v >= _sinittext && v <= _einittext) || return sp[0];
(v >= (char *)MODULES_VADDR && v <= (char *)MODULES_END)) if (sp[1] >> 22)
return (unsigned long)v; return sp[1];
return ((unsigned long *)regs->rsp)[1];
} }
return pc; return pc;
} }