Skip to content

Commit

Permalink
perf, x86: Prefer fixed-purpose counters when scheduling
Browse files Browse the repository at this point in the history
This avoids a scheduling failure for cases like:

  cycles, cycles, instructions, instructions (on Core2)

Which would end up being programmed like:

  PMC0, PMC1, FP-instructions, fail

Because all events will have the same weight.

Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/n/tip-8tnwb92asqj7xajqqoty4gel@git.kernel.org
Signed-off-by: Ingo Molnar <mingo@elte.hu>
  • Loading branch information
Peter Zijlstra authored and Ingo Molnar committed Dec 6, 2011
1 parent bc1738f commit 4defea8
Showing 1 changed file with 14 additions and 5 deletions.
19 changes: 14 additions & 5 deletions arch/x86/kernel/cpu/perf_event.c
Original file line number Diff line number Diff line change
Expand Up @@ -574,16 +574,25 @@ static bool __perf_sched_find_counter(struct perf_sched *sched)

c = sched->constraints[sched->state.event];

/* Prefer fixed purpose counters */
if (x86_pmu.num_counters_fixed) {
idx = X86_PMC_IDX_FIXED;
for_each_set_bit_cont(idx, c->idxmsk, X86_PMC_IDX_MAX) {
if (!__test_and_set_bit(idx, sched->state.used))
goto done;
}
}
/* Grab the first unused counter starting with idx */
idx = sched->state.counter;
for_each_set_bit_cont(idx, c->idxmsk, X86_PMC_IDX_MAX) {
for_each_set_bit_cont(idx, c->idxmsk, X86_PMC_IDX_FIXED) {
if (!__test_and_set_bit(idx, sched->state.used))
break;
goto done;
}
sched->state.counter = idx;

if (idx >= X86_PMC_IDX_MAX)
return false;
return false;

done:
sched->state.counter = idx;

if (c->overlap)
perf_sched_save_state(sched);
Expand Down

0 comments on commit 4defea8

Please sign in to comment.