aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/cpu/perf_counter.c
diff options
context:
space:
mode:
authormarkus.t.metzger@intel.com <markus.t.metzger@intel.com>2009-09-02 10:04:46 -0400
committerIngo Molnar <mingo@elte.hu>2009-09-04 03:26:39 -0400
commit747b50aaf728987732e6ff3ba10aba4acc4e0277 (patch)
treedd1b75f7d14b8bf7dff2519058516be69e70c356 /arch/x86/kernel/cpu/perf_counter.c
parentdc86cabe4b242446ea9aa8492c727e1220817898 (diff)
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 <markus.t.metzger@intel.com> Acked-by: Peter Zijlstra <a.p.zijlstra@chello.nl> LKML-Reference: <20090902140612.943801000@intel.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/kernel/cpu/perf_counter.c')
-rw-r--r--arch/x86/kernel/cpu/perf_counter.c25
1 files 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)
769 int cpu, err = 0; 769 int cpu, err = 0;
770 770
771 if (!bts_available()) 771 if (!bts_available())
772 return -EOPNOTSUPP; 772 return 0;
773 773
774 get_online_cpus(); 774 get_online_cpus();
775 775
@@ -914,7 +914,7 @@ static int __hw_perf_counter_init(struct perf_counter *counter)
914 if (!reserve_pmc_hardware()) 914 if (!reserve_pmc_hardware())
915 err = -EBUSY; 915 err = -EBUSY;
916 else 916 else
917 reserve_bts_hardware(); 917 err = reserve_bts_hardware();
918 } 918 }
919 if (!err) 919 if (!err)
920 atomic_inc(&active_counters); 920 atomic_inc(&active_counters);
@@ -979,6 +979,13 @@ static int __hw_perf_counter_init(struct perf_counter *counter)
979 if (config == -1LL) 979 if (config == -1LL)
980 return -EINVAL; 980 return -EINVAL;
981 981
982 /*
983 * Branch tracing:
984 */
985 if ((attr->config == PERF_COUNT_HW_BRANCH_INSTRUCTIONS) &&
986 (hwc->sample_period == 1) && !bts_available())
987 return -EOPNOTSUPP;
988
982 hwc->config |= config; 989 hwc->config |= config;
983 990
984 return 0; 991 return 0;
@@ -1355,19 +1362,9 @@ static int x86_pmu_enable(struct perf_counter *counter)
1355 1362
1356 idx = fixed_mode_idx(counter, hwc); 1363 idx = fixed_mode_idx(counter, hwc);
1357 if (idx == X86_PMC_IDX_FIXED_BTS) { 1364 if (idx == X86_PMC_IDX_FIXED_BTS) {
1358 /* 1365 /* BTS is already occupied. */
1359 * Try to use BTS for branch tracing. If that is not
1360 * available, try to get a generic counter.
1361 */
1362 if (unlikely(!cpuc->ds))
1363 goto try_generic;
1364
1365 /*
1366 * Try to get the fixed counter, if that is already taken
1367 * then try to get a generic counter:
1368 */
1369 if (test_and_set_bit(idx, cpuc->used_mask)) 1366 if (test_and_set_bit(idx, cpuc->used_mask))
1370 goto try_generic; 1367 return -EAGAIN;
1371 1368
1372 hwc->config_base = 0; 1369 hwc->config_base = 0;
1373 hwc->counter_base = 0; 1370 hwc->counter_base = 0;