perf/x86/intel/ds: Flush PEBS DS when changing PEBS_DATA_CFG
authorKan Liang <kan.liang@linux.intel.com>
Fri, 21 Apr 2023 18:45:28 +0000 (11:45 -0700)
committerPeter Zijlstra <peterz@infradead.org>
Mon, 8 May 2023 08:58:27 +0000 (10:58 +0200)
commitb752ea0c28e3f7f0aaaad6abf84f735eebc37a60
tree7c2ce916f21d479c2a3e3ba92fa910a721b8d089
parent90befef5a9e820ccccc33181ec14c015980300cc
perf/x86/intel/ds: Flush PEBS DS when changing PEBS_DATA_CFG

Several similar kernel warnings can be triggered,

  [56605.607840] CPU0 PEBS record size 0, expected 32, config 0 cpuc->record_size=208

when the below commands are running in parallel for a while on SPR.

  while true;
  do
perf record --no-buildid -a --intr-regs=AX  \
    -e cpu/event=0xd0,umask=0x81/pp \
    -c 10003 -o /dev/null ./triad;
  done &

  while true;
  do
perf record -o /tmp/out -W -d \
    -e '{ld_blocks.store_forward:period=1000000, \
                         MEM_TRANS_RETIRED.LOAD_LATENCY:u:precise=2:ldlat=4}' \
    -c 1037 ./triad;
  done

The triad program is just the generation of loads/stores.

The warnings are triggered when an unexpected PEBS record (with a
different config and size) is found.

A system-wide PEBS event with the large PEBS config may be enabled
during a context switch. Some PEBS records for the system-wide PEBS
may be generated while the old task is sched out but the new one
hasn't been sched in yet. When the new task is sched in, the
cpuc->pebs_record_size may be updated for the per-task PEBS events. So
the existing system-wide PEBS records have a different size from the
later PEBS records.

The PEBS buffer should be flushed right before the hardware is
reprogrammed. The new size and threshold should be updated after the
old buffer has been flushed.

Reported-by: Stephane Eranian <eranian@google.com>
Suggested-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: Kan Liang <kan.liang@linux.intel.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lkml.kernel.org/r/20230421184529.3320912-1-kan.liang@linux.intel.com
arch/x86/events/intel/ds.c
arch/x86/include/asm/perf_event.h