lkml.org 
[lkml]   [2019]   [Oct]   [22]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    From
    Subject[PATCH V3 00/13] Stitch LBR call stack
    Date
    From: Kan Liang <kan.liang@linux.intel.com>

    Changes since V2
    - Move tos into struct perf_branch_stack

    Changes since V1
    - Add a new branch sample type for LBR TOS. Drop the sample type in V1.
    - Add check in perf header to detect unknown input bits in event attr
    - Save and use the LBR cursor nodes from previous sample to avoid
    duplicate calculation of cursor nodes.
    - Add fast path for duplicate entries check. It benefits all call stack
    parsing, not just for stitch LBR call stack. It can be merged
    independetely.

    Start from Haswell, Linux perf can utilize the existing Last Branch
    Record (LBR) facility to record call stack. However, the depth of the
    reconstructed LBR call stack limits to the number of LBR registers.
    E.g. on skylake, the depth of reconstructed LBR call stack is <= 32
    That's because HW will overwrite the oldest LBR registers when it's
    full.

    However, the overwritten LBRs may still be retrieved from previous
    sample. At that moment, HW hasn't overwritten the LBR registers yet.
    Perf tools can stitch those overwritten LBRs on current call stacks to
    get a more complete call stack.

    To determine if LBRs can be stitched, the physical index of LBR
    registers is required. A new branch sample type is introduced in
    patch 1 to 3 to dump the LBR Top-of-Stack (TOS) information for perf
    tools.

    Only when the new branch sample type is set, the TOS information is
    dumped into the PERF_SAMPLE_BRANCH_STACK output. Perf tool should check
    the attr.branch_sample_type, and apply the corresponding format for
    PERF_SAMPLE_BRANCH_STACK samples. The check is introduced in Patch 4.

    Besides, the maximum number of LBRs is required as well. Patch 5 & 6
    retrieve the capabilities information from sysfs and save them in perf
    header.

    Patch 7 & 8 implements the LBR stitching approach.

    Users can use the options introduced in patch 9-12 to enable the LBR
    stitching approach for perf report, script, top and c2c.

    Patch 13 adds fast path for duplicate entries check. It benefits all
    call stack parsing, not just for stitch LBR call stack. It can be
    merged independetely.


    The stitching approach base on LBR call stack technology. The known
    limitations of LBR call stack technology still apply to the approach,
    e.g. Exception handing such as setjmp/longjmp will have calls/returns
    not match.
    This approach is not full proof. There can be cases where it creates
    incorrect call stacks from incorrect matches. There is no attempt
    to validate any matches in another way. So it is not enabled by default.
    However in many common cases with call stack overflows it can recreate
    better call stacks than the default lbr call stack output. So if there
    are problems with LBR overflows this is a possible workaround.

    Regression:
    Users may collect LBR call stack on a machine with new perf tool and
    new kernel (support LBR TOS). However, they may parse the perf.data with
    old perf tool (not support LBR TOS). The old tool doesn't check
    attr.branch_sample_type. Users probably get incorrect information
    without any warning.

    Performance impact:
    The processing time may increase with the LBR stitching approach
    enabled. The impact depends on the increased depth of call stacks.

    For a simple test case tchain_edit with 43 depth of call stacks.
    perf record --call-graph lbr -- ./tchain_edit
    perf report --stitch-lbr

    Without --stitch-lbr, perf report only display 32 depth of call stacks.
    With --stitch-lbr, perf report can display all 43 depth of call stacks.
    The depth of call stacks increase 34.3%.

    Correspondingly, the processing time of perf report increases 39%,
    Without --stitch-lbr: 11.0 sec
    With --stitch-lbr: 15.3 sec

    The source code of tchain_edit.c is something similar as below.
    noinline void f43(void)
    {
    int i;
    for (i = 0; i < 10000;) {

    if(i%2)
    i++;
    else
    i++;
    }
    }

    noinline void f42(void)
    {
    int i;
    for (i = 0; i < 100; i++) {
    f43();
    f43();
    f43();
    }
    }

    noinline void f41(void)
    {
    int i;
    for (i = 0; i < 100; i++) {
    f42();
    f42();
    f42();
    }
    }

    noinline void f40(void)
    {
    f41();
    }

    ... ...

    noinline void f32(void)
    {
    f33();
    }

    noinline void f31(void)
    {
    int i;

    for (i = 0; i < 10000; i++) {
    if(i%2)
    i++;
    else
    i++;
    }

    f32();
    }

    noinline void f30(void)
    {
    f31();
    }

    ... ...

    noinline void f1(void)
    {
    f2();
    }

    int main()
    {
    f1();
    }


    Kan Liang (13):
    perf/core: Add new branch sample type for LBR TOS
    perf/x86/intel: Output LBR TOS information
    perf tools: Support new branch sample type for LBR TOS
    perf header: Add check for event attr
    perf pmu: Add support for PMU capabilities
    perf header: Support CPU PMU capabilities
    perf machine: Refine the function for LBR call stack reconstruction
    perf tools: Stitch LBR call stack
    perf report: Add option to enable the LBR stitching approach
    perf script: Add option to enable the LBR stitching approach
    perf top: Add option to enable the LBR stitching approach
    perf c2c: Add option to enable the LBR stitching approach
    perf hist: Add fast path for duplicate entries check

    arch/x86/events/intel/lbr.c | 9 +
    include/linux/perf_event.h | 2 +
    include/uapi/linux/perf_event.h | 10 +-
    kernel/events/core.c | 11 +
    tools/include/uapi/linux/perf_event.h | 10 +-
    tools/perf/Documentation/perf-c2c.txt | 11 +
    tools/perf/Documentation/perf-report.txt | 11 +
    tools/perf/Documentation/perf-script.txt | 11 +
    tools/perf/Documentation/perf-top.txt | 9 +
    .../Documentation/perf.data-file-format.txt | 16 +
    tools/perf/builtin-c2c.c | 6 +
    tools/perf/builtin-record.c | 3 +
    tools/perf/builtin-report.c | 6 +
    tools/perf/builtin-script.c | 6 +
    tools/perf/builtin-stat.c | 1 +
    tools/perf/builtin-top.c | 11 +
    tools/perf/util/branch.h | 5 +-
    tools/perf/util/callchain.h | 12 +-
    tools/perf/util/env.h | 3 +
    tools/perf/util/event.h | 1 +
    tools/perf/util/evsel.c | 20 +-
    tools/perf/util/evsel.h | 6 +
    tools/perf/util/header.c | 148 +++++++
    tools/perf/util/header.h | 1 +
    tools/perf/util/hist.c | 23 +
    tools/perf/util/machine.c | 408 +++++++++++++++---
    tools/perf/util/parse-branch-options.c | 1 +
    tools/perf/util/perf_event_attr_fprintf.c | 1 +
    tools/perf/util/pmu.c | 87 ++++
    tools/perf/util/pmu.h | 12 +
    tools/perf/util/sort.c | 2 +-
    tools/perf/util/sort.h | 2 +
    tools/perf/util/thread.c | 2 +
    tools/perf/util/thread.h | 34 ++
    tools/perf/util/top.h | 1 +
    35 files changed, 829 insertions(+), 73 deletions(-)

    --
    2.17.1

    \
     
     \ /
      Last update: 2019-10-22 19:13    [W:3.235 / U:0.456 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site