diff options
author | Ingo Molnar <mingo@elte.hu> | 2012-01-27 06:07:57 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2012-01-27 06:08:09 -0500 |
commit | 44a683971119bafb5bc30778f92ee773680ebb6f (patch) | |
tree | 58648459f29d45c447bd2352e81844d4d9aa3a15 /arch | |
parent | 801493c2e249a7314e9e8e54ad60d613d0a86f14 (diff) | |
parent | 08aa0d1f376e9b966568316bd2019b3c1274d885 (diff) |
Merge branch 'perf/fast' into perf/core
Merge reason: Lets ready it for v3.4
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/include/asm/perf_event.h | 4 | ||||
-rw-r--r-- | arch/frv/include/asm/perf_event.h | 2 | ||||
-rw-r--r-- | arch/hexagon/include/asm/perf_event.h | 2 | ||||
-rw-r--r-- | arch/powerpc/include/asm/perf_event_server.h | 2 | ||||
-rw-r--r-- | arch/powerpc/kernel/perf_event.c | 6 | ||||
-rw-r--r-- | arch/s390/include/asm/perf_event.h | 1 | ||||
-rw-r--r-- | arch/x86/include/asm/perf_event.h | 2 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/perf_event.c | 82 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/perf_event.h | 8 |
9 files changed, 96 insertions, 13 deletions
diff --git a/arch/arm/include/asm/perf_event.h b/arch/arm/include/asm/perf_event.h index 99cfe3607989..7523340afb8a 100644 --- a/arch/arm/include/asm/perf_event.h +++ b/arch/arm/include/asm/perf_event.h | |||
@@ -12,10 +12,6 @@ | |||
12 | #ifndef __ARM_PERF_EVENT_H__ | 12 | #ifndef __ARM_PERF_EVENT_H__ |
13 | #define __ARM_PERF_EVENT_H__ | 13 | #define __ARM_PERF_EVENT_H__ |
14 | 14 | ||
15 | /* ARM performance counters start from 1 (in the cp15 accesses) so use the | ||
16 | * same indexes here for consistency. */ | ||
17 | #define PERF_EVENT_INDEX_OFFSET 1 | ||
18 | |||
19 | /* ARM perf PMU IDs for use by internal perf clients. */ | 15 | /* ARM perf PMU IDs for use by internal perf clients. */ |
20 | enum arm_perf_pmu_ids { | 16 | enum arm_perf_pmu_ids { |
21 | ARM_PERF_PMU_ID_XSCALE1 = 0, | 17 | ARM_PERF_PMU_ID_XSCALE1 = 0, |
diff --git a/arch/frv/include/asm/perf_event.h b/arch/frv/include/asm/perf_event.h index a69e0155d146..c52ea5546b5b 100644 --- a/arch/frv/include/asm/perf_event.h +++ b/arch/frv/include/asm/perf_event.h | |||
@@ -12,6 +12,4 @@ | |||
12 | #ifndef _ASM_PERF_EVENT_H | 12 | #ifndef _ASM_PERF_EVENT_H |
13 | #define _ASM_PERF_EVENT_H | 13 | #define _ASM_PERF_EVENT_H |
14 | 14 | ||
15 | #define PERF_EVENT_INDEX_OFFSET 0 | ||
16 | |||
17 | #endif /* _ASM_PERF_EVENT_H */ | 15 | #endif /* _ASM_PERF_EVENT_H */ |
diff --git a/arch/hexagon/include/asm/perf_event.h b/arch/hexagon/include/asm/perf_event.h index 6c2910f91180..8b8526b491c7 100644 --- a/arch/hexagon/include/asm/perf_event.h +++ b/arch/hexagon/include/asm/perf_event.h | |||
@@ -19,6 +19,4 @@ | |||
19 | #ifndef _ASM_PERF_EVENT_H | 19 | #ifndef _ASM_PERF_EVENT_H |
20 | #define _ASM_PERF_EVENT_H | 20 | #define _ASM_PERF_EVENT_H |
21 | 21 | ||
22 | #define PERF_EVENT_INDEX_OFFSET 0 | ||
23 | |||
24 | #endif /* _ASM_PERF_EVENT_H */ | 22 | #endif /* _ASM_PERF_EVENT_H */ |
diff --git a/arch/powerpc/include/asm/perf_event_server.h b/arch/powerpc/include/asm/perf_event_server.h index 8f1df1208d23..1a8093fa8f71 100644 --- a/arch/powerpc/include/asm/perf_event_server.h +++ b/arch/powerpc/include/asm/perf_event_server.h | |||
@@ -61,8 +61,6 @@ struct pt_regs; | |||
61 | extern unsigned long perf_misc_flags(struct pt_regs *regs); | 61 | extern unsigned long perf_misc_flags(struct pt_regs *regs); |
62 | extern unsigned long perf_instruction_pointer(struct pt_regs *regs); | 62 | extern unsigned long perf_instruction_pointer(struct pt_regs *regs); |
63 | 63 | ||
64 | #define PERF_EVENT_INDEX_OFFSET 1 | ||
65 | |||
66 | /* | 64 | /* |
67 | * Only override the default definitions in include/linux/perf_event.h | 65 | * Only override the default definitions in include/linux/perf_event.h |
68 | * if we have hardware PMU support. | 66 | * if we have hardware PMU support. |
diff --git a/arch/powerpc/kernel/perf_event.c b/arch/powerpc/kernel/perf_event.c index 10a140f82cb8..d614ab57ccca 100644 --- a/arch/powerpc/kernel/perf_event.c +++ b/arch/powerpc/kernel/perf_event.c | |||
@@ -1187,6 +1187,11 @@ static int power_pmu_event_init(struct perf_event *event) | |||
1187 | return err; | 1187 | return err; |
1188 | } | 1188 | } |
1189 | 1189 | ||
1190 | static int power_pmu_event_idx(struct perf_event *event) | ||
1191 | { | ||
1192 | return event->hw.idx; | ||
1193 | } | ||
1194 | |||
1190 | struct pmu power_pmu = { | 1195 | struct pmu power_pmu = { |
1191 | .pmu_enable = power_pmu_enable, | 1196 | .pmu_enable = power_pmu_enable, |
1192 | .pmu_disable = power_pmu_disable, | 1197 | .pmu_disable = power_pmu_disable, |
@@ -1199,6 +1204,7 @@ struct pmu power_pmu = { | |||
1199 | .start_txn = power_pmu_start_txn, | 1204 | .start_txn = power_pmu_start_txn, |
1200 | .cancel_txn = power_pmu_cancel_txn, | 1205 | .cancel_txn = power_pmu_cancel_txn, |
1201 | .commit_txn = power_pmu_commit_txn, | 1206 | .commit_txn = power_pmu_commit_txn, |
1207 | .event_idx = power_pmu_event_idx, | ||
1202 | }; | 1208 | }; |
1203 | 1209 | ||
1204 | /* | 1210 | /* |
diff --git a/arch/s390/include/asm/perf_event.h b/arch/s390/include/asm/perf_event.h index a75f168d2718..4eb444edbe49 100644 --- a/arch/s390/include/asm/perf_event.h +++ b/arch/s390/include/asm/perf_event.h | |||
@@ -6,4 +6,3 @@ | |||
6 | 6 | ||
7 | /* Empty, just to avoid compiling error */ | 7 | /* Empty, just to avoid compiling error */ |
8 | 8 | ||
9 | #define PERF_EVENT_INDEX_OFFSET 0 | ||
diff --git a/arch/x86/include/asm/perf_event.h b/arch/x86/include/asm/perf_event.h index 096c975e099f..9b922c136254 100644 --- a/arch/x86/include/asm/perf_event.h +++ b/arch/x86/include/asm/perf_event.h | |||
@@ -188,8 +188,6 @@ extern u32 get_ibs_caps(void); | |||
188 | #ifdef CONFIG_PERF_EVENTS | 188 | #ifdef CONFIG_PERF_EVENTS |
189 | extern void perf_events_lapic_init(void); | 189 | extern void perf_events_lapic_init(void); |
190 | 190 | ||
191 | #define PERF_EVENT_INDEX_OFFSET 0 | ||
192 | |||
193 | /* | 191 | /* |
194 | * Abuse bit 3 of the cpu eflags register to indicate proper PEBS IP fixups. | 192 | * Abuse bit 3 of the cpu eflags register to indicate proper PEBS IP fixups. |
195 | * This flag is otherwise unused and ABI specified to be 0, so nobody should | 193 | * This flag is otherwise unused and ABI specified to be 0, so nobody should |
diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index 5adce1040b11..f8bddb5b0600 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/slab.h> | 24 | #include <linux/slab.h> |
25 | #include <linux/cpu.h> | 25 | #include <linux/cpu.h> |
26 | #include <linux/bitops.h> | 26 | #include <linux/bitops.h> |
27 | #include <linux/device.h> | ||
27 | 28 | ||
28 | #include <asm/apic.h> | 29 | #include <asm/apic.h> |
29 | #include <asm/stacktrace.h> | 30 | #include <asm/stacktrace.h> |
@@ -31,6 +32,7 @@ | |||
31 | #include <asm/compat.h> | 32 | #include <asm/compat.h> |
32 | #include <asm/smp.h> | 33 | #include <asm/smp.h> |
33 | #include <asm/alternative.h> | 34 | #include <asm/alternative.h> |
35 | #include <asm/timer.h> | ||
34 | 36 | ||
35 | #include "perf_event.h" | 37 | #include "perf_event.h" |
36 | 38 | ||
@@ -1210,6 +1212,8 @@ x86_pmu_notifier(struct notifier_block *self, unsigned long action, void *hcpu) | |||
1210 | break; | 1212 | break; |
1211 | 1213 | ||
1212 | case CPU_STARTING: | 1214 | case CPU_STARTING: |
1215 | if (x86_pmu.attr_rdpmc) | ||
1216 | set_in_cr4(X86_CR4_PCE); | ||
1213 | if (x86_pmu.cpu_starting) | 1217 | if (x86_pmu.cpu_starting) |
1214 | x86_pmu.cpu_starting(cpu); | 1218 | x86_pmu.cpu_starting(cpu); |
1215 | break; | 1219 | break; |
@@ -1319,6 +1323,8 @@ static int __init init_hw_perf_events(void) | |||
1319 | } | 1323 | } |
1320 | } | 1324 | } |
1321 | 1325 | ||
1326 | x86_pmu.attr_rdpmc = 1; /* enable userspace RDPMC usage by default */ | ||
1327 | |||
1322 | pr_info("... version: %d\n", x86_pmu.version); | 1328 | pr_info("... version: %d\n", x86_pmu.version); |
1323 | pr_info("... bit width: %d\n", x86_pmu.cntval_bits); | 1329 | pr_info("... bit width: %d\n", x86_pmu.cntval_bits); |
1324 | pr_info("... generic registers: %d\n", x86_pmu.num_counters); | 1330 | pr_info("... generic registers: %d\n", x86_pmu.num_counters); |
@@ -1542,10 +1548,71 @@ static int x86_pmu_event_init(struct perf_event *event) | |||
1542 | return err; | 1548 | return err; |
1543 | } | 1549 | } |
1544 | 1550 | ||
1551 | static int x86_pmu_event_idx(struct perf_event *event) | ||
1552 | { | ||
1553 | int idx = event->hw.idx; | ||
1554 | |||
1555 | if (x86_pmu.num_counters_fixed && idx >= X86_PMC_IDX_FIXED) { | ||
1556 | idx -= X86_PMC_IDX_FIXED; | ||
1557 | idx |= 1 << 30; | ||
1558 | } | ||
1559 | |||
1560 | return idx + 1; | ||
1561 | } | ||
1562 | |||
1563 | static ssize_t get_attr_rdpmc(struct device *cdev, | ||
1564 | struct device_attribute *attr, | ||
1565 | char *buf) | ||
1566 | { | ||
1567 | return snprintf(buf, 40, "%d\n", x86_pmu.attr_rdpmc); | ||
1568 | } | ||
1569 | |||
1570 | static void change_rdpmc(void *info) | ||
1571 | { | ||
1572 | bool enable = !!(unsigned long)info; | ||
1573 | |||
1574 | if (enable) | ||
1575 | set_in_cr4(X86_CR4_PCE); | ||
1576 | else | ||
1577 | clear_in_cr4(X86_CR4_PCE); | ||
1578 | } | ||
1579 | |||
1580 | static ssize_t set_attr_rdpmc(struct device *cdev, | ||
1581 | struct device_attribute *attr, | ||
1582 | const char *buf, size_t count) | ||
1583 | { | ||
1584 | unsigned long val = simple_strtoul(buf, NULL, 0); | ||
1585 | |||
1586 | if (!!val != !!x86_pmu.attr_rdpmc) { | ||
1587 | x86_pmu.attr_rdpmc = !!val; | ||
1588 | smp_call_function(change_rdpmc, (void *)val, 1); | ||
1589 | } | ||
1590 | |||
1591 | return count; | ||
1592 | } | ||
1593 | |||
1594 | static DEVICE_ATTR(rdpmc, S_IRUSR | S_IWUSR, get_attr_rdpmc, set_attr_rdpmc); | ||
1595 | |||
1596 | static struct attribute *x86_pmu_attrs[] = { | ||
1597 | &dev_attr_rdpmc.attr, | ||
1598 | NULL, | ||
1599 | }; | ||
1600 | |||
1601 | static struct attribute_group x86_pmu_attr_group = { | ||
1602 | .attrs = x86_pmu_attrs, | ||
1603 | }; | ||
1604 | |||
1605 | static const struct attribute_group *x86_pmu_attr_groups[] = { | ||
1606 | &x86_pmu_attr_group, | ||
1607 | NULL, | ||
1608 | }; | ||
1609 | |||
1545 | static struct pmu pmu = { | 1610 | static struct pmu pmu = { |
1546 | .pmu_enable = x86_pmu_enable, | 1611 | .pmu_enable = x86_pmu_enable, |
1547 | .pmu_disable = x86_pmu_disable, | 1612 | .pmu_disable = x86_pmu_disable, |
1548 | 1613 | ||
1614 | .attr_groups = x86_pmu_attr_groups, | ||
1615 | |||
1549 | .event_init = x86_pmu_event_init, | 1616 | .event_init = x86_pmu_event_init, |
1550 | 1617 | ||
1551 | .add = x86_pmu_add, | 1618 | .add = x86_pmu_add, |
@@ -1557,8 +1624,23 @@ static struct pmu pmu = { | |||
1557 | .start_txn = x86_pmu_start_txn, | 1624 | .start_txn = x86_pmu_start_txn, |
1558 | .cancel_txn = x86_pmu_cancel_txn, | 1625 | .cancel_txn = x86_pmu_cancel_txn, |
1559 | .commit_txn = x86_pmu_commit_txn, | 1626 | .commit_txn = x86_pmu_commit_txn, |
1627 | |||
1628 | .event_idx = x86_pmu_event_idx, | ||
1560 | }; | 1629 | }; |
1561 | 1630 | ||
1631 | void perf_update_user_clock(struct perf_event_mmap_page *userpg, u64 now) | ||
1632 | { | ||
1633 | if (!boot_cpu_has(X86_FEATURE_CONSTANT_TSC)) | ||
1634 | return; | ||
1635 | |||
1636 | if (!boot_cpu_has(X86_FEATURE_NONSTOP_TSC)) | ||
1637 | return; | ||
1638 | |||
1639 | userpg->time_mult = this_cpu_read(cyc2ns); | ||
1640 | userpg->time_shift = CYC2NS_SCALE_FACTOR; | ||
1641 | userpg->time_offset = this_cpu_read(cyc2ns_offset) - now; | ||
1642 | } | ||
1643 | |||
1562 | /* | 1644 | /* |
1563 | * callchain support | 1645 | * callchain support |
1564 | */ | 1646 | */ |
diff --git a/arch/x86/kernel/cpu/perf_event.h b/arch/x86/kernel/cpu/perf_event.h index 8944062f46e2..513d617b93c4 100644 --- a/arch/x86/kernel/cpu/perf_event.h +++ b/arch/x86/kernel/cpu/perf_event.h | |||
@@ -307,6 +307,14 @@ struct x86_pmu { | |||
307 | struct x86_pmu_quirk *quirks; | 307 | struct x86_pmu_quirk *quirks; |
308 | int perfctr_second_write; | 308 | int perfctr_second_write; |
309 | 309 | ||
310 | /* | ||
311 | * sysfs attrs | ||
312 | */ | ||
313 | int attr_rdpmc; | ||
314 | |||
315 | /* | ||
316 | * CPU Hotplug hooks | ||
317 | */ | ||
310 | int (*cpu_prepare)(int cpu); | 318 | int (*cpu_prepare)(int cpu); |
311 | void (*cpu_starting)(int cpu); | 319 | void (*cpu_starting)(int cpu); |
312 | void (*cpu_dying)(int cpu); | 320 | void (*cpu_dying)(int cpu); |