aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/cpu/perf_event.c
diff options
context:
space:
mode:
authorAndi Kleen <ak@linux.intel.com>2013-01-24 10:10:25 -0500
committerArnaldo Carvalho de Melo <acme@redhat.com>2013-03-26 15:50:23 -0400
commit1a6461b12872e9622c231928e1620504d741cc79 (patch)
treeebf093761ebd3a98caf71013a14601ff7b51fe1e /arch/x86/kernel/cpu/perf_event.c
parent328ccdace8855289ad114b70ee1464ba5e3f6436 (diff)
perf/x86: Support CPU specific sysfs events
Add a way for the CPU initialization code to register additional events, and merge them into the events attribute directory. Used in the next patch. Signed-off-by: Andi Kleen <ak@linux.intel.com> Signed-off-by: Stephane Eranian <eranian@google.com> Cc: peterz@infradead.org Cc: acme@redhat.com Cc: jolsa@redhat.com Cc: namhyung.kim@lge.com Link: http://lkml.kernel.org/r/1359040242-8269-2-git-send-email-eranian@google.com [ small cleanups ] Signed-off-by: Ingo Molnar <mingo@kernel.org> [ merge_attr returns a **, not just * ] Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'arch/x86/kernel/cpu/perf_event.c')
-rw-r--r--arch/x86/kernel/cpu/perf_event.c34
1 files changed, 34 insertions, 0 deletions
diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c
index bf0f01aea994..c886dc8c63f8 100644
--- a/arch/x86/kernel/cpu/perf_event.c
+++ b/arch/x86/kernel/cpu/perf_event.c
@@ -1330,6 +1330,32 @@ static void __init filter_events(struct attribute **attrs)
1330 } 1330 }
1331} 1331}
1332 1332
1333/* Merge two pointer arrays */
1334static __init struct attribute **merge_attr(struct attribute **a, struct attribute **b)
1335{
1336 struct attribute **new;
1337 int j, i;
1338
1339 for (j = 0; a[j]; j++)
1340 ;
1341 for (i = 0; b[i]; i++)
1342 j++;
1343 j++;
1344
1345 new = kmalloc(sizeof(struct attribute *) * j, GFP_KERNEL);
1346 if (!new)
1347 return NULL;
1348
1349 j = 0;
1350 for (i = 0; a[i]; i++)
1351 new[j++] = a[i];
1352 for (i = 0; b[i]; i++)
1353 new[j++] = b[i];
1354 new[j] = NULL;
1355
1356 return new;
1357}
1358
1333static ssize_t events_sysfs_show(struct device *dev, struct device_attribute *attr, 1359static ssize_t events_sysfs_show(struct device *dev, struct device_attribute *attr,
1334 char *page) 1360 char *page)
1335{ 1361{
@@ -1469,6 +1495,14 @@ static int __init init_hw_perf_events(void)
1469 else 1495 else
1470 filter_events(x86_pmu_events_group.attrs); 1496 filter_events(x86_pmu_events_group.attrs);
1471 1497
1498 if (x86_pmu.cpu_events) {
1499 struct attribute **tmp;
1500
1501 tmp = merge_attr(x86_pmu_events_group.attrs, x86_pmu.cpu_events);
1502 if (!WARN_ON(!tmp))
1503 x86_pmu_events_group.attrs = tmp;
1504 }
1505
1472 pr_info("... version: %d\n", x86_pmu.version); 1506 pr_info("... version: %d\n", x86_pmu.version);
1473 pr_info("... bit width: %d\n", x86_pmu.cntval_bits); 1507 pr_info("... bit width: %d\n", x86_pmu.cntval_bits);
1474 pr_info("... generic registers: %d\n", x86_pmu.num_counters); 1508 pr_info("... generic registers: %d\n", x86_pmu.num_counters);