lkml.org 
[lkml]   [2022]   [Mar]   [22]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    Subject[PATCH v7 01/13] perf/core: add perf_clear_branch_entry_bitfields() helper
    From
    Make it simpler to reset all the info fields on the
    perf_branch_entry by adding a helper inline function.

    The goal is to centralize the initialization to avoid missing
    a field in case more are added.

    Signed-off-by: Stephane Eranian <eranian@google.com>
    ---
    arch/x86/events/intel/lbr.c | 36 +++++++++++++++++-------------------
    include/linux/perf_event.h | 16 ++++++++++++++++
    2 files changed, 33 insertions(+), 19 deletions(-)

    diff --git a/arch/x86/events/intel/lbr.c b/arch/x86/events/intel/lbr.c
    index fe1742c4ca49..13179f31fe10 100644
    --- a/arch/x86/events/intel/lbr.c
    +++ b/arch/x86/events/intel/lbr.c
    @@ -769,6 +769,7 @@ void intel_pmu_lbr_disable_all(void)
    void intel_pmu_lbr_read_32(struct cpu_hw_events *cpuc)
    {
    unsigned long mask = x86_pmu.lbr_nr - 1;
    + struct perf_branch_entry *br = cpuc->lbr_entries;
    u64 tos = intel_pmu_lbr_tos();
    int i;

    @@ -784,15 +785,11 @@ void intel_pmu_lbr_read_32(struct cpu_hw_events *cpuc)

    rdmsrl(x86_pmu.lbr_from + lbr_idx, msr_lastbranch.lbr);

    - cpuc->lbr_entries[i].from = msr_lastbranch.from;
    - cpuc->lbr_entries[i].to = msr_lastbranch.to;
    - cpuc->lbr_entries[i].mispred = 0;
    - cpuc->lbr_entries[i].predicted = 0;
    - cpuc->lbr_entries[i].in_tx = 0;
    - cpuc->lbr_entries[i].abort = 0;
    - cpuc->lbr_entries[i].cycles = 0;
    - cpuc->lbr_entries[i].type = 0;
    - cpuc->lbr_entries[i].reserved = 0;
    + perf_clear_branch_entry_bitfields(br);
    +
    + br->from = msr_lastbranch.from;
    + br->to = msr_lastbranch.to;
    + br++;
    }
    cpuc->lbr_stack.nr = i;
    cpuc->lbr_stack.hw_idx = tos;
    @@ -807,6 +804,7 @@ void intel_pmu_lbr_read_64(struct cpu_hw_events *cpuc)
    {
    bool need_info = false, call_stack = false;
    unsigned long mask = x86_pmu.lbr_nr - 1;
    + struct perf_branch_entry *br = cpuc->lbr_entries;
    u64 tos = intel_pmu_lbr_tos();
    int i;
    int out = 0;
    @@ -878,15 +876,14 @@ void intel_pmu_lbr_read_64(struct cpu_hw_events *cpuc)
    if (abort && x86_pmu.lbr_double_abort && out > 0)
    out--;

    - cpuc->lbr_entries[out].from = from;
    - cpuc->lbr_entries[out].to = to;
    - cpuc->lbr_entries[out].mispred = mis;
    - cpuc->lbr_entries[out].predicted = pred;
    - cpuc->lbr_entries[out].in_tx = in_tx;
    - cpuc->lbr_entries[out].abort = abort;
    - cpuc->lbr_entries[out].cycles = cycles;
    - cpuc->lbr_entries[out].type = 0;
    - cpuc->lbr_entries[out].reserved = 0;
    + perf_clear_branch_entry_bitfields(br+out);
    + br[out].from = from;
    + br[out].to = to;
    + br[out].mispred = mis;
    + br[out].predicted = pred;
    + br[out].in_tx = in_tx;
    + br[out].abort = abort;
    + br[out].cycles = cycles;
    out++;
    }
    cpuc->lbr_stack.nr = out;
    @@ -951,6 +948,8 @@ static void intel_pmu_store_lbr(struct cpu_hw_events *cpuc,
    to = rdlbr_to(i, lbr);
    info = rdlbr_info(i, lbr);

    + perf_clear_branch_entry_bitfields(e);
    +
    e->from = from;
    e->to = to;
    e->mispred = get_lbr_mispred(info);
    @@ -959,7 +958,6 @@ static void intel_pmu_store_lbr(struct cpu_hw_events *cpuc,
    e->abort = !!(info & LBR_INFO_ABORT);
    e->cycles = get_lbr_cycles(info);
    e->type = get_lbr_br_type(info);
    - e->reserved = 0;
    }

    cpuc->lbr_stack.nr = i;
    diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
    index 733649184b27..496eb6aa6e54 100644
    --- a/include/linux/perf_event.h
    +++ b/include/linux/perf_event.h
    @@ -1063,6 +1063,22 @@ static inline void perf_sample_data_init(struct perf_sample_data *data,
    data->txn = 0;
    }

    +/*
    + * Clear all bitfields in the perf_branch_entry.
    + * The to and from fields are not cleared because they are
    + * systematically modified by caller.
    + */
    +static inline void perf_clear_branch_entry_bitfields(struct perf_branch_entry *br)
    +{
    + br->mispred = 0;
    + br->predicted = 0;
    + br->in_tx = 0;
    + br->abort = 0;
    + br->cycles = 0;
    + br->type = 0;
    + br->reserved = 0;
    +}
    +
    extern void perf_output_sample(struct perf_output_handle *handle,
    struct perf_event_header *header,
    struct perf_sample_data *data,
    --
    2.35.1.894.gb6a874cedc-goog
    \
     
     \ /
      Last update: 2022-03-22 23:16    [W:4.253 / U:0.052 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site