All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH V5 1/3] Revert "perf tools: Default to cpu// for events v5"
@ 2014-09-10 17:55 kan.liang
  2014-09-10 17:55 ` [PATCH V5 2/3] perf tools: parse the pmu event prefix and surfix kan.liang
  2014-09-10 17:55 ` [PATCH V5 3/3] perf tools: Add support to new style format of kernel PMU event kan.liang
  0 siblings, 2 replies; 9+ messages in thread
From: kan.liang @ 2014-09-10 17:55 UTC (permalink / raw)
  To: acme, jolsa; +Cc: linux-kernel, ak, Kan Liang

From: Kan Liang <kan.liang@intel.com>

This reverts commit 50e200f07948 ("perf tools: Default to cpu// for
events v5")

The fixup cannot handle the case that
new style format(which without //) mixed with
other different formats.

For example,
group events with new style format: {mem-stores,mem-loads}
some hardware event + new style event: cycles,mem-loads
Cache event + new style event: LLC-loads,mem-loads
Raw event + new style event:
cpu/event=0xc8,umask=0x08/,mem-loads
old style event and new stytle mixture: mem-stores,cpu/mem-loads/

Signed-off-by: Kan Liang <kan.liang@intel.com>
---
 tools/perf/util/include/linux/string.h |  1 -
 tools/perf/util/parse-events.c         | 30 +-----------------------------
 tools/perf/util/string.c               | 24 ------------------------
 3 files changed, 1 insertion(+), 54 deletions(-)

diff --git a/tools/perf/util/include/linux/string.h b/tools/perf/util/include/linux/string.h
index 97a8007..6f19c54 100644
--- a/tools/perf/util/include/linux/string.h
+++ b/tools/perf/util/include/linux/string.h
@@ -1,4 +1,3 @@
 #include <string.h>
 
 void *memdup(const void *src, size_t len);
-int str_append(char **s, int *len, const char *a);
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index 61be3e6..b9174bc 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -6,7 +6,7 @@
 #include "parse-options.h"
 #include "parse-events.h"
 #include "exec_cmd.h"
-#include "linux/string.h"
+#include "string.h"
 #include "symbol.h"
 #include "cache.h"
 #include "header.h"
@@ -864,32 +864,6 @@ int parse_events_name(struct list_head *list, char *name)
 	return 0;
 }
 
-static int parse_events__scanner(const char *str, void *data, int start_token);
-
-static int parse_events_fixup(int ret, const char *str, void *data,
-			      int start_token)
-{
-	char *o = strdup(str);
-	char *s = NULL;
-	char *t = o;
-	char *p;
-	int len = 0;
-
-	if (!o)
-		return ret;
-	while ((p = strsep(&t, ",")) != NULL) {
-		if (s)
-			str_append(&s, &len, ",");
-		str_append(&s, &len, "cpu/");
-		str_append(&s, &len, p);
-		str_append(&s, &len, "/");
-	}
-	free(o);
-	if (!s)
-		return -ENOMEM;
-	return parse_events__scanner(s, data, start_token);
-}
-
 static int parse_events__scanner(const char *str, void *data, int start_token)
 {
 	YY_BUFFER_STATE buffer;
@@ -910,8 +884,6 @@ static int parse_events__scanner(const char *str, void *data, int start_token)
 	parse_events__flush_buffer(buffer, scanner);
 	parse_events__delete_buffer(buffer, scanner);
 	parse_events_lex_destroy(scanner);
-	if (ret && !strchr(str, '/'))
-		ret = parse_events_fixup(ret, str, data, start_token);
 	return ret;
 }
 
diff --git a/tools/perf/util/string.c b/tools/perf/util/string.c
index 2553e5b..4b0ff22 100644
--- a/tools/perf/util/string.c
+++ b/tools/perf/util/string.c
@@ -387,27 +387,3 @@ void *memdup(const void *src, size_t len)
 
 	return p;
 }
-
-/**
- * str_append - reallocate string and append another
- * @s: pointer to string pointer
- * @len: pointer to len (initialized)
- * @a: string to append.
- */
-int str_append(char **s, int *len, const char *a)
-{
-	int olen = *s ? strlen(*s) : 0;
-	int nlen = olen + strlen(a) + 1;
-	if (*len < nlen) {
-		*len = *len * 2;
-		if (*len < nlen)
-			*len = nlen;
-		*s = realloc(*s, *len);
-		if (!*s)
-			return -ENOMEM;
-		if (olen == 0)
-			**s = 0;
-	}
-	strcat(*s, a);
-	return 0;
-}
-- 
1.8.3.2


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH V5 2/3] perf tools: parse the pmu event prefix and surfix
  2014-09-10 17:55 [PATCH V5 1/3] Revert "perf tools: Default to cpu// for events v5" kan.liang
@ 2014-09-10 17:55 ` kan.liang
  2014-09-11  8:46   ` Jiri Olsa
  2014-09-11  8:51   ` Jiri Olsa
  2014-09-10 17:55 ` [PATCH V5 3/3] perf tools: Add support to new style format of kernel PMU event kan.liang
  1 sibling, 2 replies; 9+ messages in thread
From: kan.liang @ 2014-09-10 17:55 UTC (permalink / raw)
  To: acme, jolsa; +Cc: linux-kernel, ak, Kan Liang

From: Kan Liang <kan.liang@intel.com>

There are two types of event formats for PMU events. E.g. el-abort OR
cpu/el-abort/. However, the lexer mistakenly recognizes the simple style
format as two events.

The parse_events_pmu_check function uses bsearch to search the name in
known pmu event list. It can tell the lexer that the name is a PE_NAME
or a PMU event name prefix or a PMU event name suffix. All these
information will be used for accurately parsing kernel PMU events.

The pmu events list will be read from sysfs at runtime.

Note: Currently, the patch only want to handle the PMU event name as
"a-b" and "a". The only exception, "stalled-cycles-frontend" and
"stalled-cycles-fronted" are already hardcoded in lexer.

Signed-off-by: Kan Liang <kan.liang@intel.com>
---

v2: Read kernel PMU events from sysfs at runtime
v3: Use strlcpy to replace strncpyv2: Read kernel PMU events from sysfs at
runtime
v4: rebase to git.kernel.org/pub/scm/linux/kernel/git/acme/linux perf/core
v5: scan kernel pmu events from sysfs only needed
    rename the init/check/clenup functions and related struct.
    allocate each symbol string separatelly

 tools/perf/util/parse-events.c | 118 +++++++++++++++++++++++++++++++++++++++++
 tools/perf/util/parse-events.h |  14 +++++
 tools/perf/util/pmu.c          |  10 ----
 tools/perf/util/pmu.h          |  10 ++++
 4 files changed, 142 insertions(+), 10 deletions(-)

diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index b9174bc..9a50a8d 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -30,6 +30,9 @@ extern int parse_events_debug;
 #endif
 int parse_events_parse(void *data, void *scanner);
 
+static struct perf_pmu_event_symbol *perf_pmu_events_list;
+static size_t perf_pmu_events_list_num;
+
 static struct event_symbol event_symbols_hw[PERF_COUNT_HW_MAX] = {
 	[PERF_COUNT_HW_CPU_CYCLES] = {
 		.symbol = "cpu-cycles",
@@ -864,6 +867,120 @@ int parse_events_name(struct list_head *list, char *name)
 	return 0;
 }
 
+static int
+comp_pmu(const void *p1, const void *p2)
+{
+	struct perf_pmu_event_symbol *pmu1 =
+			(struct perf_pmu_event_symbol *) p1;
+	struct perf_pmu_event_symbol *pmu2 =
+			(struct perf_pmu_event_symbol *) p2;
+
+	return strcmp(pmu1->symbol, pmu2->symbol);
+}
+
+/*
+ * Read the pmu events list from sysfs
+ * Save it into perf_pmu_events_list
+ */
+static void perf_pmu__parse_init(void)
+{
+
+	struct perf_pmu *pmu = NULL;
+	struct perf_pmu_alias *alias;
+	int len = 0;
+
+	while ((pmu = perf_pmu__scan(pmu)) != NULL)
+		list_for_each_entry(alias, &pmu->aliases, list) {
+			if (!strcmp(pmu->name, "cpu")) {
+				if (strchr(alias->name, '-'))
+					len++;
+				len++;
+			}
+	}
+	if (len == 0)
+		return;
+	perf_pmu_events_list =
+		malloc(sizeof(struct perf_pmu_event_symbol) * len);
+	perf_pmu_events_list_num = len;
+
+	pmu = NULL;
+	len = 0;
+	while ((pmu = perf_pmu__scan(pmu)) != NULL)
+		list_for_each_entry(alias, &pmu->aliases, list) {
+			if (!strcmp(pmu->name, "cpu")) {
+				struct perf_pmu_event_symbol *p =
+					perf_pmu_events_list + len;
+				char *tmp = strchr(alias->name, '-');
+
+				if (tmp != NULL) {
+					p->symbol =
+						malloc(tmp - alias->name + 1);
+					strlcpy(p->symbol, alias->name,
+						tmp - alias->name + 1);
+					p->type = KERNEL_PMU_EVENT_PREFIX;
+					tmp++;
+					p++;
+					p->symbol = malloc(strlen(tmp) + 1);
+					strcpy(p->symbol, tmp);
+					p->type = KERNEL_PMU_EVENT_SUFFIX;
+					len += 2;
+				} else {
+					p->symbol =
+						malloc(strlen(alias->name) + 1);
+					strcpy(p->symbol, alias->name);
+					p->type = KERNEL_PMU_EVENT;
+					len++;
+				}
+			}
+		}
+	qsort(perf_pmu_events_list, len,
+		sizeof(struct perf_pmu_event_symbol), comp_pmu);
+
+}
+
+static void perf_pmu__parse_cleanup(void)
+{
+	if (!perf_pmu_events_list_num) {
+		struct perf_pmu_event_symbol *p;
+		size_t i;
+
+		for (i = 0; i < perf_pmu_events_list_num; i++) {
+			p = perf_pmu_events_list + i;
+			free(p->symbol);
+		}
+		free(perf_pmu_events_list);
+		perf_pmu_events_list = NULL;
+		perf_pmu_events_list_num = 0;
+	}
+}
+
+enum perf_pmu_event_symbol_type
+perf_pmu__parse_check(const char *name)
+{
+	struct perf_pmu_event_symbol p, *r;
+
+	/* scan kernel pmu events from sysfs if needed */
+	if (!perf_pmu_events_list_num)
+		perf_pmu__parse_init();
+	/*
+	 * name "cpu" could be prefix of cpu-cycles or cpu// events.
+	 * cpu-cycles has been handled by hardcode.
+	 * So it must be cpu// events, not kernel pmu event.
+	 */
+	if (!perf_pmu_events_list_num || !strcmp(name, "cpu"))
+		return NONE_KERNEL_PMU_EVENT;
+
+	p.symbol = malloc(strlen(name) + 1);
+	strcpy(p.symbol, name);
+	r = bsearch(&p, perf_pmu_events_list,
+			perf_pmu_events_list_num,
+			sizeof(struct perf_pmu_event_symbol), comp_pmu);
+	free(p.symbol);
+	if (r == NULL)
+		return NONE_KERNEL_PMU_EVENT;
+	return r->type;
+}
+
 static int parse_events__scanner(const char *str, void *data, int start_token)
 {
 	YY_BUFFER_STATE buffer;
@@ -918,6 +1035,7 @@ int parse_events(struct perf_evlist *evlist, const char *str)
 	int ret;
 
 	ret = parse_events__scanner(str, &data, PE_START_EVENTS);
+	perf_pmu__parse_cleanup();
 	if (!ret) {
 		int entries = data.idx - evlist->nr_entries;
 		perf_evlist__splice_list_tail(evlist, &data.list, entries);
diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h
index df094b4..9f064e4 100644
--- a/tools/perf/util/parse-events.h
+++ b/tools/perf/util/parse-events.h
@@ -35,6 +35,18 @@ extern int parse_filter(const struct option *opt, const char *str, int unset);
 
 #define EVENTS_HELP_MAX (128*1024)
 
+enum perf_pmu_event_symbol_type {
+	NONE_KERNEL_PMU_EVENT,		/* not a PMU EVENT */
+	KERNEL_PMU_EVENT,		/* normal style PMU event */
+	KERNEL_PMU_EVENT_PREFIX,	/* prefix of pre-suf style event */
+	KERNEL_PMU_EVENT_SUFFIX,	/* suffix of pre-suf style event */
+};
+
+struct perf_pmu_event_symbol {
+	char	*symbol;
+	enum perf_pmu_event_symbol_type	type;
+};
+
 enum {
 	PARSE_EVENTS__TERM_TYPE_NUM,
 	PARSE_EVENTS__TERM_TYPE_STR,
@@ -95,6 +107,8 @@ int parse_events_add_breakpoint(struct list_head *list, int *idx,
 				void *ptr, char *type);
 int parse_events_add_pmu(struct list_head *list, int *idx,
 			 char *pmu , struct list_head *head_config);
+enum perf_pmu_event_symbol_type
+perf_pmu__parse_check(const char *name);
 void parse_events__set_leader(char *name, struct list_head *list);
 void parse_events_update_lists(struct list_head *list_event,
 			       struct list_head *list_all);
diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
index 22a4ad5..f358345 100644
--- a/tools/perf/util/pmu.c
+++ b/tools/perf/util/pmu.c
@@ -12,16 +12,6 @@
 #include "parse-events.h"
 #include "cpumap.h"
 
-#define UNIT_MAX_LEN	31 /* max length for event unit name */
-
-struct perf_pmu_alias {
-	char *name;
-	struct list_head terms; /* HEAD struct parse_events_term -> list */
-	struct list_head list;  /* ELEM */
-	char unit[UNIT_MAX_LEN+1];
-	double scale;
-};
-
 struct perf_pmu_format {
 	char *name;
 	int value;
diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h
index 0f5c0a8..2020519 100644
--- a/tools/perf/util/pmu.h
+++ b/tools/perf/util/pmu.h
@@ -25,6 +25,16 @@ struct perf_pmu {
 	struct list_head list;    /* ELEM */
 };
 
+#define UNIT_MAX_LEN	31 /* max length for event unit name */
+
+struct perf_pmu_alias {
+	char *name;
+	struct list_head terms; /* HEAD struct parse_events_term -> list */
+	struct list_head list;  /* ELEM */
+	char unit[UNIT_MAX_LEN+1];
+	double scale;
+};
+
 struct perf_pmu *perf_pmu__find(const char *name);
 int perf_pmu__config(struct perf_pmu *pmu, struct perf_event_attr *attr,
 		     struct list_head *head_terms);
-- 
1.8.3.2


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH V5 3/3] perf tools: Add support to new style format of kernel PMU event
  2014-09-10 17:55 [PATCH V5 1/3] Revert "perf tools: Default to cpu// for events v5" kan.liang
  2014-09-10 17:55 ` [PATCH V5 2/3] perf tools: parse the pmu event prefix and surfix kan.liang
@ 2014-09-10 17:55 ` kan.liang
  1 sibling, 0 replies; 9+ messages in thread
From: kan.liang @ 2014-09-10 17:55 UTC (permalink / raw)
  To: acme, jolsa; +Cc: linux-kernel, ak, Kan Liang

From: Kan Liang <kan.liang@intel.com>

Add new rules for kernel PMU event.

Currently, the patch only want to handle the PMU event name as "a-b" and
"a".

event_pmu:
PE_KERNEL_PMU_EVENT
|
PE_PMU_EVENT_PRE '-' PE_PMU_EVENT_SUF

PE_KERNEL_PMU_EVENT token is for
cycles-ct/cycles-t/mem-loads/mem-stores.
The prefix cycles is mixed up with cpu-cycles.
loads and stores are mixed up with cache event
So they have to be hardcode in lex.

PE_PMU_EVENT_PRE and PE_PMU_EVENT_SUF tokens are for other PMU
events.
The lex looks generic identifier up in the table and return the matched
token. If there is no match, generic PE_NAME token will be return.

Using the rules, kernel PMU event could use new style format without //

so you can use

perf record -e mem-loads ...

instead of

perf record -e cpu/mem-loads/

Signed-off-by: Kan Liang <kan.liang@intel.com>
---

v5: Use ALLOC_LIST

 tools/perf/util/parse-events.l | 30 +++++++++++++++++++++++++++++-
 tools/perf/util/parse-events.y | 40 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 69 insertions(+), 1 deletion(-)

diff --git a/tools/perf/util/parse-events.l b/tools/perf/util/parse-events.l
index 3432995..ea970cf 100644
--- a/tools/perf/util/parse-events.l
+++ b/tools/perf/util/parse-events.l
@@ -51,6 +51,24 @@ static int str(yyscan_t scanner, int token)
 	return token;
 }
 
+static int pmu_str_check(yyscan_t scanner)
+{
+	YYSTYPE *yylval = parse_events_get_lval(scanner);
+	char *text = parse_events_get_text(scanner);
+
+	yylval->str = strdup(text);
+	switch (perf_pmu__parse_check(text)) {
+		case KERNEL_PMU_EVENT_PREFIX:
+			return PE_PMU_EVENT_PRE;
+		case KERNEL_PMU_EVENT_SUFFIX:
+			return PE_PMU_EVENT_SUF;
+		case KERNEL_PMU_EVENT:
+			return PE_KERNEL_PMU_EVENT;
+		default:
+			return PE_NAME;
+	}
+}
+
 static int sym(yyscan_t scanner, int type, int config)
 {
 	YYSTYPE *yylval = parse_events_get_lval(scanner);
@@ -178,6 +196,16 @@ alignment-faults				{ return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_AL
 emulation-faults				{ return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_EMULATION_FAULTS); }
 dummy						{ return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_DUMMY); }
 
+	/*
+	 * We have to handle the kernel PMU event cycles-ct/cycles-t/mem-loads/mem-stores separately.
+	 * Because the prefix cycles is mixed up with cpu-cycles.
+	 * loads and stores are mixed up with cache event
+	 */
+cycles-ct					{ return str(yyscanner, PE_KERNEL_PMU_EVENT); }
+cycles-t					{ return str(yyscanner, PE_KERNEL_PMU_EVENT); }
+mem-loads					{ return str(yyscanner, PE_KERNEL_PMU_EVENT); }
+mem-stores					{ return str(yyscanner, PE_KERNEL_PMU_EVENT); }
+
 L1-dcache|l1-d|l1d|L1-data		|
 L1-icache|l1-i|l1i|L1-instruction	|
 LLC|L2					|
@@ -199,7 +227,7 @@ r{num_raw_hex}		{ return raw(yyscanner); }
 {num_hex}		{ return value(yyscanner, 16); }
 
 {modifier_event}	{ return str(yyscanner, PE_MODIFIER_EVENT); }
-{name}			{ return str(yyscanner, PE_NAME); }
+{name}			{ return pmu_str_check(yyscanner); }
 "/"			{ BEGIN(config); return '/'; }
 -			{ return '-'; }
 ,			{ BEGIN(event); return ','; }
diff --git a/tools/perf/util/parse-events.y b/tools/perf/util/parse-events.y
index 55fab6a..3f26c03 100644
--- a/tools/perf/util/parse-events.y
+++ b/tools/perf/util/parse-events.y
@@ -47,6 +47,7 @@ static inc_group_count(struct list_head *list,
 %token PE_NAME_CACHE_TYPE PE_NAME_CACHE_OP_RESULT
 %token PE_PREFIX_MEM PE_PREFIX_RAW PE_PREFIX_GROUP
 %token PE_ERROR
+%token PE_PMU_EVENT_PRE PE_PMU_EVENT_SUF PE_KERNEL_PMU_EVENT
 %type <num> PE_VALUE
 %type <num> PE_VALUE_SYM_HW
 %type <num> PE_VALUE_SYM_SW
@@ -58,6 +59,7 @@ static inc_group_count(struct list_head *list,
 %type <str> PE_MODIFIER_EVENT
 %type <str> PE_MODIFIER_BP
 %type <str> PE_EVENT_NAME
+%type <str> PE_PMU_EVENT_PRE PE_PMU_EVENT_SUF PE_KERNEL_PMU_EVENT
 %type <num> value_sym
 %type <head> event_config
 %type <term> event_term
@@ -220,6 +222,44 @@ PE_NAME '/' '/'
 	ABORT_ON(parse_events_add_pmu(list, &data->idx, $1, NULL));
 	$$ = list;
 }
+|
+PE_KERNEL_PMU_EVENT
+{
+	struct parse_events_evlist *data = _data;
+	struct list_head *head;
+	struct parse_events_term *term;
+	struct list_head *list;
+
+	ALLOC_LIST(head);
+	ABORT_ON(parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER,
+					$1, 1));
+	list_add_tail(&term->list, head);
+
+	ALLOC_LIST(list);
+	ABORT_ON(parse_events_add_pmu(list, &data->idx, "cpu", head));
+	parse_events__free_terms(head);
+	$$ = list;
+}
+|
+PE_PMU_EVENT_PRE '-' PE_PMU_EVENT_SUF
+{
+	struct parse_events_evlist *data = _data;
+	struct list_head *head;
+	struct parse_events_term *term;
+	struct list_head *list;
+	char pmu_name[128];
+	snprintf(&pmu_name, 128, "%s-%s", $1, $3);
+
+	ALLOC_LIST(head);
+	ABORT_ON(parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER,
+					&pmu_name, 1));
+	list_add_tail(&term->list, head);
+
+	ALLOC_LIST(list);
+	ABORT_ON(parse_events_add_pmu(list, &data->idx, "cpu", head));
+	parse_events__free_terms(head);
+	$$ = list;
+}
 
 value_sym:
 PE_VALUE_SYM_HW
-- 
1.8.3.2


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH V5 2/3] perf tools: parse the pmu event prefix and surfix
  2014-09-10 17:55 ` [PATCH V5 2/3] perf tools: parse the pmu event prefix and surfix kan.liang
@ 2014-09-11  8:46   ` Jiri Olsa
  2014-09-11 13:31     ` Liang, Kan
  2014-09-11  8:51   ` Jiri Olsa
  1 sibling, 1 reply; 9+ messages in thread
From: Jiri Olsa @ 2014-09-11  8:46 UTC (permalink / raw)
  To: kan.liang; +Cc: acme, linux-kernel, ak

On Wed, Sep 10, 2014 at 01:55:31PM -0400, kan.liang@intel.com wrote:
> From: Kan Liang <kan.liang@intel.com>
> 

SNIP

>  	return 0;
>  }
>  
> +static int
> +comp_pmu(const void *p1, const void *p2)
> +{
> +	struct perf_pmu_event_symbol *pmu1 =
> +			(struct perf_pmu_event_symbol *) p1;
> +	struct perf_pmu_event_symbol *pmu2 =
> +			(struct perf_pmu_event_symbol *) p2;
> +
> +	return strcmp(pmu1->symbol, pmu2->symbol);
> +}
> +
> +/*
> + * Read the pmu events list from sysfs
> + * Save it into perf_pmu_events_list
> + */
> +static void perf_pmu__parse_init(void)
> +{
> +
> +	struct perf_pmu *pmu = NULL;
> +	struct perf_pmu_alias *alias;
> +	int len = 0;
> +

missing my previous comment being addressed:

---
Why do we need to call scan here? Looks like:
  pmu = pmu_lookup("cpu")

should be enough.. and could be used below as well
---

or commented why not to do it..

jirka

> +	while ((pmu = perf_pmu__scan(pmu)) != NULL)
> +		list_for_each_entry(alias, &pmu->aliases, list) {
> +			if (!strcmp(pmu->name, "cpu")) {
> +				if (strchr(alias->name, '-'))
> +					len++;
> +				len++;
> +			}
> +	}
> +	if (len == 0)
> +		return;
> +	perf_pmu_events_list =
> +		malloc(sizeof(struct perf_pmu_event_symbol) * len);
> +	perf_pmu_events_list_num = len;
> +
> +	pmu = NULL;
> +	len = 0;
> +	while ((pmu = perf_pmu__scan(pmu)) != NULL)
> +		list_for_each_entry(alias, &pmu->aliases, list) {
> +			if (!strcmp(pmu->name, "cpu")) {
> +				struct perf_pmu_event_symbol *p =
> +					perf_pmu_events_list + len;
> +				char *tmp = strchr(alias->name, '-');
> +
> +				if (tmp != NULL) {
> +					p->symbol =
> +						malloc(tmp - alias->name + 1);
> +					strlcpy(p->symbol, alias->name,
> +						tmp - alias->name + 1);
> +					p->type = KERNEL_PMU_EVENT_PREFIX;
> +					tmp++;
> +					p++;
> +					p->symbol = malloc(strlen(tmp) + 1);
> +					strcpy(p->symbol, tmp);
> +					p->type = KERNEL_PMU_EVENT_SUFFIX;
> +					len += 2;
> +				} else {
> +					p->symbol =
> +						malloc(strlen(alias->name) + 1);
> +					strcpy(p->symbol, alias->name);
> +					p->type = KERNEL_PMU_EVENT;
> +					len++;
> +				}
> +			}
> +		}
> +	qsort(perf_pmu_events_list, len,
> +		sizeof(struct perf_pmu_event_symbol), comp_pmu);
> +
> +}
> +

SNIP

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH V5 2/3] perf tools: parse the pmu event prefix and surfix
  2014-09-10 17:55 ` [PATCH V5 2/3] perf tools: parse the pmu event prefix and surfix kan.liang
  2014-09-11  8:46   ` Jiri Olsa
@ 2014-09-11  8:51   ` Jiri Olsa
  2014-09-11 13:50     ` Liang, Kan
  1 sibling, 1 reply; 9+ messages in thread
From: Jiri Olsa @ 2014-09-11  8:51 UTC (permalink / raw)
  To: kan.liang; +Cc: acme, linux-kernel, ak

On Wed, Sep 10, 2014 at 01:55:31PM -0400, kan.liang@intel.com wrote:

SNIP

> +	struct perf_pmu_event_symbol *pmu2 =
> +			(struct perf_pmu_event_symbol *) p2;
> +
> +	return strcmp(pmu1->symbol, pmu2->symbol);
> +}
> +
> +/*
> + * Read the pmu events list from sysfs
> + * Save it into perf_pmu_events_list
> + */
> +static void perf_pmu__parse_init(void)
> +{
> +
> +	struct perf_pmu *pmu = NULL;
> +	struct perf_pmu_alias *alias;
> +	int len = 0;
> +
> +	while ((pmu = perf_pmu__scan(pmu)) != NULL)
> +		list_for_each_entry(alias, &pmu->aliases, list) {
> +			if (!strcmp(pmu->name, "cpu")) {
> +				if (strchr(alias->name, '-'))
> +					len++;
> +				len++;
> +			}
> +	}
> +	if (len == 0)
> +		return;

s oif 'len' is 0 we will scan all the time? maybe we want some
separate 'init' variable..


> +	perf_pmu_events_list =
> +		malloc(sizeof(struct perf_pmu_event_symbol) * len);
> +	perf_pmu_events_list_num = len;
> +
> +	pmu = NULL;
> +	len = 0;

SNIP

> +	qsort(perf_pmu_events_list, len,
> +		sizeof(struct perf_pmu_event_symbol), comp_pmu);
> +
> +}
> +
> +static void perf_pmu__parse_cleanup(void)
> +{
> +	if (!perf_pmu_events_list_num) {

should this be 'if (perf_pmu_events_list_num)' ?

could you also please write automated test for this feature?

thanks,
jirka

> +		struct perf_pmu_event_symbol *p;
> +		size_t i;
> +
> +		for (i = 0; i < perf_pmu_events_list_num; i++) {
> +			p = perf_pmu_events_list + i;
> +			free(p->symbol);
> +		}
> +		free(perf_pmu_events_list);
> +		perf_pmu_events_list = NULL;
> +		perf_pmu_events_list_num = 0;
> +	}
> +}
> +

SNIP

^ permalink raw reply	[flat|nested] 9+ messages in thread

* RE: [PATCH V5 2/3] perf tools: parse the pmu event prefix and surfix
  2014-09-11  8:46   ` Jiri Olsa
@ 2014-09-11 13:31     ` Liang, Kan
  2014-09-11 13:37       ` Jiri Olsa
  0 siblings, 1 reply; 9+ messages in thread
From: Liang, Kan @ 2014-09-11 13:31 UTC (permalink / raw)
  To: Jiri Olsa; +Cc: acme, linux-kernel, ak



> SNIP
> 
> >  	return 0;
> >  }
> >
> > +static int
> > +comp_pmu(const void *p1, const void *p2) {
> > +	struct perf_pmu_event_symbol *pmu1 =
> > +			(struct perf_pmu_event_symbol *) p1;
> > +	struct perf_pmu_event_symbol *pmu2 =
> > +			(struct perf_pmu_event_symbol *) p2;
> > +
> > +	return strcmp(pmu1->symbol, pmu2->symbol); }
> > +
> > +/*
> > + * Read the pmu events list from sysfs
> > + * Save it into perf_pmu_events_list
> > + */
> > +static void perf_pmu__parse_init(void) {
> > +
> > +	struct perf_pmu *pmu = NULL;
> > +	struct perf_pmu_alias *alias;
> > +	int len = 0;
> > +
> 
> missing my previous comment being addressed:
>

I just found it in Junk E-mail. I have no idea why. :(
 
> ---
> Why do we need to call scan here? Looks like:
>   pmu = pmu_lookup("cpu")
> 
> should be enough.. and could be used below as well
> ---
>

Could we use "perf_pmu__find" here?
pmu_lookup is a static function.
Also, it looks we don't need to lookup all the time if the PMU is loaded.
 
Thanks,
Kan

> or commented why not to do it..
> 
> jirka
> 


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH V5 2/3] perf tools: parse the pmu event prefix and surfix
  2014-09-11 13:31     ` Liang, Kan
@ 2014-09-11 13:37       ` Jiri Olsa
  0 siblings, 0 replies; 9+ messages in thread
From: Jiri Olsa @ 2014-09-11 13:37 UTC (permalink / raw)
  To: Liang, Kan; +Cc: acme, linux-kernel, ak

On Thu, Sep 11, 2014 at 01:31:48PM +0000, Liang, Kan wrote:
> 
> 
> > SNIP
> > 
> > >  	return 0;
> > >  }
> > >
> > > +static int
> > > +comp_pmu(const void *p1, const void *p2) {
> > > +	struct perf_pmu_event_symbol *pmu1 =
> > > +			(struct perf_pmu_event_symbol *) p1;
> > > +	struct perf_pmu_event_symbol *pmu2 =
> > > +			(struct perf_pmu_event_symbol *) p2;
> > > +
> > > +	return strcmp(pmu1->symbol, pmu2->symbol); }
> > > +
> > > +/*
> > > + * Read the pmu events list from sysfs
> > > + * Save it into perf_pmu_events_list
> > > + */
> > > +static void perf_pmu__parse_init(void) {
> > > +
> > > +	struct perf_pmu *pmu = NULL;
> > > +	struct perf_pmu_alias *alias;
> > > +	int len = 0;
> > > +
> > 
> > missing my previous comment being addressed:
> >
> 
> I just found it in Junk E-mail. I have no idea why. :(
>  
> > ---
> > Why do we need to call scan here? Looks like:
> >   pmu = pmu_lookup("cpu")
> > 
> > should be enough.. and could be used below as well
> > ---
> >
> 
> Could we use "perf_pmu__find" here?
> pmu_lookup is a static function.
> Also, it looks we don't need to lookup all the time if the PMU is loaded.

right, perf_pmu__find seems better

thanks,
jirka

^ permalink raw reply	[flat|nested] 9+ messages in thread

* RE: [PATCH V5 2/3] perf tools: parse the pmu event prefix and surfix
  2014-09-11  8:51   ` Jiri Olsa
@ 2014-09-11 13:50     ` Liang, Kan
  2014-09-11 14:53       ` Jiri Olsa
  0 siblings, 1 reply; 9+ messages in thread
From: Liang, Kan @ 2014-09-11 13:50 UTC (permalink / raw)
  To: Jiri Olsa; +Cc: acme, linux-kernel, ak



> On Wed, Sep 10, 2014 at 01:55:31PM -0400, kan.liang@intel.com wrote:
> 
> SNIP
> 
> > +	struct perf_pmu_event_symbol *pmu2 =
> > +			(struct perf_pmu_event_symbol *) p2;
> > +
> > +	return strcmp(pmu1->symbol, pmu2->symbol); }
> > +
> > +/*
> > + * Read the pmu events list from sysfs
> > + * Save it into perf_pmu_events_list
> > + */
> > +static void perf_pmu__parse_init(void) {
> > +
> > +	struct perf_pmu *pmu = NULL;
> > +	struct perf_pmu_alias *alias;
> > +	int len = 0;
> > +
> > +	while ((pmu = perf_pmu__scan(pmu)) != NULL)
> > +		list_for_each_entry(alias, &pmu->aliases, list) {
> > +			if (!strcmp(pmu->name, "cpu")) {
> > +				if (strchr(alias->name, '-'))
> > +					len++;
> > +				len++;
> > +			}
> > +	}
> > +	if (len == 0)
> > +		return;
> 
> s oif 'len' is 0 we will scan all the time? maybe we want some separate 'init'
> variable..
> 

Maybe we can reuse the "perf_pmu_events_list_num".
static int perf_pmu_events_list_num;

If len is 0, we just set perf_pmu_events_list_num to -1.
Is it OK?

Thanks,
Kan

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH V5 2/3] perf tools: parse the pmu event prefix and surfix
  2014-09-11 13:50     ` Liang, Kan
@ 2014-09-11 14:53       ` Jiri Olsa
  0 siblings, 0 replies; 9+ messages in thread
From: Jiri Olsa @ 2014-09-11 14:53 UTC (permalink / raw)
  To: Liang, Kan; +Cc: acme, linux-kernel, ak

On Thu, Sep 11, 2014 at 01:50:50PM +0000, Liang, Kan wrote:
> 
> 
> > On Wed, Sep 10, 2014 at 01:55:31PM -0400, kan.liang@intel.com wrote:
> > 
> > SNIP
> > 
> > > +	struct perf_pmu_event_symbol *pmu2 =
> > > +			(struct perf_pmu_event_symbol *) p2;
> > > +
> > > +	return strcmp(pmu1->symbol, pmu2->symbol); }
> > > +
> > > +/*
> > > + * Read the pmu events list from sysfs
> > > + * Save it into perf_pmu_events_list
> > > + */
> > > +static void perf_pmu__parse_init(void) {
> > > +
> > > +	struct perf_pmu *pmu = NULL;
> > > +	struct perf_pmu_alias *alias;
> > > +	int len = 0;
> > > +
> > > +	while ((pmu = perf_pmu__scan(pmu)) != NULL)
> > > +		list_for_each_entry(alias, &pmu->aliases, list) {
> > > +			if (!strcmp(pmu->name, "cpu")) {
> > > +				if (strchr(alias->name, '-'))
> > > +					len++;
> > > +				len++;
> > > +			}
> > > +	}
> > > +	if (len == 0)
> > > +		return;
> > 
> > s oif 'len' is 0 we will scan all the time? maybe we want some separate 'init'
> > variable..
> > 
> 
> Maybe we can reuse the "perf_pmu_events_list_num".
> static int perf_pmu_events_list_num;
> 
> If len is 0, we just set perf_pmu_events_list_num to -1.
> Is it OK?

seems ok

jirka

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2014-09-11 14:53 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-09-10 17:55 [PATCH V5 1/3] Revert "perf tools: Default to cpu// for events v5" kan.liang
2014-09-10 17:55 ` [PATCH V5 2/3] perf tools: parse the pmu event prefix and surfix kan.liang
2014-09-11  8:46   ` Jiri Olsa
2014-09-11 13:31     ` Liang, Kan
2014-09-11 13:37       ` Jiri Olsa
2014-09-11  8:51   ` Jiri Olsa
2014-09-11 13:50     ` Liang, Kan
2014-09-11 14:53       ` Jiri Olsa
2014-09-10 17:55 ` [PATCH V5 3/3] perf tools: Add support to new style format of kernel PMU event kan.liang

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.