• Stephane Eranian's avatar
    perf/x86/pebs: Add workaround for broken OVFL status on HSW+ · 76f3540e
    Stephane Eranian authored
    commit 8077eca0 upstream.
    
    This patch fixes an issue with the GLOBAL_OVERFLOW_STATUS bits on
    Haswell, Broadwell and Skylake processors when using PEBS.
    
    The SDM stipulates that when the PEBS iterrupt threshold is crossed,
    an interrupt is posted and the kernel is interrupted. The kernel will
    find GLOBAL_OVF_SATUS bit 62 set indicating there are PEBS records to
    drain. But the bits corresponding to the actual counters should NOT be
    set. The kernel follows the SDM and assumes that all PEBS events are
    processed in the drain_pebs() callback. The kernel then checks for
    remaining overflows on any other (non-PEBS) events and processes these
    in the for_each_bit_set(&status) loop.
    
    As it turns out, under certain conditions on HSW and later processors,
    on PEBS buffer interrupt, bit 62 is set but the counter bits may be
    set as well. In that case, the kernel drains PEBS and generates
    SAMPLES with the EXACT tag, then it processes the counter bits, and
    generates normal (non-EXACT) SAMPLES.
    
    I ran into this problem by trying to understand why on HSW sampling on
    a PEBS event was sometimes returning SAMPLES without the EXACT tag.
    This should not happen on user level code because HSW has the
    eventing_ip which always point to the instruction that caused the
    event.
    
    The workaround in this patch simply ensures that the bits for the
    counters used for PEBS events are cleared after the PEBS buffer has
    been drained. With this fix 100% of the PEBS samples on my user code
    report the EXACT tag.
    
    Before:
      $ perf record -e cpu/event=0xd0,umask=0x81/upp ./multichase
      $ perf report -D | fgrep SAMPLES
      PERF_RECORD_SAMPLE(IP, 0x2): 11775/11775: 0x406de5 period: 73469 addr: 0 exact=Y
                               \--- EXACT tag is missing
    
    After:
      $ perf record -e cpu/event=0xd0,umask=0x81/upp ./multichase
      $ perf report -D | fgrep SAMPLES
      PERF_RECORD_SAMPLE(IP, 0x4002): 11775/11775: 0x406de5 period: 73469 addr: 0 exact=Y
                               \--- EXACT tag is set
    
    The problem tends to appear more often when multiple PEBS events are used.
    Signed-off-by: default avatarStephane Eranian <eranian@google.com>
    Signed-off-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
    Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
    Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
    Cc: Jiri Olsa <jolsa@redhat.com>
    Cc: Linus Torvalds <torvalds@linux-foundation.org>
    Cc: Peter Zijlstra <peterz@infradead.org>
    Cc: Thomas Gleixner <tglx@linutronix.de>
    Cc: Vince Weaver <vincent.weaver@maine.edu>
    Cc: adrian.hunter@intel.com
    Cc: kan.liang@intel.com
    Cc: namhyung@kernel.org
    Link: http://lkml.kernel.org/r/1457034642-21837-3-git-send-email-eranian@google.comSigned-off-by: default avatarIngo Molnar <mingo@kernel.org>
    [bwh: Backported to 3.16: adjust filename]
    Signed-off-by: default avatarBen Hutchings <ben@decadent.org.uk>
    76f3540e
perf_event_intel.c 74.8 KB