• Frederic Weisbecker's avatar
    perf: Take a hot regs snapshot for trace events · c530665c
    Frederic Weisbecker authored
    We are taking a wrong regs snapshot when a trace event triggers.
    Either we use get_irq_regs(), which gives us the interrupted
    registers if we are in an interrupt, or we use task_pt_regs()
    which gives us the state before we entered the kernel, assuming
    we are lucky enough to be no kernel thread, in which case
    task_pt_regs() returns the initial set of regs when the kernel
    thread was started.
    
    What we want is different. We need a hot snapshot of the regs,
    so that we can get the instruction pointer to record in the
    sample, the frame pointer for the callchain, and some other
    things.
    
    Let's use the new perf_fetch_caller_regs() for that.
    
    Comparison with perf record -e lock: -R -a -f -g
    Before:
    
            perf  [kernel]                   [k] __do_softirq
                   |
                   --- __do_softirq
                      |
                      |--55.16%-- __open
                      |
                       --44.84%-- __write_nocancel
    
    After:
    
                perf  [kernel]           [k] perf_tp_event
                   |
                   --- perf_tp_event
                      |
                      |--41.07%-- lock_acquire
                      |          |
                      |          |--39.36%-- _raw_spin_lock
                      |          |          |
                      |          |          |--7.81%-- hrtimer_interrupt
                      |          |          |          smp_apic_timer_interrupt
                      |          |          |          apic_timer_interrupt
    
    The old case was producing unreliable callchains. Now having
    right frame and instruction pointers, we have the trace we
    want.
    
    Also syscalls and kprobe events already have the right regs,
    let's use them instead of wasting a retrieval.
    
    v2: Follow the rename perf_save_regs() -> perf_fetch_caller_regs()
    Signed-off-by: default avatarFrederic Weisbecker <fweisbec@gmail.com>
    Cc: Ingo Molnar <mingo@elte.hu>
    Cc: Thomas Gleixner <tglx@linutronix.de>
    Cc: H. Peter Anvin <hpa@zytor.com>
    Cc: Peter Zijlstra <peterz@infradead.org>
    Cc: Paul Mackerras <paulus@samba.org>
    Cc: Steven Rostedt <rostedt@goodmis.org>
    Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
    Cc: Masami Hiramatsu <mhiramat@redhat.com>
    Cc: Jason Baron <jbaron@redhat.com>
    Cc: Archs <linux-arch@vger.kernel.org>
    c530665c
trace_syscalls.c 13.6 KB