Messages in this thread Patch in this message | | | Date | Thu, 9 Sep 2021 00:56:48 -0700 | Subject | [PATCH v1 01/13] perf/core: add union to struct perf_branch_entry | From | Stephane Eranian <> |
| |
To make it simpler to reset all the info fields on the perf_branch_entry in a single store, we use a union. This avoids missing some of the bitfields and improves generated code by minimizing the number of stores.
Using an anonymous struct around the bitfields to guarantee field ordering.
A single perf_branch_entry.val = 0 guarantees all fields are all zeroes on any arch.
Signed-off-by: Stephane Eranian <eranian@google.com> --- arch/x86/events/intel/lbr.c | 13 +++---------- include/uapi/linux/perf_event.h | 19 ++++++++++++------- 2 files changed, 15 insertions(+), 17 deletions(-)
diff --git a/arch/x86/events/intel/lbr.c b/arch/x86/events/intel/lbr.c index 9e6d6eaeb4cb..27aa48cce3c6 100644 --- a/arch/x86/events/intel/lbr.c +++ b/arch/x86/events/intel/lbr.c @@ -801,15 +801,9 @@ 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].val = 0; 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; } cpuc->lbr_stack.nr = i; cpuc->lbr_stack.hw_idx = tos; @@ -896,6 +890,7 @@ 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].val = 0; cpuc->lbr_entries[out].from = from; cpuc->lbr_entries[out].to = to; cpuc->lbr_entries[out].mispred = mis; @@ -903,8 +898,6 @@ void intel_pmu_lbr_read_64(struct cpu_hw_events *cpuc) 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; out++; } cpuc->lbr_stack.nr = out; @@ -966,6 +959,7 @@ static void intel_pmu_store_lbr(struct cpu_hw_events *cpuc, to = rdlbr_to(i, lbr); info = rdlbr_info(i, lbr); + e->val = 0; e->from = from; e->to = to; e->mispred = get_lbr_mispred(info); @@ -974,7 +968,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/uapi/linux/perf_event.h b/include/uapi/linux/perf_event.h index f92880a15645..eb11f383f4be 100644 --- a/include/uapi/linux/perf_event.h +++ b/include/uapi/linux/perf_event.h @@ -1329,13 +1329,18 @@ union perf_mem_data_src { struct perf_branch_entry { __u64 from; __u64 to; - __u64 mispred:1, /* target mispredicted */ - predicted:1,/* target predicted */ - in_tx:1, /* in transaction */ - abort:1, /* transaction abort */ - cycles:16, /* cycle count to last branch */ - type:4, /* branch type */ - reserved:40; + union { + __u64 val; /* to make it easier to clear all fields */ + struct { + __u64 mispred:1, /* target mispredicted */ + predicted:1,/* target predicted */ + in_tx:1, /* in transaction */ + abort:1, /* transaction abort */ + cycles:16, /* cycle count to last branch */ + type:4, /* branch type */ + reserved:40; + }; + }; }; union perf_sample_weight { -- 2.33.0.153.gba50c8fa24-goog
| |