perf/core: Add perf_clear_branch_entry_bitfields() helper
authorStephane Eranian <eranian@google.com>
Tue, 22 Mar 2022 22:15:05 +0000 (15:15 -0700)
committerPeter Zijlstra <peterz@infradead.org>
Tue, 5 Apr 2022 08:24:36 +0000 (10:24 +0200)
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>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lore.kernel.org/r/20220322221517.2510440-2-eranian@google.com
arch/x86/events/intel/lbr.c
include/linux/perf_event.h

index fe1742c4ca4986cb3da2f46f6af101bf20d0b5c4..13179f31fe10facf139f4c7c00fd8627363a5594 100644 (file)
@@ -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;
index af97dd427501cbc9d80a1c1480e942576d1a229c..a411080d5169f5d308d84e021b8724ff3c6e2cd6 100644 (file)
@@ -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,