From 747b50aaf728987732e6ff3ba10aba4acc4e0277 Mon Sep 17 00:00:00 2001 From: "markus.t.metzger@intel.com" Date: Wed, 2 Sep 2009 16:04:46 +0200 Subject: [PATCH] x86, perf_counter, bts: Fail if BTS is not available Reserve PERF_COUNT_HW_BRANCH_INSTRUCTIONS with sample_period == 1 for BTS tracing and fail, if BTS is not available. Signed-off-by: Markus Metzger Acked-by: Peter Zijlstra LKML-Reference: <20090902140612.943801000@intel.com> Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_counter.c | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c index 396e35db705..2f41874ffb8 100644 --- a/arch/x86/kernel/cpu/perf_counter.c +++ b/arch/x86/kernel/cpu/perf_counter.c @@ -769,7 +769,7 @@ static int reserve_bts_hardware(void) int cpu, err = 0; if (!bts_available()) - return -EOPNOTSUPP; + return 0; get_online_cpus(); @@ -914,7 +914,7 @@ static int __hw_perf_counter_init(struct perf_counter *counter) if (!reserve_pmc_hardware()) err = -EBUSY; else - reserve_bts_hardware(); + err = reserve_bts_hardware(); } if (!err) atomic_inc(&active_counters); @@ -979,6 +979,13 @@ static int __hw_perf_counter_init(struct perf_counter *counter) if (config == -1LL) return -EINVAL; + /* + * Branch tracing: + */ + if ((attr->config == PERF_COUNT_HW_BRANCH_INSTRUCTIONS) && + (hwc->sample_period == 1) && !bts_available()) + return -EOPNOTSUPP; + hwc->config |= config; return 0; @@ -1355,19 +1362,9 @@ static int x86_pmu_enable(struct perf_counter *counter) idx = fixed_mode_idx(counter, hwc); if (idx == X86_PMC_IDX_FIXED_BTS) { - /* - * Try to use BTS for branch tracing. If that is not - * available, try to get a generic counter. - */ - if (unlikely(!cpuc->ds)) - goto try_generic; - - /* - * Try to get the fixed counter, if that is already taken - * then try to get a generic counter: - */ + /* BTS is already occupied. */ if (test_and_set_bit(idx, cpuc->used_mask)) - goto try_generic; + return -EAGAIN; hwc->config_base = 0; hwc->counter_base = 0; -- 2.11.4.GIT