hw_perf_enable() would disable events that were not yet enabled.
This causes problems with code that assumes that ->enable/->disable calls
are balanced (like the LBR code does).
What happens is that we disable newly added counters that match their
previous assignment, even though they are not yet programmed on the
hardware.
Avoid this by only doing the first pass over the existing events.
Signed-off-by: Peter Zijlstra <[email protected]>
Cc: Arnaldo Carvalho de Melo <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
LKML-Reference: <new-submission>
Signed-off-by: Ingo Molnar <[email protected]>
return;
if (cpuc->n_added) {
+ int n_running = cpuc->n_events - cpuc->n_added;
/*
* apply assignment obtained either from
* hw_perf_group_sched_in() or x86_pmu_enable()
* step1: save events moving to new counters
* step2: reprogram moved events into new counters
*/
- for (i = 0; i < cpuc->n_events; i++) {
+ for (i = 0; i < n_running; i++) {
event = cpuc->event_list[i];
hwc = &event->hw;