Re: [PATCH v4 6/6] perf mem record: Use the IBS swfilt filter when available
From: Arnaldo Carvalho de Melo
Date: Fri Sep 25 2026 - 06:33:04 EST
On Fri, Sep 25, 2026 at 09:32:42AM +0530, Ravi Bangoria wrote:
> Hi Arnaldo,
>
> > IBS events with exclude_{user,kernel} bits, as used for per-thread
> > recording when kernel samples are not allowed, are rejected on hardware
> > without the privilege filter, so per-thread 'perf mem record' fails on
> > AMD:
> >
> > $ perf mem record -o /dev/null -- true
> > Failure to open event 'ibs_op/ldlat=0/u' on PMU 'ibs_op' which will be removed.
> >
> > Kernel v6.14 added swfilt, a software privilege filter exposed as the
> > 'swfilt' format term, making those events usable per-thread. Give the
> > ibs_op memory events extra tables with the term, selected in
> > perf_pmu__arch_init() when the PMU exposes it, keeping the names that
> > need system wide mode otherwise; the knowledge that IBS needs this
> > stays in the arch code.
> >
> > Suggested-by: Namhyung Kim <namhyung@xxxxxxxxxx>
> > Suggested-by: Ravi Bangoria <ravi.bangoria@xxxxxxx>
> > Assisted-by: LLM
> > Signed-off-by: Arnaldo Carvalho de Melo <acme@xxxxxxxxxx>
>
> Reviewed-by: Ravi Bangoria <ravi.bangoria@xxxxxxx>
>
> > + * ... Keep it even when
> > + * the event has no exclude bits yet, 'perf record' adds them on the
> > + * first open failure and retries with the same name.
>
> Currently, 'perf record' fails rather than silently retrying with
> /swfilt=1/. The reason to not transparently add /swfilt=1/ is to
> make the user aware that software filtering is being used, and it
> is not overhead free.
Made it more concise:
+/*
+ * IBS events with exclude_{user,kernel} bits are rejected on hardware
+ * without the privilege filter unless swfilt is used: the extra tables
+ * carry the term, selected when the PMU exposes it.
+ */
struct perf_mem_event perf_mem_events_amd[PERF_MEM_EVENTS__MAX] = {
E(NULL, NULL, NULL, false, 0),
E(NULL, NULL, NULL, false, 0),
E("mem-ldst", "%s//", NULL, false, 0),
};
+struct perf_mem_event perf_mem_events_amd_swfilt[PERF_MEM_EVENTS__MAX] = {
+ E(NULL, NULL, NULL, false, 0),
+ E(NULL, NULL, NULL, false, 0),
+ E("mem-ldst", "%s/swfilt=1/", NULL, false, 0),
+};
+
struct perf_mem_event perf_mem_events_amd_ldlat[PERF_MEM_EVENTS__MAX] = {
E(NULL, NULL, NULL, false, 0),
E(NULL, NULL, NULL, false, 0),
E("mem-ldst", "%s/ldlat=%u/", NULL, true, 0),
};
+
+struct perf_mem_event perf_mem_events_amd_ldlat_swfilt[PERF_MEM_EVENTS__MAX] = {
+ E(NULL, NULL, NULL, false, 0),
+ E(NULL, NULL, NULL, false, 0),
+ E("mem-ldst", "%s/ldlat=%u,swfilt=1/", NULL, true, 0),
+};o
- Arnaldo