Nysal reported that userspace backtraces are missing in offcputime bcc
tool. As an example:
    $ sudo ./bcc/tools/offcputime.py -uU
    Tracing off-CPU time (us) of user threads by user stack... Hit Ctrl-C to 
end.

    ^C
        write
        -                python (9107)
            8

        write
        -                sudo (9105)
            9

        mmap
        -                python (9107)
            16

        clock_nanosleep
        -                multipathd (697)
            3001604

The offcputime bcc tool attaches a bpf program to a kprobe on
finish_task_switch(), which is usually hit on a syscall from userspace.
With the switch to system call vectored, we started setting
pt_regs->link to zero. This is because system call vectored behaves like
a function call with LR pointing to the system call return address, and
with no modification to SRR0/SRR1. The LR value does indicate our next
instruction, so it is being saved as pt_regs->nip, and pt_regs->link is
being set to zero. This is not a problem by itself, but BPF uses perf
callchain infrastructure for capturing stack traces, and that stores LR
as the second entry in the stack trace. perf has code to cope with the
second entry being zero, and skips over it. However, generic userspace
unwinders assume that a zero entry indicates end of the stack trace,
resulting in a truncated userspace stack trace.

Rather than fixing all userspace unwinders to ignore/skip past the
second entry, store the real LR value in pt_regs->link so that there
continues to be a valid, though duplicate entry in the stack trace.

With this change:
    $ sudo ./bcc/tools/offcputime.py -uU
    Tracing off-CPU time (us) of user threads by user stack... Hit Ctrl-C to 
end.

    ^C
        write
        write
        [unknown]
        [unknown]
        [unknown]
        [unknown]
        [unknown]
        PyObject_VectorcallMethod
        [unknown]
        [unknown]
        PyObject_CallOneArg
        PyFile_WriteObject
        PyFile_WriteString
        [unknown]
        [unknown]
        PyObject_Vectorcall
        _PyEval_EvalFrameDefault
        PyEval_EvalCode
        [unknown]
        [unknown]
        [unknown]
        _PyRun_SimpleFileObject
        _PyRun_AnyFileObject
        Py_RunMain
        [unknown]
        Py_BytesMain
        [unknown]
        __libc_start_main
        -                python (1293)
            7

        write
        write
        [unknown]
        sudo_ev_loop_v1
        sudo_ev_dispatch_v1
        [unknown]
        [unknown]
        [unknown]
        [unknown]
        __libc_start_main
        -                sudo (1291)
            7

        syscall
        syscall
        bpf_open_perf_buffer_opts
        [unknown]
        [unknown]
        [unknown]
        [unknown]
        _PyObject_MakeTpCall
        PyObject_Vectorcall
        _PyEval_EvalFrameDefault
        PyEval_EvalCode
        [unknown]
        [unknown]
        [unknown]
        _PyRun_SimpleFileObject
        _PyRun_AnyFileObject
        Py_RunMain
        [unknown]
        Py_BytesMain
        [unknown]
        __libc_start_main
        -                python (1293)
            11

        clock_nanosleep
        clock_nanosleep
        nanosleep
        sleep
        [unknown]
        [unknown]
        __clone
        -                multipathd (698)
            3001661

Fixes: 7fa95f9adaee ("powerpc/64s: system call support for scv/rfscv 
instructions")
Cc: sta...@vger.kernel.org
Reported-by: Nysal Jan K.A <ny...@linux.ibm.com>
Signed-off-by: Naveen N Rao <nav...@kernel.org>
---
v2: Update change log, re-order instructions storing into pt_regs->nip 
and pt_regs->link and add a comment to better describe the change. Also 
added a Fixes: tag.


 arch/powerpc/kernel/interrupt_64.S | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/kernel/interrupt_64.S 
b/arch/powerpc/kernel/interrupt_64.S
index bd863702d812..1ad059a9e2fe 100644
--- a/arch/powerpc/kernel/interrupt_64.S
+++ b/arch/powerpc/kernel/interrupt_64.S
@@ -52,7 +52,8 @@ _ASM_NOKPROBE_SYMBOL(system_call_vectored_\name)
        mr      r10,r1
        ld      r1,PACAKSAVE(r13)
        std     r10,0(r1)
-       std     r11,_NIP(r1)
+       std     r11,_LINK(r1)
+       std     r11,_NIP(r1)    /* Saved LR is also the next instruction */
        std     r12,_MSR(r1)
        std     r0,GPR0(r1)
        std     r10,GPR1(r1)
@@ -70,7 +71,6 @@ _ASM_NOKPROBE_SYMBOL(system_call_vectored_\name)
        std     r9,GPR13(r1)
        SAVE_NVGPRS(r1)
        std     r11,_XER(r1)
-       std     r11,_LINK(r1)
        std     r11,_CTR(r1)
 
        li      r11,\trapnr

base-commit: 414e92af226ede4935509b0b5e041810c92e003f
-- 
2.43.0

Reply via email to