On Wed, Apr 29, 2026 at 01:29:18PM -0600, Gustavo A. R. Silva wrote: > -Wflex-array-member-not-at-end was introduced in GCC-14, and we are > getting ready to enable it, globally. > > Use the TRAILING_OVERLAP() helper to fix the following warnings: > > 14 arch/x86/events/intel/../perf_event.h:326:41: warning: structure > containing a flexible array member is not at the end of another structure > [-Wflex-array-member-not-at-end] > 6 arch/x86/events/amd/../perf_event.h:326:41: warning: structure containing a > flexible array member is not at the end of another structure > [-Wflex-array-member-not-at-end] > 3 arch/x86/events/perf_event.h:326:41: warning: structure containing a > flexible array member is not at the end of another structure > [-Wflex-array-member-not-at-end] > 1 arch/x86/xen/../events/perf_event.h:326:41: warning: structure containing a > flexible array member is not at the end of another structure > [-Wflex-array-member-not-at-end] > 1 arch/x86/events/zhaoxin/../perf_event.h:326:41: warning: structure > containing a flexible array member is not at the end of another structure > [-Wflex-array-member-not-at-end] > 1 ./arch/x86/include/generated/../../events/perf_event.h:326:41: warning: > structure containing a flexible array member is not at the end of another > structure [-Wflex-array-member-not-at-end] > > This helper creates a union between a flexible-array member (FAM) > and a set of members that would otherwise follow it. This overlays > the trailing members onto the FAM while preserving the original > memory layout. > > Lastly, the static_assert() ensures the alignment between the FAM > and struct perf_branch_entry lbr_entries[MAX_LBR_ENTRIES]; is not > inadvertently changed, and it's intentionally placed inmediately > after the related structure (that is, no blank line in between). > > It's also worth mentioning that the entire Intel LBR bits block > is moved just to avoid splitting it. > > Signed-off-by: Gustavo A. R. Silva <[email protected]> > --- > arch/x86/events/perf_event.h | 41 ++++++++++++++++++++---------------- > 1 file changed, 23 insertions(+), 18 deletions(-) > > diff --git a/arch/x86/events/perf_event.h b/arch/x86/events/perf_event.h > index fad87d3c8b2c..9641b888cbee 100644 > --- a/arch/x86/events/perf_event.h > +++ b/arch/x86/events/perf_event.h > @@ -318,24 +318,6 @@ struct cpu_hw_events { > /* Cached CFG_C values */ > u64 cfg_c_val[X86_PMC_IDX_MAX]; > > - /* > - * Intel LBR bits > - */ > - int lbr_users; > - int lbr_pebs_users; > - struct perf_branch_stack lbr_stack; > - struct perf_branch_entry lbr_entries[MAX_LBR_ENTRIES]; > - u64 lbr_counters[MAX_LBR_ENTRIES]; /* > branch stack extra */ > - union { > - struct er_account *lbr_sel; > - struct er_account *lbr_ctl; > - }; > - u64 br_sel; > - void *last_task_ctx; > - int last_log_id; > - int lbr_select; > - void *lbr_xsave; > - > /* > * Intel host/guest exclude bits > */ > @@ -384,7 +366,30 @@ struct cpu_hw_events { > void *kfree_on_online[X86_PERF_KFREE_MAX]; > > struct pmu *pmu; > + > + /* > + * Intel LBR bits > + */ > + int lbr_users; > + int lbr_pebs_users; > + union { > + struct er_account *lbr_sel; > + struct er_account *lbr_ctl; > + }; > + u64 br_sel; > + void *last_task_ctx; > + int last_log_id; > + int lbr_select; > + void *lbr_xsave; > + > + /* Must be last as it ends in a flexible-array member. */ > + TRAILING_OVERLAP(struct perf_branch_stack, lbr_stack, entries, > + struct perf_branch_entry lbr_entries[MAX_LBR_ENTRIES]; > + u64 lbr_counters[MAX_LBR_ENTRIES]; > /* branch stack extra */ > + ); > }; > +static_assert(offsetof(struct cpu_hw_events, lbr_stack.entries) == > + offsetof(struct cpu_hw_events, lbr_entries));
This is horrible. That code was perfectly fine, and now you've made it an unholy trainwreck just because compiler is stupid :-( Also, we seem to be going around in circles, what was wrong with: https://lore.kernel.org/all/[email protected]/

