From: Anton Blanchard <anton@samba.org>
To: Bob Nelson <rrnelson@linux.vnet.ibm.com>
Cc: linuxppc <linuxppc-dev@ozlabs.org>
Subject: Re: OProfile callgraph support not working correctly on PPC processors
Date: Sun, 6 Jan 2008 18:11:04 -0600 [thread overview]
Message-ID: <20080107001104.GC26734@kryten> (raw)
In-Reply-To: <200712211115.33238.rrnelson@linux.vnet.ibm.com>
Hi,
> I have been investigating why I have not been able to get callgraph code for
> OProfile on Cell to work correctly and I am pretty sure that I have run into
> a problem that is common across all the Power platforms. (At least the other
> ones I have looked at.) I have a simple test program that is attached
> below. It has a main, that calls function1, which calls function2. Each of
> the functions has some type of loop in it so that I can catch it spending
> some CPU time with OProfile. I have also attached the objdump -d output for
> the program cut down to the three pertinent functions that shows what is
> happening. In a nutshell when a terminal function (calls no other function)
> is called the compiler is making an optimization that seems to break the ABI
> convention as far as I can tell. It does not store the Link Register on the
> stack like any other function. It just leaves the return address in LR,
> knowing that nothing should change it. (You can see at the top of both main
> and function1 the first thing it does is "mflr r0" to copy the link register
> to R0 to be saved. It does not do that in function2.) When OProfile takes
> an interrupt and needs to gather the callgraph information it does so by
> grabbing the process' stack pointer (R1) and follows the chain back up the
> stack to gather all the caller's addresses. This works for most functions,
> except for terminal functions for the reason noted above.
Sounds like a standard tail call optimisation. You would have a similar
problem on a normal function if you took a PMU exception in the function
prolog before the LR had been saved to the stack.
> Looking at the assembly listing I drew myself a diagram of the stack while
> function2 is active to convince myself of what was wrong and here is what I
> see it as... When the interrupt is handled OProfile grabs a copy of R1, it
> ignores the first frame on the stack because there should be no address
> stored. In the second frame it expects to find function2's caller but since
> function2 doesn't store it, it grabs some random data and proceeds. The stack
> chain is all ok so it doesn't go off into neverland trying to follow a bad
> chain, but it grabs an invalid address for the caller. And that is why
> OProfile thinks terminal functions have no callers on PPC...
>
> Any suggestions on how this can be fixed? I am guessing that changing the
> compiler and recompiling every program is probably not the answer. I assume
> the link register has to be saved in the interrupt routine when it runs, or
> else it couldn't call anything else without crashing the program that was
> interrupted. Is there a safe place to find it?
You could make use of the LR itself, but you would need to work out if
the LR was in the same function as the stack saved LR, or worse still if
someone uses the LR for an indirect branch it could be completely wrong.
To do a better job you would probably have to parse the dwarf debug
info. Maybe we could always dump the LR and stack LR and decide what one
to use when oprofile userspace parses it.
Anton
prev parent reply other threads:[~2008-01-07 0:11 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-12-21 17:15 OProfile callgraph support not working correctly on PPC processors Bob Nelson
2008-01-07 0:11 ` Anton Blanchard [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20080107001104.GC26734@kryten \
--to=anton@samba.org \
--cc=linuxppc-dev@ozlabs.org \
--cc=rrnelson@linux.vnet.ibm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).