From: "Yan, Zheng" <zheng.z.yan@intel.com>
To: Jiri Olsa <jolsa@redhat.com>
Cc: a.p.zijlstra@chello.nl, mingo@elte.hu, andi@firstfloor.org,
eranian@google.com, linux-kernel@vger.kernel.org,
ming.m.lin@intel.com
Subject: Re: [PATCH 4/6] perf tool: Parse general events from sysfs
Date: Wed, 25 Apr 2012 13:47:46 +0800 [thread overview]
Message-ID: <4F979002.9090906@intel.com> (raw)
In-Reply-To: <20120424090427.GA2125@m.brq.redhat.com>
On 04/24/2012 05:04 PM, Jiri Olsa wrote:
> hi,
> so the point is to have an alias support for pmu event definition.
> Seems like good idea to improve usability/readability, I have some
> general comments though..
>
Thank you very much for reviewing this.
> - you suggest to have sysfs files having contents like:
> event=0x2c,umask=0xf
> when we were adding the formats stuff into sysfs, we had to cut off
> the sysfs file contents to bare minimum to obey the sysfs rule:
> single file = single value
> so you might have some troubles pushing that through.. not sure ;)
>
> - I haven't read the whole patchset, but seems like the "events"
> directory is now specific to a 'Intel uncore pmu'. If thats the
> case I think there should be generic way for each pmu to define
> this stuff.
>
> - as for the tools/pmu.c change I'd like to see more consistent
> way of parsing this, than via 'newcfg' variable.. but none
> is comming to me so far ;) I'll think about that..
>
For this point, how about making the parser re-entrantable like the patch
attached below does.
Regards
Yan, Zheng
---
diff --git a/tools/perf/Makefile b/tools/perf/Makefile
index e98e14c..a8b47d2 100644
--- a/tools/perf/Makefile
+++ b/tools/perf/Makefile
@@ -728,11 +728,13 @@ $(OUTPUT)perf.o perf.spec \
# These two need to be here so that when O= is not used they take precedence
# over the general rule for .o
+ALL_CFLAGS_NO_WERROR = $(shell echo $(ALL_CFLAGS) | sed "s/-Werror //g")
+
$(OUTPUT)util/%-flex.o: $(OUTPUT)util/%-flex.c $(OUTPUT)PERF-CFLAGS
- $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -Iutil/ -Wno-redundant-decls -Wno-switch-default -Wno-unused-function $<
+ $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS_NO_WERROR) -Iutil/ -Wno-redundant-decls -Wno-switch-default -Wno-unused-function $<
$(OUTPUT)util/%-bison.o: $(OUTPUT)util/%-bison.c $(OUTPUT)PERF-CFLAGS
- $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -DYYENABLE_NLS=0 -DYYLTYPE_IS_TRIVIAL=0 -Iutil/ -Wno-redundant-decls -Wno-switch-default -Wno-unused-function $<
+ $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS_NO_WERROR) -DYYENABLE_NLS=0 -DYYLTYPE_IS_TRIVIAL=0 -Iutil/ -Wno-redundant-decls -Wno-switch-default -Wno-unused-function $<
$(OUTPUT)%.o: %.c $(OUTPUT)PERF-CFLAGS
$(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) $<
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index 5b3a0ef..b776c2e 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -11,6 +11,7 @@
#include "cache.h"
#include "header.h"
#include "debugfs.h"
+#include "parse-events-bison.h"
#include "parse-events-flex.h"
#include "pmu.h"
@@ -24,7 +25,8 @@ struct event_symbol {
};
int parse_events_parse(struct list_head *list, struct list_head *list_tmp,
- int *idx);
+ int *idx, void *scanner);
+static int __parse_events(const char *str, int *idx, struct list_head *list);
#define CHW(x) .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_##x
#define CSW(x) .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_##x
@@ -651,8 +653,11 @@ int parse_events_add_numeric(struct list_head *list, int *idx,
int parse_events_add_pmu(struct list_head *list, int *idx,
char *name, struct list_head *head_config)
{
+ LIST_HEAD(event);
struct perf_event_attr attr;
struct perf_pmu *pmu;
+ char *config;
+ int ret;
pmu = perf_pmu__find(name);
if (!pmu)
@@ -666,10 +671,21 @@ int parse_events_add_pmu(struct list_head *list, int *idx,
*/
config_attr(&attr, head_config, 0);
- if (perf_pmu__config(pmu, &attr, head_config))
- return -EINVAL;
+ ret = perf_pmu__config(pmu, &attr, head_config);
+ if (!ret)
+ return add_event(list, idx, &attr, (char *) "pmu");
+
+ ret = perf_pmu__alias(pmu, &config, head_config);
+ if (ret)
+ return ret;
+
+ ret = __parse_events(config, idx, &event);
+ free(config);
+ if (ret)
+ return ret;
- return add_event(list, idx, &attr, (char *) "pmu");
+ list_splice_tail(&event, list);
+ return 0;
}
void parse_events_update_lists(struct list_head *list_event,
@@ -747,20 +763,34 @@ int parse_events_modifier(struct list_head *list, char *str)
return 0;
}
-int parse_events(struct perf_evlist *evlist, const char *str, int unset __used)
+static int __parse_events(const char *str, int *idx, struct list_head *list)
{
- LIST_HEAD(list);
LIST_HEAD(list_tmp);
YY_BUFFER_STATE buffer;
- int ret, idx = evlist->nr_entries;
+ void *scanner;
+ int ret;
+
+ ret = parse_events_lex_init(&scanner);
+ if (ret)
+ return ret;
+
+ buffer = parse_events__scan_string(str, scanner);
+
+ ret = parse_events_parse(list, &list_tmp, idx, scanner);
- buffer = parse_events__scan_string(str);
+ parse_events__flush_buffer(buffer, scanner);
+ parse_events__delete_buffer(buffer, scanner);
+ parse_events_lex_destroy(scanner);
- ret = parse_events_parse(&list, &list_tmp, &idx);
+ return ret;
+}
- parse_events__flush_buffer(buffer);
- parse_events__delete_buffer(buffer);
+int parse_events(struct perf_evlist *evlist, const char *str, int unset __used)
+{
+ LIST_HEAD(list);
+ int ret, idx = evlist->nr_entries;
+ ret = __parse_events(str, &idx, &list);
if (!ret) {
int entries = idx - evlist->nr_entries;
perf_evlist__splice_list_tail(evlist, &list, entries);
diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h
index ca069f8..e1ffeb7 100644
--- a/tools/perf/util/parse-events.h
+++ b/tools/perf/util/parse-events.h
@@ -80,7 +80,7 @@ void parse_events_update_lists(struct list_head *list_event,
struct list_head *list_all);
void parse_events_error(struct list_head *list_all,
struct list_head *list_event,
- int *idx, char const *msg);
+ int *idx, void *scanner, char const *msg);
void print_events(const char *event_glob);
void print_events_type(u8 type);
diff --git a/tools/perf/util/parse-events.l b/tools/perf/util/parse-events.l
index 05d766e..72066d2 100644
--- a/tools/perf/util/parse-events.l
+++ b/tools/perf/util/parse-events.l
@@ -1,4 +1,6 @@
+%option reentrant
+%option bison-bridge
%option prefix="parse_events_"
%{
@@ -7,7 +9,7 @@
#include "parse-events-bison.h"
#include "parse-events.h"
-static int __value(char *str, int base, int token)
+static int __value(YYSTYPE *yylval, char *str, int base, int token)
{
long num;
@@ -16,35 +18,35 @@ static int __value(char *str, int base, int token)
if (errno)
return PE_ERROR;
- parse_events_lval.num = num;
+ yylval->num = num;
return token;
}
-static int value(int base)
+static int value(YYSTYPE *yylval, char *text, int base)
{
- return __value(parse_events_text, base, PE_VALUE);
+ return __value(yylval, text, base, PE_VALUE);
}
-static int raw(void)
+static int raw(YYSTYPE *yylval, char *text)
{
- return __value(parse_events_text + 1, 16, PE_RAW);
+ return __value(yylval, text + 1, 16, PE_RAW);
}
-static int str(int token)
+static int str(YYSTYPE *yylval, char *text, int token)
{
- parse_events_lval.str = strdup(parse_events_text);
+ yylval->str = strdup(text);
return token;
}
-static int sym(int type, int config)
+static int sym(YYSTYPE *yylval, int type, int config)
{
- parse_events_lval.num = (type << 16) + config;
+ yylval->num = (type << 16) + config;
return PE_VALUE_SYM;
}
-static int term(int type)
+static int term(YYSTYPE *yylval, int type)
{
- parse_events_lval.num = type;
+ yylval->num = type;
return PE_TERM;
}
@@ -58,25 +60,25 @@ modifier_event [ukhp]{1,5}
modifier_bp [rwx]
%%
-cpu-cycles|cycles { return sym(PERF_TYPE_HARDWARE, PERF_COUNT_HW_CPU_CYCLES); }
-stalled-cycles-frontend|idle-cycles-frontend { return sym(PERF_TYPE_HARDWARE, PERF_COUNT_HW_STALLED_CYCLES_FRONTEND); }
-stalled-cycles-backend|idle-cycles-backend { return sym(PERF_TYPE_HARDWARE, PERF_COUNT_HW_STALLED_CYCLES_BACKEND); }
-instructions { return sym(PERF_TYPE_HARDWARE, PERF_COUNT_HW_INSTRUCTIONS); }
-cache-references { return sym(PERF_TYPE_HARDWARE, PERF_COUNT_HW_CACHE_REFERENCES); }
-cache-misses { return sym(PERF_TYPE_HARDWARE, PERF_COUNT_HW_CACHE_MISSES); }
-branch-instructions|branches { return sym(PERF_TYPE_HARDWARE, PERF_COUNT_HW_BRANCH_INSTRUCTIONS); }
-branch-misses { return sym(PERF_TYPE_HARDWARE, PERF_COUNT_HW_BRANCH_MISSES); }
-bus-cycles { return sym(PERF_TYPE_HARDWARE, PERF_COUNT_HW_BUS_CYCLES); }
-ref-cycles { return sym(PERF_TYPE_HARDWARE, PERF_COUNT_HW_REF_CPU_CYCLES); }
-cpu-clock { return sym(PERF_TYPE_SOFTWARE, PERF_COUNT_SW_CPU_CLOCK); }
-task-clock { return sym(PERF_TYPE_SOFTWARE, PERF_COUNT_SW_TASK_CLOCK); }
-page-faults|faults { return sym(PERF_TYPE_SOFTWARE, PERF_COUNT_SW_PAGE_FAULTS); }
-minor-faults { return sym(PERF_TYPE_SOFTWARE, PERF_COUNT_SW_PAGE_FAULTS_MIN); }
-major-faults { return sym(PERF_TYPE_SOFTWARE, PERF_COUNT_SW_PAGE_FAULTS_MAJ); }
-context-switches|cs { return sym(PERF_TYPE_SOFTWARE, PERF_COUNT_SW_CONTEXT_SWITCHES); }
-cpu-migrations|migrations { return sym(PERF_TYPE_SOFTWARE, PERF_COUNT_SW_CPU_MIGRATIONS); }
-alignment-faults { return sym(PERF_TYPE_SOFTWARE, PERF_COUNT_SW_ALIGNMENT_FAULTS); }
-emulation-faults { return sym(PERF_TYPE_SOFTWARE, PERF_COUNT_SW_EMULATION_FAULTS); }
+cpu-cycles|cycles { return sym(yylval, PERF_TYPE_HARDWARE, PERF_COUNT_HW_CPU_CYCLES); }
+stalled-cycles-frontend|idle-cycles-frontend { return sym(yylval, PERF_TYPE_HARDWARE, PERF_COUNT_HW_STALLED_CYCLES_FRONTEND); }
+stalled-cycles-backend|idle-cycles-backend { return sym(yylval, PERF_TYPE_HARDWARE, PERF_COUNT_HW_STALLED_CYCLES_BACKEND); }
+instructions { return sym(yylval, PERF_TYPE_HARDWARE, PERF_COUNT_HW_INSTRUCTIONS); }
+cache-references { return sym(yylval, PERF_TYPE_HARDWARE, PERF_COUNT_HW_CACHE_REFERENCES); }
+cache-misses { return sym(yylval, PERF_TYPE_HARDWARE, PERF_COUNT_HW_CACHE_MISSES); }
+branch-instructions|branches { return sym(yylval, PERF_TYPE_HARDWARE, PERF_COUNT_HW_BRANCH_INSTRUCTIONS); }
+branch-misses { return sym(yylval, PERF_TYPE_HARDWARE, PERF_COUNT_HW_BRANCH_MISSES); }
+bus-cycles { return sym(yylval, PERF_TYPE_HARDWARE, PERF_COUNT_HW_BUS_CYCLES); }
+ref-cycles { return sym(yylval, PERF_TYPE_HARDWARE, PERF_COUNT_HW_REF_CPU_CYCLES); }
+cpu-clock { return sym(yylval, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_CPU_CLOCK); }
+task-clock { return sym(yylval, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_TASK_CLOCK); }
+page-faults|faults { return sym(yylval, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_PAGE_FAULTS); }
+minor-faults { return sym(yylval, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_PAGE_FAULTS_MIN); }
+major-faults { return sym(yylval, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_PAGE_FAULTS_MAJ); }
+context-switches|cs { return sym(yylval, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_CONTEXT_SWITCHES); }
+cpu-migrations|migrations { return sym(yylval, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_CPU_MIGRATIONS); }
+alignment-faults { return sym(yylval, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_ALIGNMENT_FAULTS); }
+emulation-faults { return sym(yylval, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_EMULATION_FAULTS); }
L1-dcache|l1-d|l1d|L1-data |
L1-icache|l1-i|l1i|L1-instruction |
@@ -84,14 +86,14 @@ LLC|L2 |
dTLB|d-tlb|Data-TLB |
iTLB|i-tlb|Instruction-TLB |
branch|branches|bpu|btb|bpc |
-node { return str(PE_NAME_CACHE_TYPE); }
+node { return str(yylval, yytext, PE_NAME_CACHE_TYPE); }
load|loads|read |
store|stores|write |
prefetch|prefetches |
speculative-read|speculative-load |
refs|Reference|ops|access |
-misses|miss { return str(PE_NAME_CACHE_OP_RESULT); }
+misses|miss { return str(yylval, yytext, PE_NAME_CACHE_OP_RESULT); }
/*
* These are event config hardcoded term names to be specified
@@ -99,20 +101,20 @@ misses|miss { return str(PE_NAME_CACHE_OP_RESULT); }
* so we can put them here directly. In case the we have a conflict
* in future, this needs to go into '//' condition block.
*/
-config { return term(PARSE_EVENTS__TERM_TYPE_CONFIG); }
-config1 { return term(PARSE_EVENTS__TERM_TYPE_CONFIG1); }
-config2 { return term(PARSE_EVENTS__TERM_TYPE_CONFIG2); }
-period { return term(PARSE_EVENTS__TERM_TYPE_SAMPLE_PERIOD); }
-branch_type { return term(PARSE_EVENTS__TERM_TYPE_BRANCH_SAMPLE_TYPE); }
+config { return term(yylval, PARSE_EVENTS__TERM_TYPE_CONFIG); }
+config1 { return term(yylval, PARSE_EVENTS__TERM_TYPE_CONFIG1); }
+config2 { return term(yylval, PARSE_EVENTS__TERM_TYPE_CONFIG2); }
+period { return term(yylval, PARSE_EVENTS__TERM_TYPE_SAMPLE_PERIOD); }
+branch_type { return term(yylval, PARSE_EVENTS__TERM_TYPE_BRANCH_SAMPLE_TYPE); }
mem: { return PE_PREFIX_MEM; }
-r{num_raw_hex} { return raw(); }
-{num_dec} { return value(10); }
-{num_hex} { return value(16); }
+r{num_raw_hex} { return raw(yylval, yytext); }
+{num_dec} { return value(yylval, yytext, 10); }
+{num_hex} { return value(yylval, yytext, 16); }
-{modifier_event} { return str(PE_MODIFIER_EVENT); }
-{modifier_bp} { return str(PE_MODIFIER_BP); }
-{name} { return str(PE_NAME); }
+{modifier_event} { return str(yylval, yytext, PE_MODIFIER_EVENT); }
+{modifier_bp} { return str(yylval, yytext, PE_MODIFIER_BP); }
+{name} { return str(yylval, yytext, PE_NAME); }
"/" { return '/'; }
- { return '-'; }
, { return ','; }
@@ -121,7 +123,7 @@ r{num_raw_hex} { return raw(); }
%%
-int parse_events_wrap(void)
+int parse_events_wrap(void *scanner __used)
{
return 1;
}
diff --git a/tools/perf/util/parse-events.y b/tools/perf/util/parse-events.y
index d9637da..8a26f3d 100644
--- a/tools/perf/util/parse-events.y
+++ b/tools/perf/util/parse-events.y
@@ -1,8 +1,10 @@
-
+%pure-parser
%name-prefix "parse_events_"
%parse-param {struct list_head *list_all}
%parse-param {struct list_head *list_event}
%parse-param {int *idx}
+%parse-param {void *scanner}
+%lex-param {void* scanner}
%{
@@ -13,8 +15,9 @@
#include "types.h"
#include "util.h"
#include "parse-events.h"
+#include "parse-events-bison.h"
-extern int parse_events_lex (void);
+extern int parse_events_lex (YYSTYPE* lvalp, void* scanner);
#define ABORT_ON(val) \
do { \
@@ -194,7 +197,7 @@ PE_NAME
{
struct parse_events__term *term;
- ABORT_ON(parse_events__new_term(&term, PARSE_EVENTS__TERM_TYPE_NUM,
+ ABORT_ON(parse_events__new_term(&term, PARSE_EVENTS__TERM_TYPE_STR,
$1, NULL, 1));
$$ = term;
}
@@ -223,7 +226,7 @@ sep_slash_dc: '/' | ':' |
void parse_events_error(struct list_head *list_all __used,
struct list_head *list_event __used,
- int *idx __used,
+ int *idx __used, void *scanner __used,
char const *msg __used)
{
}
diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
index cb08a11..3daf828 100644
--- a/tools/perf/util/pmu.c
+++ b/tools/perf/util/pmu.c
@@ -80,6 +80,89 @@ static int pmu_format(char *name, struct list_head *format)
return 0;
}
+static int perf_pmu__new_event(struct list_head *list, char *name, FILE *file)
+{
+ struct perf_pmu__event *event;
+ char buf[256];
+ int ret;
+
+ ret = fread(buf, 1, sizeof(buf), file);
+ if (ret == 0)
+ return -EINVAL;
+
+ event = zalloc(sizeof(*event));
+ if (!event)
+ return -ENOMEM;
+
+ event->name = strdup(name);
+ event->config = strndup(buf, ret);
+
+ list_add_tail(&event->list, list);
+ return 0;
+}
+
+/*
+ * Process all the sysfs attributes located under the directory
+ * specified in 'dir' parameter.
+ */
+static int pmu_events_parse(char *dir, struct list_head *head)
+{
+ struct dirent *evt_ent;
+ DIR *event_dir;
+ int ret = 0;
+
+ event_dir = opendir(dir);
+ if (!event_dir)
+ return -EINVAL;
+
+ while (!ret && (evt_ent = readdir(event_dir))) {
+ char path[PATH_MAX];
+ char *name = evt_ent->d_name;
+ FILE *file;
+
+ if (!strcmp(name, ".") || !strcmp(name, ".."))
+ continue;
+
+ snprintf(path, PATH_MAX, "%s/%s", dir, name);
+
+ ret = -EINVAL;
+ file = fopen(path, "r");
+ if (!file)
+ break;
+ ret = perf_pmu__new_event(head, name, file);
+ fclose(file);
+ }
+
+ closedir(event_dir);
+ return ret;
+}
+
+/*
+ * Reading the pmu event definition, which should be located at:
+ * /sys/bus/event_source/devices/<dev>/events as sysfs group attributes.
+ */
+static int pmu_events(char *name, struct list_head *events)
+{
+ struct stat st;
+ char path[PATH_MAX];
+ const char *sysfs;
+
+ sysfs = sysfs_find_mountpoint();
+ if (!sysfs)
+ return -1;
+
+ snprintf(path, PATH_MAX,
+ "%s/bus/event_source/devices/%s/events", sysfs, name);
+
+ if (stat(path, &st) < 0)
+ return -1;
+
+ if (pmu_events_parse(path, events))
+ return -1;
+
+ return 0;
+}
+
/*
* Reading/parsing the default pmu type value, which should be
* located at:
@@ -118,6 +201,7 @@ static struct perf_pmu *pmu_lookup(char *name)
{
struct perf_pmu *pmu;
LIST_HEAD(format);
+ LIST_HEAD(events);
__u32 type;
/*
@@ -135,8 +219,12 @@ static struct perf_pmu *pmu_lookup(char *name)
if (!pmu)
return NULL;
+ pmu_events(name, &events);
+
INIT_LIST_HEAD(&pmu->format);
+ INIT_LIST_HEAD(&pmu->events);
list_splice(&format, &pmu->format);
+ list_splice(&events, &pmu->events);
pmu->name = strdup(name);
pmu->type = type;
return pmu;
@@ -262,6 +350,47 @@ static int pmu_config(struct list_head *formats, struct perf_event_attr *attr,
return 0;
}
+
+static struct perf_pmu__event*
+pmu_find_event(struct list_head *events, char *name)
+{
+ struct perf_pmu__event *event;
+
+ list_for_each_entry(event, events, list)
+ if (!strcmp(event->name, name))
+ return event;
+
+ return NULL;
+}
+
+static int pmu_event(struct perf_pmu *pmu, struct list_head *head_terms,
+ char **config)
+{
+ struct parse_events__term *term;
+ struct perf_pmu__event *event;
+ char *buf;
+
+ if (!list_is_singular(head_terms))
+ return -EINVAL;
+
+ term = list_entry(head_terms->next, struct parse_events__term, list);
+
+ if (term->type != PARSE_EVENTS__TERM_TYPE_STR || term->val.str)
+ return -EINVAL;
+
+ event = pmu_find_event(&pmu->events, term->config);
+ if (!event)
+ return -EINVAL;
+
+ buf = malloc(strlen(pmu->name) + strlen(event->config) + 3);
+ if (!buf)
+ return -ENOMEM;
+
+ sprintf(buf, "%s/%s/", pmu->name, event->config);
+ *config = buf;
+ return 0;
+}
+
/*
* Configures event's 'attr' parameter based on the:
* 1) users input - specified in terms parameter
@@ -274,6 +403,12 @@ int perf_pmu__config(struct perf_pmu *pmu, struct perf_event_attr *attr,
return pmu_config(&pmu->format, attr, head_terms);
}
+int perf_pmu__alias(struct perf_pmu *pmu, char **config,
+ struct list_head *head_terms)
+{
+ return pmu_event(pmu, head_terms, config);
+}
+
int perf_pmu__new_format(struct list_head *list, char *name,
int config, unsigned long *bits)
{
diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h
index 68c0db9..3656b42 100644
--- a/tools/perf/util/pmu.h
+++ b/tools/perf/util/pmu.h
@@ -19,16 +19,25 @@ struct perf_pmu__format {
struct list_head list;
};
+struct perf_pmu__event {
+ char *name;
+ char *config;
+ struct list_head list;
+};
+
struct perf_pmu {
char *name;
__u32 type;
struct list_head format;
+ struct list_head events;
struct list_head list;
};
struct perf_pmu *perf_pmu__find(char *name);
int perf_pmu__config(struct perf_pmu *pmu, struct perf_event_attr *attr,
struct list_head *head_terms);
+int perf_pmu__alias(struct perf_pmu *pmu, char **config,
+ struct list_head *head_terms);
int perf_pmu_wrap(void);
void perf_pmu_error(struct list_head *list, char *name, char const *msg);
next prev parent reply other threads:[~2012-04-25 5:47 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-04-01 1:41 [RFC PATCH V2 0/6] perf: Intel uncore pmu counting support Yan, Zheng
2012-04-01 1:41 ` [PATCH 1/6] perf: Export perf_assign_events Yan, Zheng
2012-04-01 1:41 ` [PATCH 2/6] perf: Generic intel uncore support Yan, Zheng
2012-04-01 1:41 ` [PATCH 3/6] perf: Add Nehalem and Sandy Bridge " Yan, Zheng
2012-04-01 1:41 ` [PATCH 4/6] perf tool: Parse general events from sysfs Yan, Zheng
2012-04-24 9:04 ` Jiri Olsa
2012-04-25 5:47 ` Yan, Zheng [this message]
2012-04-25 13:01 ` Jiri Olsa
2012-04-01 1:41 ` [PATCH 5/6] perf: Generic pci uncore device support Yan, Zheng
2012-04-01 1:41 ` [PATCH 6/6] perf: Add Sandy Bridge-EP uncore support Yan, Zheng
2012-04-23 15:21 ` [RFC PATCH V2 0/6] perf: Intel uncore pmu counting support Stephane Eranian
2012-04-24 8:56 ` Yan, Zheng
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4F979002.9090906@intel.com \
--to=zheng.z.yan@intel.com \
--cc=a.p.zijlstra@chello.nl \
--cc=andi@firstfloor.org \
--cc=eranian@google.com \
--cc=jolsa@redhat.com \
--cc=linux-kernel@vger.kernel.org \
--cc=ming.m.lin@intel.com \
--cc=mingo@elte.hu \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.