aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorAdrian Hunter <adrian.hunter@intel.com>2014-07-31 02:00:49 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2014-09-17 16:08:08 -0400
commitdc0a6202421170a6d8d2c6f5176575b3f60e0f85 (patch)
tree42ff43dac280a0b92ef7af4f65148585836e0c8c /tools
parentc501e90b4700e4f247ccdcf5ae81f9846a2ef5f9 (diff)
perf tools: Let default config be defined for a PMU
This allows default config terms to be provided for a PMU. So, for example, when the Intel PT PMU is added, it will be possible to specify: intel_pt// which will be the same as: intel_pt/tsc=1,noretcomp=0/ meaning that the trace should contain TSC timestamps and perform 'return compression'. An important consideration of this patch is that it must be possible to overwrite the default values. That has meant changing the logic so that a zero value can replace a non-zero value. Signed-off-by: Adrian Hunter <adrian.hunter@intel.com> Cc: David Ahern <dsahern@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Namhyung Kim <namhyung@gmail.com> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Stephane Eranian <eranian@google.com> Link: http://lkml.kernel.org/r/1406786474-9306-7-git-send-email-adrian.hunter@intel.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools')
-rw-r--r--tools/perf/tests/pmu.c2
-rw-r--r--tools/perf/util/parse-events.c7
-rw-r--r--tools/perf/util/pmu.c42
-rw-r--r--tools/perf/util/pmu.h9
4 files changed, 41 insertions, 19 deletions
diff --git a/tools/perf/tests/pmu.c b/tools/perf/tests/pmu.c
index 12b322fa3475..eeb68bb1972d 100644
--- a/tools/perf/tests/pmu.c
+++ b/tools/perf/tests/pmu.c
@@ -152,7 +152,7 @@ int test__pmu(void)
152 if (ret) 152 if (ret)
153 break; 153 break;
154 154
155 ret = perf_pmu__config_terms(&formats, &attr, terms); 155 ret = perf_pmu__config_terms(&formats, &attr, terms, false);
156 if (ret) 156 if (ret)
157 break; 157 break;
158 158
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index e75628813968..61be3e695ec2 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -643,7 +643,12 @@ int parse_events_add_pmu(struct list_head *list, int *idx,
643 if (!pmu) 643 if (!pmu)
644 return -EINVAL; 644 return -EINVAL;
645 645
646 memset(&attr, 0, sizeof(attr)); 646 if (pmu->default_config) {
647 memcpy(&attr, pmu->default_config,
648 sizeof(struct perf_event_attr));
649 } else {
650 memset(&attr, 0, sizeof(attr));
651 }
647 652
648 if (!head_config) { 653 if (!head_config) {
649 attr.type = pmu->type; 654 attr.type = pmu->type;
diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
index 9bf582750561..438bb261f391 100644
--- a/tools/perf/util/pmu.c
+++ b/tools/perf/util/pmu.c
@@ -2,6 +2,7 @@
2#include <sys/types.h> 2#include <sys/types.h>
3#include <unistd.h> 3#include <unistd.h>
4#include <stdio.h> 4#include <stdio.h>
5#include <stdbool.h>
5#include <dirent.h> 6#include <dirent.h>
6#include <api/fs/fs.h> 7#include <api/fs/fs.h>
7#include <locale.h> 8#include <locale.h>
@@ -387,6 +388,12 @@ static struct cpu_map *pmu_cpumask(const char *name)
387 return cpus; 388 return cpus;
388} 389}
389 390
391struct perf_event_attr *__attribute__((weak))
392perf_pmu__get_default_config(struct perf_pmu *pmu __maybe_unused)
393{
394 return NULL;
395}
396
390static struct perf_pmu *pmu_lookup(const char *name) 397static struct perf_pmu *pmu_lookup(const char *name)
391{ 398{
392 struct perf_pmu *pmu; 399 struct perf_pmu *pmu;
@@ -421,6 +428,9 @@ static struct perf_pmu *pmu_lookup(const char *name)
421 pmu->name = strdup(name); 428 pmu->name = strdup(name);
422 pmu->type = type; 429 pmu->type = type;
423 list_add_tail(&pmu->list, &pmus); 430 list_add_tail(&pmu->list, &pmus);
431
432 pmu->default_config = perf_pmu__get_default_config(pmu);
433
424 return pmu; 434 return pmu;
425} 435}
426 436
@@ -479,28 +489,24 @@ pmu_find_format(struct list_head *formats, char *name)
479} 489}
480 490
481/* 491/*
482 * Returns value based on the format definition (format parameter) 492 * Sets value based on the format definition (format parameter)
483 * and unformated value (value parameter). 493 * and unformated value (value parameter).
484 *
485 * TODO maybe optimize a little ;)
486 */ 494 */
487static __u64 pmu_format_value(unsigned long *format, __u64 value) 495static void pmu_format_value(unsigned long *format, __u64 value, __u64 *v,
496 bool zero)
488{ 497{
489 unsigned long fbit, vbit; 498 unsigned long fbit, vbit;
490 __u64 v = 0;
491 499
492 for (fbit = 0, vbit = 0; fbit < PERF_PMU_FORMAT_BITS; fbit++) { 500 for (fbit = 0, vbit = 0; fbit < PERF_PMU_FORMAT_BITS; fbit++) {
493 501
494 if (!test_bit(fbit, format)) 502 if (!test_bit(fbit, format))
495 continue; 503 continue;
496 504
497 if (!(value & (1llu << vbit++))) 505 if (value & (1llu << vbit++))
498 continue; 506 *v |= (1llu << fbit);
499 507 else if (zero)
500 v |= (1llu << fbit); 508 *v &= ~(1llu << fbit);
501 } 509 }
502
503 return v;
504} 510}
505 511
506/* 512/*
@@ -509,7 +515,8 @@ static __u64 pmu_format_value(unsigned long *format, __u64 value)
509 */ 515 */
510static int pmu_config_term(struct list_head *formats, 516static int pmu_config_term(struct list_head *formats,
511 struct perf_event_attr *attr, 517 struct perf_event_attr *attr,
512 struct parse_events_term *term) 518 struct parse_events_term *term,
519 bool zero)
513{ 520{
514 struct perf_pmu_format *format; 521 struct perf_pmu_format *format;
515 __u64 *vp; 522 __u64 *vp;
@@ -548,18 +555,19 @@ static int pmu_config_term(struct list_head *formats,
548 * non-hardcoded terms, here's the place to translate 555 * non-hardcoded terms, here's the place to translate
549 * them into value. 556 * them into value.
550 */ 557 */
551 *vp |= pmu_format_value(format->bits, term->val.num); 558 pmu_format_value(format->bits, term->val.num, vp, zero);
552 return 0; 559 return 0;
553} 560}
554 561
555int perf_pmu__config_terms(struct list_head *formats, 562int perf_pmu__config_terms(struct list_head *formats,
556 struct perf_event_attr *attr, 563 struct perf_event_attr *attr,
557 struct list_head *head_terms) 564 struct list_head *head_terms,
565 bool zero)
558{ 566{
559 struct parse_events_term *term; 567 struct parse_events_term *term;
560 568
561 list_for_each_entry(term, head_terms, list) 569 list_for_each_entry(term, head_terms, list)
562 if (pmu_config_term(formats, attr, term)) 570 if (pmu_config_term(formats, attr, term, zero))
563 return -EINVAL; 571 return -EINVAL;
564 572
565 return 0; 573 return 0;
@@ -573,8 +581,10 @@ int perf_pmu__config_terms(struct list_head *formats,
573int perf_pmu__config(struct perf_pmu *pmu, struct perf_event_attr *attr, 581int perf_pmu__config(struct perf_pmu *pmu, struct perf_event_attr *attr,
574 struct list_head *head_terms) 582 struct list_head *head_terms)
575{ 583{
584 bool zero = !!pmu->default_config;
585
576 attr->type = pmu->type; 586 attr->type = pmu->type;
577 return perf_pmu__config_terms(&pmu->format, attr, head_terms); 587 return perf_pmu__config_terms(&pmu->format, attr, head_terms, zero);
578} 588}
579 589
580static struct perf_pmu_alias *pmu_find_alias(struct perf_pmu *pmu, 590static struct perf_pmu_alias *pmu_find_alias(struct perf_pmu *pmu,
diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h
index 1c1e2eecbe1f..413b9a63c38d 100644
--- a/tools/perf/util/pmu.h
+++ b/tools/perf/util/pmu.h
@@ -13,9 +13,12 @@ enum {
13 13
14#define PERF_PMU_FORMAT_BITS 64 14#define PERF_PMU_FORMAT_BITS 64
15 15
16struct perf_event_attr;
17
16struct perf_pmu { 18struct perf_pmu {
17 char *name; 19 char *name;
18 __u32 type; 20 __u32 type;
21 struct perf_event_attr *default_config;
19 struct cpu_map *cpus; 22 struct cpu_map *cpus;
20 struct list_head format; /* HEAD struct perf_pmu_format -> list */ 23 struct list_head format; /* HEAD struct perf_pmu_format -> list */
21 struct list_head aliases; /* HEAD struct perf_pmu_alias -> list */ 24 struct list_head aliases; /* HEAD struct perf_pmu_alias -> list */
@@ -27,7 +30,8 @@ int perf_pmu__config(struct perf_pmu *pmu, struct perf_event_attr *attr,
27 struct list_head *head_terms); 30 struct list_head *head_terms);
28int perf_pmu__config_terms(struct list_head *formats, 31int perf_pmu__config_terms(struct list_head *formats,
29 struct perf_event_attr *attr, 32 struct perf_event_attr *attr,
30 struct list_head *head_terms); 33 struct list_head *head_terms,
34 bool zero);
31int perf_pmu__check_alias(struct perf_pmu *pmu, struct list_head *head_terms, 35int perf_pmu__check_alias(struct perf_pmu *pmu, struct list_head *head_terms,
32 const char **unit, double *scale); 36 const char **unit, double *scale);
33struct list_head *perf_pmu__alias(struct perf_pmu *pmu, 37struct list_head *perf_pmu__alias(struct perf_pmu *pmu,
@@ -46,4 +50,7 @@ void print_pmu_events(const char *event_glob, bool name_only);
46bool pmu_have_event(const char *pname, const char *name); 50bool pmu_have_event(const char *pname, const char *name);
47 51
48int perf_pmu__test(void); 52int perf_pmu__test(void);
53
54struct perf_event_attr *perf_pmu__get_default_config(struct perf_pmu *pmu);
55
49#endif /* __PMU_H */ 56#endif /* __PMU_H */