aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/cpu/perf_event.c
diff options
context:
space:
mode:
authorPeter Zijlstra <a.p.zijlstra@chello.nl>2011-11-20 17:30:47 -0500
committerIngo Molnar <mingo@elte.hu>2011-12-21 05:01:11 -0500
commit0c9d42ed4cee2aa1dfc3a260b741baae8615744f (patch)
tree393a3a3d0be5cbd57e1d03490b3f6a5a15d5367d /arch/x86/kernel/cpu/perf_event.c
parentfe4a330885aee20f233de36085fb15c38094e635 (diff)
perf, x86: Provide means for disabling userspace RDPMC
Allow the disabling of RDPMC via a pmu specific attribute: echo 0 > /sys/bus/event_source/devices/cpu/rdpmc Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Stephane Eranian <eranian@google.com> Cc: Arun Sharma <asharma@fb.com> Link: http://lkml.kernel.org/n/tip-pqeog465zo5hsimtkfz73f27@git.kernel.org Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/kernel/cpu/perf_event.c')
-rw-r--r--arch/x86/kernel/cpu/perf_event.c55
1 files changed, 54 insertions, 1 deletions
diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c
index 53b569910175..116b040a73a8 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>
@@ -1210,7 +1211,8 @@ x86_pmu_notifier(struct notifier_block *self, unsigned long action, void *hcpu)
1210 break; 1211 break;
1211 1212
1212 case CPU_STARTING: 1213 case CPU_STARTING:
1213 set_in_cr4(X86_CR4_PCE); 1214 if (x86_pmu.attr_rdpmc)
1215 set_in_cr4(X86_CR4_PCE);
1214 if (x86_pmu.cpu_starting) 1216 if (x86_pmu.cpu_starting)
1215 x86_pmu.cpu_starting(cpu); 1217 x86_pmu.cpu_starting(cpu);
1216 break; 1218 break;
@@ -1320,6 +1322,8 @@ static int __init init_hw_perf_events(void)
1320 } 1322 }
1321 } 1323 }
1322 1324
1325 x86_pmu.attr_rdpmc = 1; /* enable userspace RDPMC usage by default */
1326
1323 pr_info("... version: %d\n", x86_pmu.version); 1327 pr_info("... version: %d\n", x86_pmu.version);
1324 pr_info("... bit width: %d\n", x86_pmu.cntval_bits); 1328 pr_info("... bit width: %d\n", x86_pmu.cntval_bits);
1325 pr_info("... generic registers: %d\n", x86_pmu.num_counters); 1329 pr_info("... generic registers: %d\n", x86_pmu.num_counters);
@@ -1555,10 +1559,59 @@ static int x86_pmu_event_idx(struct perf_event *event)
1555 return idx + 1; 1559 return idx + 1;
1556} 1560}
1557 1561
1562static ssize_t get_attr_rdpmc(struct device *cdev,
1563 struct device_attribute *attr,
1564 char *buf)
1565{
1566 return snprintf(buf, 40, "%d\n", x86_pmu.attr_rdpmc);
1567}
1568
1569static void change_rdpmc(void *info)
1570{
1571 bool enable = !!(unsigned long)info;
1572
1573 if (enable)
1574 set_in_cr4(X86_CR4_PCE);
1575 else
1576 clear_in_cr4(X86_CR4_PCE);
1577}
1578
1579static ssize_t set_attr_rdpmc(struct device *cdev,
1580 struct device_attribute *attr,
1581 const char *buf, size_t count)
1582{
1583 unsigned long val = simple_strtoul(buf, NULL, 0);
1584
1585 if (!!val != !!x86_pmu.attr_rdpmc) {
1586 x86_pmu.attr_rdpmc = !!val;
1587 smp_call_function(change_rdpmc, (void *)val, 1);
1588 }
1589
1590 return count;
1591}
1592
1593static DEVICE_ATTR(rdpmc, S_IRUSR | S_IWUSR, get_attr_rdpmc, set_attr_rdpmc);
1594
1595static struct attribute *x86_pmu_attrs[] = {
1596 &dev_attr_rdpmc.attr,
1597 NULL,
1598};
1599
1600static struct attribute_group x86_pmu_attr_group = {
1601 .attrs = x86_pmu_attrs,
1602};
1603
1604static const struct attribute_group *x86_pmu_attr_groups[] = {
1605 &x86_pmu_attr_group,
1606 NULL,
1607};
1608
1558static struct pmu pmu = { 1609static struct pmu pmu = {
1559 .pmu_enable = x86_pmu_enable, 1610 .pmu_enable = x86_pmu_enable,
1560 .pmu_disable = x86_pmu_disable, 1611 .pmu_disable = x86_pmu_disable,
1561 1612
1613 .attr_groups = x86_pmu_attr_groups,
1614
1562 .event_init = x86_pmu_event_init, 1615 .event_init = x86_pmu_event_init,
1563 1616
1564 .add = x86_pmu_add, 1617 .add = x86_pmu_add,