]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
perf/x86/intel: Allow to update user space GPRs from PEBS records
authorDapeng Mi <dapeng1.mi@linux.intel.com>
Tue, 15 Apr 2025 10:41:35 +0000 (10:41 +0000)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 2 May 2025 05:41:02 +0000 (07:41 +0200)
commit 71dcc11c2cd9e434c34a63154ecadca21c135ddd upstream.

Currently when a user samples user space GPRs (--user-regs option) with
PEBS, the user space GPRs actually always come from software PMI
instead of from PEBS hardware. This leads to the sampled GPRs to
possibly be inaccurate for single PEBS record case because of the
skid between counter overflow and GPRs sampling on PMI.

For the large PEBS case, it is even worse. If user sets the
exclude_kernel attribute, large PEBS would be used to sample user space
GPRs, but since PEBS GPRs group is not really enabled, it leads to all
samples in the large PEBS record to share the same piece of user space
GPRs, like this reproducer shows:

  $ perf record -e branches:pu --user-regs=ip,ax -c 100000 ./foo
  $ perf report -D | grep "AX"

  .... AX    0x000000003a0d4ead
  .... AX    0x000000003a0d4ead
  .... AX    0x000000003a0d4ead
  .... AX    0x000000003a0d4ead
  .... AX    0x000000003a0d4ead
  .... AX    0x000000003a0d4ead
  .... AX    0x000000003a0d4ead
  .... AX    0x000000003a0d4ead
  .... AX    0x000000003a0d4ead
  .... AX    0x000000003a0d4ead
  .... AX    0x000000003a0d4ead

So enable GPRs group for user space GPRs sampling and prioritize reading
GPRs from PEBS. If the PEBS sampled GPRs is not user space GPRs (single
PEBS record case), perf_sample_regs_user() modifies them to user space
GPRs.

[ mingo: Clarified the changelog. ]

Fixes: c22497f5838c ("perf/x86/intel: Support adaptive PEBS v4")
Signed-off-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Cc: stable@vger.kernel.org
Link: https://lore.kernel.org/r/20250415104135.318169-2-dapeng1.mi@linux.intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
arch/x86/events/intel/ds.c

index 48f30ffef1f4b8ec444d6b373576469f8e056ce6..ed34e38e206bda02dac8de6540cd59a8d7576add 100644 (file)
@@ -988,8 +988,10 @@ static u64 pebs_update_adaptive_cfg(struct perf_event *event)
         * + precise_ip < 2 for the non event IP
         * + For RTM TSX weight we need GPRs for the abort code.
         */
-       gprs = (sample_type & PERF_SAMPLE_REGS_INTR) &&
-              (attr->sample_regs_intr & PEBS_GP_REGS);
+       gprs = ((sample_type & PERF_SAMPLE_REGS_INTR) &&
+               (attr->sample_regs_intr & PEBS_GP_REGS)) ||
+              ((sample_type & PERF_SAMPLE_REGS_USER) &&
+               (attr->sample_regs_user & PEBS_GP_REGS));
 
        tsx_weight = (sample_type & PERF_SAMPLE_WEIGHT) &&
                     ((attr->config & INTEL_ARCH_EVENT_MASK) ==
@@ -1572,7 +1574,7 @@ static void setup_pebs_adaptive_sample_data(struct perf_event *event,
                        regs->flags &= ~PERF_EFLAGS_EXACT;
                }
 
-               if (sample_type & PERF_SAMPLE_REGS_INTR)
+               if (sample_type & (PERF_SAMPLE_REGS_INTR | PERF_SAMPLE_REGS_USER))
                        adaptive_pebs_save_regs(regs, gprs);
        }