Skip to content
  • Kan Liang's avatar
    perf/x86/intel: Fix event update for auto-reload · d31fc13f
    Kan Liang authored and Ingo Molnar's avatar Ingo Molnar committed
    There is a bug when reading event->count with large PEBS enabled.
    
    Here is an example:
    
      # ./read_count
      0x71f0
      0x122c0
      0x1000000001c54
      0x100000001257d
      0x200000000bdc5
    
    In fixed period mode, the auto-reload mechanism could be enabled for
    PEBS events, but the calculation of event->count does not take the
    auto-reload values into account.
    
    Anyone who reads event->count will get the wrong result, e.g x86_pmu_read().
    
    This bug was introduced with the auto-reload mechanism enabled since
    commit:
    
      851559e3
    
     ("perf/x86/intel: Use the PEBS auto reload mechanism when possible")
    
    Introduce intel_pmu_save_and_restart_reload() to calculate the
    event->count only for auto-reload.
    
    Since the counter increments a negative counter value and overflows on
    the sign switch, giving the interval:
    
            [-period, 0]
    
    the difference between two consequtive reads is:
    
     A) value2 - value1;
        when no overflows have happened in between,
     B) (0 - value1) + (value2 - (-period));
        when one overflow happened in between,
     C) (0 - value1) + (n - 1) * (period) + (value2 - (-period));
        when @n overflows happened in between.
    
    Here A) is the obvious difference, B) is the extension to the discrete
    interval, where the first term is to the top of the interval and the
    second term is from the bottom of the next interval and C) the extension
    to multiple intervals, where the middle term is the whole intervals
    covered.
    
    The equation for all cases is:
    
        value2 - value1 + n * period
    
    Previously the event->count is updated right before the sample output.
    But for case A, there is no PEBS record ready. It needs to be specially
    handled.
    
    Remove the auto-reload code from x86_perf_event_set_period() since
    we'll not longer call that function in this case.
    
    Based-on-code-from: Peter Zijlstra (Intel) <peterz@infradead.org>
    Signed-off-by: default avatarKan Liang <kan.liang@linux.intel.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: Stephane Eranian <eranian@google.com>
    Cc: Thomas Gleixner <tglx@linutronix.de>
    Cc: Vince Weaver <vincent.weaver@maine.edu>
    Cc: acme@kernel.org
    Fixes: 851559e3 ("perf/x86/intel: Use the PEBS auto reload mechanism when possible")
    Link: http://lkml.kernel.org/r/1518474035-21006-2-git-send-email-kan.liang@linux.intel.com
    
    
    Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
    d31fc13f