Re: [PATCH v3 2/3] perf tools: parse the pmu event prefix and surfix

2014-09-02 Thread Jiri Olsa
On Mon, Sep 01, 2014 at 12:29:46PM -0400, kan.li...@intel.com wrote:
> From: Kan Liang 
> 
> 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.

this one does not apply to latest acme's perf/core

could you please rebase your patchset to:
  git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux perf/core

thanks,
jirka
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v3 2/3] perf tools: parse the pmu event prefix and surfix

2014-09-02 Thread Jiri Olsa
On Mon, Sep 01, 2014 at 12:29:46PM -0400, kan.li...@intel.com wrote:
 From: Kan Liang kan.li...@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.

this one does not apply to latest acme's perf/core

could you please rebase your patchset to:
  git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux perf/core

thanks,
jirka
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v3 2/3] perf tools: parse the pmu event prefix and surfix

2014-09-01 Thread kan . liang
From: Kan Liang 

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.

Signed-off-by: Kan Liang 
---
v2: Read kernel PMU events from sysfs at runtime
v3: Use strlcpy to replace strncpy

 tools/perf/util/parse-events.c | 103 +
 tools/perf/util/parse-events.h |  15 ++
 tools/perf/util/pmu.c  |  10 
 tools/perf/util/pmu.h  |  10 
 4 files changed, 128 insertions(+), 10 deletions(-)

diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index 7a0aa75..313dadd 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -29,6 +29,9 @@ extern int parse_events_debug;
 #endif
 int parse_events_parse(void *data, void *scanner);
 
+static struct kernel_pmu_event_symbol *kernel_pmu_events_list;
+static size_t kernel_pmu_events_list_num;
+
 static struct event_symbol event_symbols_hw[PERF_COUNT_HW_MAX] = {
[PERF_COUNT_HW_CPU_CYCLES] = {
.symbol = "cpu-cycles",
@@ -852,6 +855,103 @@ int parse_events_name(struct list_head *list, char *name)
return 0;
 }
 
+static int
+comp_pmu(const void *p1, const void *p2)
+{
+   struct kernel_pmu_event_symbol *pmu1 =
+   (struct kernel_pmu_event_symbol *) p1;
+   struct kernel_pmu_event_symbol *pmu2 =
+   (struct kernel_pmu_event_symbol *) p2;
+
+   return strcmp(pmu1->symbol, pmu2->symbol);
+}
+
+enum kernel_pmu_event_type
+parse_events_pmu_check(const char *name)
+{
+   struct kernel_pmu_event_symbol p, *r;
+
+   /*
+* 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 (!kernel_pmu_events_list_num || !strcmp(name, "cpu"))
+   return NONE_KERNEL_PMU_EVENT;
+
+   strcpy(p.symbol, name);
+   r = bsearch(, kernel_pmu_events_list,
+   kernel_pmu_events_list_num,
+   sizeof(struct kernel_pmu_event_symbol), comp_pmu);
+   if (r == NULL)
+   return NONE_KERNEL_PMU_EVENT;
+   return r->type;
+}
+
+/*
+ * Read the pmu events list from sysfs
+ * Save it into kernel_pmu_events_list
+ */
+static void scan_kernel_pmu_events_list(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, >aliases, list) {
+   if (!strcmp(pmu->name, "cpu")) {
+   if (strchr(alias->name, '-'))
+   len++;
+   len++;
+   }
+   }
+   if (len == 0)
+   return;
+   kernel_pmu_events_list =
+   malloc(sizeof(struct kernel_pmu_event_symbol) * len);
+   kernel_pmu_events_list_num = len;
+
+   pmu = NULL;
+   len = 0;
+   while ((pmu = perf_pmu__scan(pmu)) != NULL)
+   list_for_each_entry(alias, >aliases, list) {
+   if (!strcmp(pmu->name, "cpu")) {
+   struct kernel_pmu_event_symbol *p =
+   kernel_pmu_events_list + len;
+   char *tmp = strchr(alias->name, '-');
+
+   if (tmp != NULL) {
+   strlcpy(p->symbol, alias->name,
+   tmp - alias->name + 1);
+   p->type = KERNEL_PMU_EVENT_PREFIX;
+   tmp++;
+   p++;
+   strcpy(p->symbol, tmp);
+   p->type = KERNEL_PMU_EVENT_SUFFIX;
+   len += 2;
+   } else {
+   strcpy(p->symbol, alias->name);
+   p->type = KERNEL_PMU_EVENT;
+   len++;
+   }
+   }
+   }
+   qsort(kernel_pmu_events_list, len,
+   sizeof(struct kernel_pmu_event_symbol), comp_pmu);
+
+}
+
+static void release_kernel_pmu_events_list(void)
+{
+   if (kernel_pmu_events_list) {
+   free(kernel_pmu_events_list);
+   kernel_pmu_events_list = NULL;
+   }
+   

[PATCH v3 2/3] perf tools: parse the pmu event prefix and surfix

2014-09-01 Thread kan . liang
From: Kan Liang kan.li...@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.

Signed-off-by: Kan Liang kan.li...@intel.com
---
v2: Read kernel PMU events from sysfs at runtime
v3: Use strlcpy to replace strncpy

 tools/perf/util/parse-events.c | 103 +
 tools/perf/util/parse-events.h |  15 ++
 tools/perf/util/pmu.c  |  10 
 tools/perf/util/pmu.h  |  10 
 4 files changed, 128 insertions(+), 10 deletions(-)

diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index 7a0aa75..313dadd 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -29,6 +29,9 @@ extern int parse_events_debug;
 #endif
 int parse_events_parse(void *data, void *scanner);
 
+static struct kernel_pmu_event_symbol *kernel_pmu_events_list;
+static size_t kernel_pmu_events_list_num;
+
 static struct event_symbol event_symbols_hw[PERF_COUNT_HW_MAX] = {
[PERF_COUNT_HW_CPU_CYCLES] = {
.symbol = cpu-cycles,
@@ -852,6 +855,103 @@ int parse_events_name(struct list_head *list, char *name)
return 0;
 }
 
+static int
+comp_pmu(const void *p1, const void *p2)
+{
+   struct kernel_pmu_event_symbol *pmu1 =
+   (struct kernel_pmu_event_symbol *) p1;
+   struct kernel_pmu_event_symbol *pmu2 =
+   (struct kernel_pmu_event_symbol *) p2;
+
+   return strcmp(pmu1-symbol, pmu2-symbol);
+}
+
+enum kernel_pmu_event_type
+parse_events_pmu_check(const char *name)
+{
+   struct kernel_pmu_event_symbol p, *r;
+
+   /*
+* 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 (!kernel_pmu_events_list_num || !strcmp(name, cpu))
+   return NONE_KERNEL_PMU_EVENT;
+
+   strcpy(p.symbol, name);
+   r = bsearch(p, kernel_pmu_events_list,
+   kernel_pmu_events_list_num,
+   sizeof(struct kernel_pmu_event_symbol), comp_pmu);
+   if (r == NULL)
+   return NONE_KERNEL_PMU_EVENT;
+   return r-type;
+}
+
+/*
+ * Read the pmu events list from sysfs
+ * Save it into kernel_pmu_events_list
+ */
+static void scan_kernel_pmu_events_list(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;
+   kernel_pmu_events_list =
+   malloc(sizeof(struct kernel_pmu_event_symbol) * len);
+   kernel_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 kernel_pmu_event_symbol *p =
+   kernel_pmu_events_list + len;
+   char *tmp = strchr(alias-name, '-');
+
+   if (tmp != NULL) {
+   strlcpy(p-symbol, alias-name,
+   tmp - alias-name + 1);
+   p-type = KERNEL_PMU_EVENT_PREFIX;
+   tmp++;
+   p++;
+   strcpy(p-symbol, tmp);
+   p-type = KERNEL_PMU_EVENT_SUFFIX;
+   len += 2;
+   } else {
+   strcpy(p-symbol, alias-name);
+   p-type = KERNEL_PMU_EVENT;
+   len++;
+   }
+   }
+   }
+   qsort(kernel_pmu_events_list, len,
+   sizeof(struct kernel_pmu_event_symbol), comp_pmu);
+
+}
+
+static void release_kernel_pmu_events_list(void)
+{
+   if (kernel_pmu_events_list) {
+   free(kernel_pmu_events_list);
+   kernel_pmu_events_list =