diff options
-rw-r--r-- | arch/x86/kernel/cpu/perf_event.c | 19 |
1 files changed, 14 insertions, 5 deletions
diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index fa6fdec5afb..66f8ba9a67f 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c | |||
@@ -574,16 +574,25 @@ static bool __perf_sched_find_counter(struct perf_sched *sched) | |||
574 | 574 | ||
575 | c = sched->constraints[sched->state.event]; | 575 | c = sched->constraints[sched->state.event]; |
576 | 576 | ||
577 | /* Prefer fixed purpose counters */ | ||
578 | if (x86_pmu.num_counters_fixed) { | ||
579 | idx = X86_PMC_IDX_FIXED; | ||
580 | for_each_set_bit_cont(idx, c->idxmsk, X86_PMC_IDX_MAX) { | ||
581 | if (!__test_and_set_bit(idx, sched->state.used)) | ||
582 | goto done; | ||
583 | } | ||
584 | } | ||
577 | /* Grab the first unused counter starting with idx */ | 585 | /* Grab the first unused counter starting with idx */ |
578 | idx = sched->state.counter; | 586 | idx = sched->state.counter; |
579 | for_each_set_bit_cont(idx, c->idxmsk, X86_PMC_IDX_MAX) { | 587 | for_each_set_bit_cont(idx, c->idxmsk, X86_PMC_IDX_FIXED) { |
580 | if (!__test_and_set_bit(idx, sched->state.used)) | 588 | if (!__test_and_set_bit(idx, sched->state.used)) |
581 | break; | 589 | goto done; |
582 | } | 590 | } |
583 | sched->state.counter = idx; | ||
584 | 591 | ||
585 | if (idx >= X86_PMC_IDX_MAX) | 592 | return false; |
586 | return false; | 593 | |
594 | done: | ||
595 | sched->state.counter = idx; | ||
587 | 596 | ||
588 | if (c->overlap) | 597 | if (c->overlap) |
589 | perf_sched_save_state(sched); | 598 | perf_sched_save_state(sched); |