• Andi Kleen's avatar
    perf/x86/intel: Add INST_RETIRED.ALL workarounds · 294fe0f5
    Andi Kleen authored
    On Broadwell INST_RETIRED.ALL cannot be used with any period
    that doesn't have the lowest 6 bits cleared. And the period
    should not be smaller than 128.
    
    This is erratum BDM11 and BDM55:
    
      http://www.intel.com/content/dam/www/public/us/en/documents/specification-updates/5th-gen-core-family-spec-update.pdf
    
    BDM11: When using a period < 100; we may get incorrect PEBS/PMI
    interrupts and/or an invalid counter state.
    BDM55: When bit0-5 of the period are !0 we may get redundant PEBS
    records on overflow.
    
    Add a new callback to enforce this, and set it for Broadwell.
    
    How does this handle the case when an app requests a specific
    period with some of the bottom bits set?
    
    Short answer:
    
    Any useful instruction sampling period needs to be 4-6 orders
    of magnitude larger than 128, as an PMI every 128 instructions
    would instantly overwhelm the system and be throttled.
    So the +-64 error from this is really small compared to the
    period, much smaller than normal system jitter.
    
    Long answer (by Peterz):
    
    IFF we guarantee perf_event_attr::sample_period >= 128.
    
    Suppose we start out with sample_period=192; then we'll set period_left
    to 192, we'll end up with left = 128 (we truncate the lower bits). We
    get an interrupt, find that period_left = 64 (>0 so we return 0 and
    don't get an overflow handler), up that to 128. Then we trigger again,
    at n=256. Then we find period_left = -64 (<=0 so we return 1 and do get
    an overflow). We increment with sample_period so we get left = 128. We
    fire again, at n=384, period_left = 0 (<=0 so we return 1 and get an
    overflow). And on and on.
    
    So while the individual interrupts are 'wrong' we get then with
    interval=256,128 in exactly the right ratio to average out at 192. And
    this works for everything >=128.
    
    So the num_samples*fixed_period thing is still entirely correct +- 127,
    which is good enough I'd say, as you already have that error anyhow.
    
    So no need to 'fix' the tools, al we need to do is refuse to create
    INST_RETIRED:ALL events with sample_period < 128.
    Signed-off-by: default avatarAndi Kleen <ak@linux.intel.com>
    [ Updated comments and changelog a bit. ]
    Signed-off-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
    Link: http://lkml.kernel.org/r/1424225886-18652-3-git-send-email-andi@firstfloor.orgSigned-off-by: default avatarIngo Molnar <mingo@kernel.org>
    294fe0f5
perf_event.c 50.7 KB