aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarkus Metzger <markus.t.metzger@intel.com>2009-07-21 09:56:48 -0400
committerIngo Molnar <mingo@elte.hu>2009-08-09 07:04:14 -0400
commit30dd568c912602b7dbd609a45d053e01b13422bb (patch)
tree96e970d91b3ef06301ca0f03bc4b1a0068b06122
parent183f3b0887083d36c8a25cd5e3518906415d1889 (diff)
x86, perf_counter, bts: Add BTS support to perfcounters
Implement a performance counter with: attr.type = PERF_TYPE_HARDWARE attr.config = PERF_COUNT_HW_BRANCH_INSTRUCTIONS attr.sample_period = 1 Using branch trace store (BTS) on x86 hardware, if available. The from and to address for each branch can be sampled using: PERF_SAMPLE_IP for the from address PERF_SAMPLE_ADDR for the to address [ v2: address review feedback, fix bugs ] Signed-off-by: Markus Metzger <markus.t.metzger@intel.com> Acked-by: Peter Zijlstra <a.p.zijlstra@chello.nl> Signed-off-by: Ingo Molnar <mingo@elte.hu>
-rw-r--r--arch/x86/include/asm/perf_counter.h10
-rw-r--r--arch/x86/kernel/cpu/perf_counter.c325
-rw-r--r--include/linux/perf_counter.h2
-rw-r--r--kernel/perf_counter.c10
4 files changed, 340 insertions, 7 deletions
diff --git a/arch/x86/include/asm/perf_counter.h b/arch/x86/include/asm/perf_counter.h
index fa64e401589d..e7b7c938ae27 100644
--- a/arch/x86/include/asm/perf_counter.h
+++ b/arch/x86/include/asm/perf_counter.h
@@ -84,6 +84,16 @@ union cpuid10_edx {
84#define MSR_ARCH_PERFMON_FIXED_CTR2 0x30b 84#define MSR_ARCH_PERFMON_FIXED_CTR2 0x30b
85#define X86_PMC_IDX_FIXED_BUS_CYCLES (X86_PMC_IDX_FIXED + 2) 85#define X86_PMC_IDX_FIXED_BUS_CYCLES (X86_PMC_IDX_FIXED + 2)
86 86
87/*
88 * We model BTS tracing as another fixed-mode PMC.
89 *
90 * We choose a value in the middle of the fixed counter range, since lower
91 * values are used by actual fixed counters and higher values are used
92 * to indicate other overflow conditions in the PERF_GLOBAL_STATUS msr.
93 */
94#define X86_PMC_IDX_FIXED_BTS (X86_PMC_IDX_FIXED + 16)
95
96
87#ifdef CONFIG_PERF_COUNTERS 97#ifdef CONFIG_PERF_COUNTERS
88extern void init_hw_perf_counters(void); 98extern void init_hw_perf_counters(void);
89extern void perf_counters_lapic_init(void); 99extern void perf_counters_lapic_init(void);
diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c
index a7aa8f900954..b237c181aa41 100644
--- a/arch/x86/kernel/cpu/perf_counter.c
+++ b/arch/x86/kernel/cpu/perf_counter.c
@@ -6,6 +6,7 @@
6 * Copyright (C) 2009 Jaswinder Singh Rajput 6 * Copyright (C) 2009 Jaswinder Singh Rajput
7 * Copyright (C) 2009 Advanced Micro Devices, Inc., Robert Richter 7 * Copyright (C) 2009 Advanced Micro Devices, Inc., Robert Richter
8 * Copyright (C) 2008-2009 Red Hat, Inc., Peter Zijlstra <pzijlstr@redhat.com> 8 * Copyright (C) 2008-2009 Red Hat, Inc., Peter Zijlstra <pzijlstr@redhat.com>
9 * Copyright (C) 2009 Intel Corporation, <markus.t.metzger@intel.com>
9 * 10 *
10 * For licencing details see kernel-base/COPYING 11 * For licencing details see kernel-base/COPYING
11 */ 12 */
@@ -20,6 +21,7 @@
20#include <linux/sched.h> 21#include <linux/sched.h>
21#include <linux/uaccess.h> 22#include <linux/uaccess.h>
22#include <linux/highmem.h> 23#include <linux/highmem.h>
24#include <linux/cpu.h>
23 25
24#include <asm/apic.h> 26#include <asm/apic.h>
25#include <asm/stacktrace.h> 27#include <asm/stacktrace.h>
@@ -27,12 +29,52 @@
27 29
28static u64 perf_counter_mask __read_mostly; 30static u64 perf_counter_mask __read_mostly;
29 31
32/* The maximal number of PEBS counters: */
33#define MAX_PEBS_COUNTERS 4
34
35/* The size of a BTS record in bytes: */
36#define BTS_RECORD_SIZE 24
37
38/* The size of a per-cpu BTS buffer in bytes: */
39#define BTS_BUFFER_SIZE (BTS_RECORD_SIZE * 1024)
40
41/* The BTS overflow threshold in bytes from the end of the buffer: */
42#define BTS_OVFL_TH (BTS_RECORD_SIZE * 64)
43
44
45/*
46 * Bits in the debugctlmsr controlling branch tracing.
47 */
48#define X86_DEBUGCTL_TR (1 << 6)
49#define X86_DEBUGCTL_BTS (1 << 7)
50#define X86_DEBUGCTL_BTINT (1 << 8)
51#define X86_DEBUGCTL_BTS_OFF_OS (1 << 9)
52#define X86_DEBUGCTL_BTS_OFF_USR (1 << 10)
53
54/*
55 * A debug store configuration.
56 *
57 * We only support architectures that use 64bit fields.
58 */
59struct debug_store {
60 u64 bts_buffer_base;
61 u64 bts_index;
62 u64 bts_absolute_maximum;
63 u64 bts_interrupt_threshold;
64 u64 pebs_buffer_base;
65 u64 pebs_index;
66 u64 pebs_absolute_maximum;
67 u64 pebs_interrupt_threshold;
68 u64 pebs_counter_reset[MAX_PEBS_COUNTERS];
69};
70
30struct cpu_hw_counters { 71struct cpu_hw_counters {
31 struct perf_counter *counters[X86_PMC_IDX_MAX]; 72 struct perf_counter *counters[X86_PMC_IDX_MAX];
32 unsigned long used_mask[BITS_TO_LONGS(X86_PMC_IDX_MAX)]; 73 unsigned long used_mask[BITS_TO_LONGS(X86_PMC_IDX_MAX)];
33 unsigned long active_mask[BITS_TO_LONGS(X86_PMC_IDX_MAX)]; 74 unsigned long active_mask[BITS_TO_LONGS(X86_PMC_IDX_MAX)];
34 unsigned long interrupts; 75 unsigned long interrupts;
35 int enabled; 76 int enabled;
77 struct debug_store *ds;
36}; 78};
37 79
38/* 80/*
@@ -57,6 +99,8 @@ struct x86_pmu {
57 u64 counter_mask; 99 u64 counter_mask;
58 u64 max_period; 100 u64 max_period;
59 u64 intel_ctrl; 101 u64 intel_ctrl;
102 void (*enable_bts)(u64 config);
103 void (*disable_bts)(void);
60}; 104};
61 105
62static struct x86_pmu x86_pmu __read_mostly; 106static struct x86_pmu x86_pmu __read_mostly;
@@ -576,6 +620,9 @@ x86_perf_counter_update(struct perf_counter *counter,
576 u64 prev_raw_count, new_raw_count; 620 u64 prev_raw_count, new_raw_count;
577 s64 delta; 621 s64 delta;
578 622
623 if (idx == X86_PMC_IDX_FIXED_BTS)
624 return 0;
625
579 /* 626 /*
580 * Careful: an NMI might modify the previous counter value. 627 * Careful: an NMI might modify the previous counter value.
581 * 628 *
@@ -659,10 +706,109 @@ static void release_pmc_hardware(void)
659 enable_lapic_nmi_watchdog(); 706 enable_lapic_nmi_watchdog();
660} 707}
661 708
709static inline bool bts_available(void)
710{
711 return x86_pmu.enable_bts != NULL;
712}
713
714static inline void init_debug_store_on_cpu(int cpu)
715{
716 struct debug_store *ds = per_cpu(cpu_hw_counters, cpu).ds;
717
718 if (!ds)
719 return;
720
721 wrmsr_on_cpu(cpu, MSR_IA32_DS_AREA,
722 (u32)((u64)(long)ds), (u32)((u64)(long)ds >> 32));
723}
724
725static inline void fini_debug_store_on_cpu(int cpu)
726{
727 if (!per_cpu(cpu_hw_counters, cpu).ds)
728 return;
729
730 wrmsr_on_cpu(cpu, MSR_IA32_DS_AREA, 0, 0);
731}
732
733static void release_bts_hardware(void)
734{
735 int cpu;
736
737 if (!bts_available())
738 return;
739
740 get_online_cpus();
741
742 for_each_online_cpu(cpu)
743 fini_debug_store_on_cpu(cpu);
744
745 for_each_possible_cpu(cpu) {
746 struct debug_store *ds = per_cpu(cpu_hw_counters, cpu).ds;
747
748 if (!ds)
749 continue;
750
751 per_cpu(cpu_hw_counters, cpu).ds = NULL;
752
753 kfree((void *)(long)ds->bts_buffer_base);
754 kfree(ds);
755 }
756
757 put_online_cpus();
758}
759
760static int reserve_bts_hardware(void)
761{
762 int cpu, err = 0;
763
764 if (!bts_available())
765 return -EOPNOTSUPP;
766
767 get_online_cpus();
768
769 for_each_possible_cpu(cpu) {
770 struct debug_store *ds;
771 void *buffer;
772
773 err = -ENOMEM;
774 buffer = kzalloc(BTS_BUFFER_SIZE, GFP_KERNEL);
775 if (unlikely(!buffer))
776 break;
777
778 ds = kzalloc(sizeof(*ds), GFP_KERNEL);
779 if (unlikely(!ds)) {
780 kfree(buffer);
781 break;
782 }
783
784 ds->bts_buffer_base = (u64)(long)buffer;
785 ds->bts_index = ds->bts_buffer_base;
786 ds->bts_absolute_maximum =
787 ds->bts_buffer_base + BTS_BUFFER_SIZE;
788 ds->bts_interrupt_threshold =
789 ds->bts_absolute_maximum - BTS_OVFL_TH;
790
791 per_cpu(cpu_hw_counters, cpu).ds = ds;
792 err = 0;
793 }
794
795 if (err)
796 release_bts_hardware();
797 else {
798 for_each_online_cpu(cpu)
799 init_debug_store_on_cpu(cpu);
800 }
801
802 put_online_cpus();
803
804 return err;
805}
806
662static void hw_perf_counter_destroy(struct perf_counter *counter) 807static void hw_perf_counter_destroy(struct perf_counter *counter)
663{ 808{
664 if (atomic_dec_and_mutex_lock(&active_counters, &pmc_reserve_mutex)) { 809 if (atomic_dec_and_mutex_lock(&active_counters, &pmc_reserve_mutex)) {
665 release_pmc_hardware(); 810 release_pmc_hardware();
811 release_bts_hardware();
666 mutex_unlock(&pmc_reserve_mutex); 812 mutex_unlock(&pmc_reserve_mutex);
667 } 813 }
668} 814}
@@ -705,6 +851,42 @@ set_ext_hw_attr(struct hw_perf_counter *hwc, struct perf_counter_attr *attr)
705 return 0; 851 return 0;
706} 852}
707 853
854static void intel_pmu_enable_bts(u64 config)
855{
856 unsigned long debugctlmsr;
857
858 debugctlmsr = get_debugctlmsr();
859
860 debugctlmsr |= X86_DEBUGCTL_TR;
861 debugctlmsr |= X86_DEBUGCTL_BTS;
862 debugctlmsr |= X86_DEBUGCTL_BTINT;
863
864 if (!(config & ARCH_PERFMON_EVENTSEL_OS))
865 debugctlmsr |= X86_DEBUGCTL_BTS_OFF_OS;
866
867 if (!(config & ARCH_PERFMON_EVENTSEL_USR))
868 debugctlmsr |= X86_DEBUGCTL_BTS_OFF_USR;
869
870 update_debugctlmsr(debugctlmsr);
871}
872
873static void intel_pmu_disable_bts(void)
874{
875 struct cpu_hw_counters *cpuc = &__get_cpu_var(cpu_hw_counters);
876 unsigned long debugctlmsr;
877
878 if (!cpuc->ds)
879 return;
880
881 debugctlmsr = get_debugctlmsr();
882
883 debugctlmsr &=
884 ~(X86_DEBUGCTL_TR | X86_DEBUGCTL_BTS | X86_DEBUGCTL_BTINT |
885 X86_DEBUGCTL_BTS_OFF_OS | X86_DEBUGCTL_BTS_OFF_USR);
886
887 update_debugctlmsr(debugctlmsr);
888}
889
708/* 890/*
709 * Setup the hardware configuration for a given attr_type 891 * Setup the hardware configuration for a given attr_type
710 */ 892 */
@@ -721,9 +903,13 @@ static int __hw_perf_counter_init(struct perf_counter *counter)
721 err = 0; 903 err = 0;
722 if (!atomic_inc_not_zero(&active_counters)) { 904 if (!atomic_inc_not_zero(&active_counters)) {
723 mutex_lock(&pmc_reserve_mutex); 905 mutex_lock(&pmc_reserve_mutex);
724 if (atomic_read(&active_counters) == 0 && !reserve_pmc_hardware()) 906 if (atomic_read(&active_counters) == 0) {
725 err = -EBUSY; 907 if (!reserve_pmc_hardware())
726 else 908 err = -EBUSY;
909 else
910 reserve_bts_hardware();
911 }
912 if (!err)
727 atomic_inc(&active_counters); 913 atomic_inc(&active_counters);
728 mutex_unlock(&pmc_reserve_mutex); 914 mutex_unlock(&pmc_reserve_mutex);
729 } 915 }
@@ -801,7 +987,18 @@ static void p6_pmu_disable_all(void)
801 987
802static void intel_pmu_disable_all(void) 988static void intel_pmu_disable_all(void)
803{ 989{
990 struct cpu_hw_counters *cpuc = &__get_cpu_var(cpu_hw_counters);
991
992 if (!cpuc->enabled)
993 return;
994
995 cpuc->enabled = 0;
996 barrier();
997
804 wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, 0); 998 wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, 0);
999
1000 if (test_bit(X86_PMC_IDX_FIXED_BTS, cpuc->active_mask))
1001 intel_pmu_disable_bts();
805} 1002}
806 1003
807static void amd_pmu_disable_all(void) 1004static void amd_pmu_disable_all(void)
@@ -859,7 +1056,25 @@ static void p6_pmu_enable_all(void)
859 1056
860static void intel_pmu_enable_all(void) 1057static void intel_pmu_enable_all(void)
861{ 1058{
1059 struct cpu_hw_counters *cpuc = &__get_cpu_var(cpu_hw_counters);
1060
1061 if (cpuc->enabled)
1062 return;
1063
1064 cpuc->enabled = 1;
1065 barrier();
1066
862 wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, x86_pmu.intel_ctrl); 1067 wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, x86_pmu.intel_ctrl);
1068
1069 if (test_bit(X86_PMC_IDX_FIXED_BTS, cpuc->active_mask)) {
1070 struct perf_counter *counter =
1071 cpuc->counters[X86_PMC_IDX_FIXED_BTS];
1072
1073 if (WARN_ON_ONCE(!counter))
1074 return;
1075
1076 intel_pmu_enable_bts(counter->hw.config);
1077 }
863} 1078}
864 1079
865static void amd_pmu_enable_all(void) 1080static void amd_pmu_enable_all(void)
@@ -946,6 +1161,11 @@ p6_pmu_disable_counter(struct hw_perf_counter *hwc, int idx)
946static inline void 1161static inline void
947intel_pmu_disable_counter(struct hw_perf_counter *hwc, int idx) 1162intel_pmu_disable_counter(struct hw_perf_counter *hwc, int idx)
948{ 1163{
1164 if (unlikely(idx == X86_PMC_IDX_FIXED_BTS)) {
1165 intel_pmu_disable_bts();
1166 return;
1167 }
1168
949 if (unlikely(hwc->config_base == MSR_ARCH_PERFMON_FIXED_CTR_CTRL)) { 1169 if (unlikely(hwc->config_base == MSR_ARCH_PERFMON_FIXED_CTR_CTRL)) {
950 intel_pmu_disable_fixed(hwc, idx); 1170 intel_pmu_disable_fixed(hwc, idx);
951 return; 1171 return;
@@ -974,6 +1194,9 @@ x86_perf_counter_set_period(struct perf_counter *counter,
974 s64 period = hwc->sample_period; 1194 s64 period = hwc->sample_period;
975 int err, ret = 0; 1195 int err, ret = 0;
976 1196
1197 if (idx == X86_PMC_IDX_FIXED_BTS)
1198 return 0;
1199
977 /* 1200 /*
978 * If we are way outside a reasoable range then just skip forward: 1201 * If we are way outside a reasoable range then just skip forward:
979 */ 1202 */
@@ -1056,6 +1279,14 @@ static void p6_pmu_enable_counter(struct hw_perf_counter *hwc, int idx)
1056 1279
1057static void intel_pmu_enable_counter(struct hw_perf_counter *hwc, int idx) 1280static void intel_pmu_enable_counter(struct hw_perf_counter *hwc, int idx)
1058{ 1281{
1282 if (unlikely(idx == X86_PMC_IDX_FIXED_BTS)) {
1283 if (!__get_cpu_var(cpu_hw_counters).enabled)
1284 return;
1285
1286 intel_pmu_enable_bts(hwc->config);
1287 return;
1288 }
1289
1059 if (unlikely(hwc->config_base == MSR_ARCH_PERFMON_FIXED_CTR_CTRL)) { 1290 if (unlikely(hwc->config_base == MSR_ARCH_PERFMON_FIXED_CTR_CTRL)) {
1060 intel_pmu_enable_fixed(hwc, idx); 1291 intel_pmu_enable_fixed(hwc, idx);
1061 return; 1292 return;
@@ -1077,11 +1308,16 @@ fixed_mode_idx(struct perf_counter *counter, struct hw_perf_counter *hwc)
1077{ 1308{
1078 unsigned int event; 1309 unsigned int event;
1079 1310
1311 event = hwc->config & ARCH_PERFMON_EVENT_MASK;
1312
1313 if (unlikely((event ==
1314 x86_pmu.event_map(PERF_COUNT_HW_BRANCH_INSTRUCTIONS)) &&
1315 (hwc->sample_period == 1)))
1316 return X86_PMC_IDX_FIXED_BTS;
1317
1080 if (!x86_pmu.num_counters_fixed) 1318 if (!x86_pmu.num_counters_fixed)
1081 return -1; 1319 return -1;
1082 1320
1083 event = hwc->config & ARCH_PERFMON_EVENT_MASK;
1084
1085 if (unlikely(event == x86_pmu.event_map(PERF_COUNT_HW_INSTRUCTIONS))) 1321 if (unlikely(event == x86_pmu.event_map(PERF_COUNT_HW_INSTRUCTIONS)))
1086 return X86_PMC_IDX_FIXED_INSTRUCTIONS; 1322 return X86_PMC_IDX_FIXED_INSTRUCTIONS;
1087 if (unlikely(event == x86_pmu.event_map(PERF_COUNT_HW_CPU_CYCLES))) 1323 if (unlikely(event == x86_pmu.event_map(PERF_COUNT_HW_CPU_CYCLES)))
@@ -1102,7 +1338,25 @@ static int x86_pmu_enable(struct perf_counter *counter)
1102 int idx; 1338 int idx;
1103 1339
1104 idx = fixed_mode_idx(counter, hwc); 1340 idx = fixed_mode_idx(counter, hwc);
1105 if (idx >= 0) { 1341 if (idx == X86_PMC_IDX_FIXED_BTS) {
1342 /*
1343 * Try to use BTS for branch tracing. If that is not
1344 * available, try to get a generic counter.
1345 */
1346 if (unlikely(!cpuc->ds))
1347 goto try_generic;
1348
1349 /*
1350 * Try to get the fixed counter, if that is already taken
1351 * then try to get a generic counter:
1352 */
1353 if (test_and_set_bit(idx, cpuc->used_mask))
1354 goto try_generic;
1355
1356 hwc->config_base = 0;
1357 hwc->counter_base = 0;
1358 hwc->idx = idx;
1359 } else if (idx >= 0) {
1106 /* 1360 /*
1107 * Try to get the fixed counter, if that is already taken 1361 * Try to get the fixed counter, if that is already taken
1108 * then try to get a generic counter: 1362 * then try to get a generic counter:
@@ -1213,6 +1467,45 @@ void perf_counter_print_debug(void)
1213 local_irq_restore(flags); 1467 local_irq_restore(flags);
1214} 1468}
1215 1469
1470static void intel_pmu_drain_bts_buffer(struct cpu_hw_counters *cpuc,
1471 struct perf_sample_data *data)
1472{
1473 struct debug_store *ds = cpuc->ds;
1474 struct bts_record {
1475 u64 from;
1476 u64 to;
1477 u64 flags;
1478 };
1479 struct perf_counter *counter = cpuc->counters[X86_PMC_IDX_FIXED_BTS];
1480 unsigned long orig_ip = data->regs->ip;
1481 u64 at;
1482
1483 if (!counter)
1484 return;
1485
1486 if (!ds)
1487 return;
1488
1489 for (at = ds->bts_buffer_base;
1490 at < ds->bts_index;
1491 at += sizeof(struct bts_record)) {
1492 struct bts_record *rec = (struct bts_record *)(long)at;
1493
1494 data->regs->ip = rec->from;
1495 data->addr = rec->to;
1496
1497 perf_counter_output(counter, 1, data);
1498 }
1499
1500 ds->bts_index = ds->bts_buffer_base;
1501
1502 data->regs->ip = orig_ip;
1503 data->addr = 0;
1504
1505 /* There's new data available. */
1506 counter->pending_kill = POLL_IN;
1507}
1508
1216static void x86_pmu_disable(struct perf_counter *counter) 1509static void x86_pmu_disable(struct perf_counter *counter)
1217{ 1510{
1218 struct cpu_hw_counters *cpuc = &__get_cpu_var(cpu_hw_counters); 1511 struct cpu_hw_counters *cpuc = &__get_cpu_var(cpu_hw_counters);
@@ -1237,6 +1530,15 @@ static void x86_pmu_disable(struct perf_counter *counter)
1237 * that we are disabling: 1530 * that we are disabling:
1238 */ 1531 */
1239 x86_perf_counter_update(counter, hwc, idx); 1532 x86_perf_counter_update(counter, hwc, idx);
1533
1534 /* Drain the remaining BTS records. */
1535 if (unlikely(idx == X86_PMC_IDX_FIXED_BTS)) {
1536 struct perf_sample_data data;
1537 struct pt_regs regs;
1538
1539 data.regs = &regs;
1540 intel_pmu_drain_bts_buffer(cpuc, &data);
1541 }
1240 cpuc->counters[idx] = NULL; 1542 cpuc->counters[idx] = NULL;
1241 clear_bit(idx, cpuc->used_mask); 1543 clear_bit(idx, cpuc->used_mask);
1242 1544
@@ -1264,6 +1566,7 @@ static int intel_pmu_save_and_restart(struct perf_counter *counter)
1264 1566
1265static void intel_pmu_reset(void) 1567static void intel_pmu_reset(void)
1266{ 1568{
1569 struct debug_store *ds = __get_cpu_var(cpu_hw_counters).ds;
1267 unsigned long flags; 1570 unsigned long flags;
1268 int idx; 1571 int idx;
1269 1572
@@ -1281,6 +1584,8 @@ static void intel_pmu_reset(void)
1281 for (idx = 0; idx < x86_pmu.num_counters_fixed; idx++) { 1584 for (idx = 0; idx < x86_pmu.num_counters_fixed; idx++) {
1282 checking_wrmsrl(MSR_ARCH_PERFMON_FIXED_CTR0 + idx, 0ull); 1585 checking_wrmsrl(MSR_ARCH_PERFMON_FIXED_CTR0 + idx, 0ull);
1283 } 1586 }
1587 if (ds)
1588 ds->bts_index = ds->bts_buffer_base;
1284 1589
1285 local_irq_restore(flags); 1590 local_irq_restore(flags);
1286} 1591}
@@ -1346,6 +1651,7 @@ static int intel_pmu_handle_irq(struct pt_regs *regs)
1346 cpuc = &__get_cpu_var(cpu_hw_counters); 1651 cpuc = &__get_cpu_var(cpu_hw_counters);
1347 1652
1348 perf_disable(); 1653 perf_disable();
1654 intel_pmu_drain_bts_buffer(cpuc, &data);
1349 status = intel_pmu_get_status(); 1655 status = intel_pmu_get_status();
1350 if (!status) { 1656 if (!status) {
1351 perf_enable(); 1657 perf_enable();
@@ -1547,6 +1853,8 @@ static struct x86_pmu intel_pmu = {
1547 * the generic counter period: 1853 * the generic counter period:
1548 */ 1854 */
1549 .max_period = (1ULL << 31) - 1, 1855 .max_period = (1ULL << 31) - 1,
1856 .enable_bts = intel_pmu_enable_bts,
1857 .disable_bts = intel_pmu_disable_bts,
1550}; 1858};
1551 1859
1552static struct x86_pmu amd_pmu = { 1860static struct x86_pmu amd_pmu = {
@@ -1936,3 +2244,8 @@ struct perf_callchain_entry *perf_callchain(struct pt_regs *regs)
1936 2244
1937 return entry; 2245 return entry;
1938} 2246}
2247
2248void hw_perf_counter_setup_online(int cpu)
2249{
2250 init_debug_store_on_cpu(cpu);
2251}
diff --git a/include/linux/perf_counter.h b/include/linux/perf_counter.h
index 2aabe43c1d04..0a6f3209c9de 100644
--- a/include/linux/perf_counter.h
+++ b/include/linux/perf_counter.h
@@ -692,6 +692,8 @@ struct perf_sample_data {
692 692
693extern int perf_counter_overflow(struct perf_counter *counter, int nmi, 693extern int perf_counter_overflow(struct perf_counter *counter, int nmi,
694 struct perf_sample_data *data); 694 struct perf_sample_data *data);
695extern void perf_counter_output(struct perf_counter *counter, int nmi,
696 struct perf_sample_data *data);
695 697
696/* 698/*
697 * Return 1 for a software counter, 0 for a hardware counter 699 * Return 1 for a software counter, 0 for a hardware counter
diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c
index 546e62d62941..bf8110b35c51 100644
--- a/kernel/perf_counter.c
+++ b/kernel/perf_counter.c
@@ -88,6 +88,7 @@ void __weak hw_perf_disable(void) { barrier(); }
88void __weak hw_perf_enable(void) { barrier(); } 88void __weak hw_perf_enable(void) { barrier(); }
89 89
90void __weak hw_perf_counter_setup(int cpu) { barrier(); } 90void __weak hw_perf_counter_setup(int cpu) { barrier(); }
91void __weak hw_perf_counter_setup_online(int cpu) { barrier(); }
91 92
92int __weak 93int __weak
93hw_perf_group_sched_in(struct perf_counter *group_leader, 94hw_perf_group_sched_in(struct perf_counter *group_leader,
@@ -2630,7 +2631,7 @@ static u32 perf_counter_tid(struct perf_counter *counter, struct task_struct *p)
2630 return task_pid_nr_ns(p, counter->ns); 2631 return task_pid_nr_ns(p, counter->ns);
2631} 2632}
2632 2633
2633static void perf_counter_output(struct perf_counter *counter, int nmi, 2634void perf_counter_output(struct perf_counter *counter, int nmi,
2634 struct perf_sample_data *data) 2635 struct perf_sample_data *data)
2635{ 2636{
2636 int ret; 2637 int ret;
@@ -4566,6 +4567,11 @@ perf_cpu_notify(struct notifier_block *self, unsigned long action, void *hcpu)
4566 perf_counter_init_cpu(cpu); 4567 perf_counter_init_cpu(cpu);
4567 break; 4568 break;
4568 4569
4570 case CPU_ONLINE:
4571 case CPU_ONLINE_FROZEN:
4572 hw_perf_counter_setup_online(cpu);
4573 break;
4574
4569 case CPU_DOWN_PREPARE: 4575 case CPU_DOWN_PREPARE:
4570 case CPU_DOWN_PREPARE_FROZEN: 4576 case CPU_DOWN_PREPARE_FROZEN:
4571 perf_counter_exit_cpu(cpu); 4577 perf_counter_exit_cpu(cpu);
@@ -4590,6 +4596,8 @@ void __init perf_counter_init(void)
4590{ 4596{
4591 perf_cpu_notify(&perf_cpu_nb, (unsigned long)CPU_UP_PREPARE, 4597 perf_cpu_notify(&perf_cpu_nb, (unsigned long)CPU_UP_PREPARE,
4592 (void *)(long)smp_processor_id()); 4598 (void *)(long)smp_processor_id());
4599 perf_cpu_notify(&perf_cpu_nb, (unsigned long)CPU_ONLINE,
4600 (void *)(long)smp_processor_id());
4593 register_cpu_notifier(&perf_cpu_nb); 4601 register_cpu_notifier(&perf_cpu_nb);
4594} 4602}
4595 4603