From: tip-bot for Zheng Yan <zheng.z.yan@intel.com>
To: linux-tip-commits@vger.kernel.org
Cc: linux-kernel@vger.kernel.org, hpa@zytor.com, mingo@kernel.org,
torvalds@linux-foundation.org, a.p.zijlstra@chello.nl,
jolsa@redhat.com, akpm@linux-foundation.org,
zheng.z.yan@intel.com, tglx@linutronix.de
Subject: [tip:perf/core] perf/tool: Add PMU event alias support
Date: Wed, 20 Jun 2012 04:00:29 -0700 [thread overview]
Message-ID: <tip-a6146d5040cce560f700221158d77dd335eed332@git.kernel.org> (raw)
In-Reply-To: <1339741902-8449-13-git-send-email-zheng.z.yan@intel.com>
Commit-ID: a6146d5040cce560f700221158d77dd335eed332
Gitweb: http://git.kernel.org/tip/a6146d5040cce560f700221158d77dd335eed332
Author: Zheng Yan <zheng.z.yan@intel.com>
AuthorDate: Fri, 15 Jun 2012 14:31:41 +0800
Committer: Ingo Molnar <mingo@kernel.org>
CommitDate: Mon, 18 Jun 2012 12:13:26 +0200
perf/tool: Add PMU event alias support
Add support to specify alias term within the event description.
The definition of pmu event alias is located at:
${sysfs_mount}/bus/event_source/devices/${pmu}/events/
Each file in the 'events' directory defines a event alias. Its contents
are like:
config=1,config1=2
Using pmu event alias, an event can be now specified like:
uncore/CLOCKTICKS/ or uncore/event=CLOCKTICKS/
Signed-off-by: Zheng Yan <zheng.z.yan@intel.com>
[ Cleaned it up. ]
Signed-off-by: Jiri Olsa <jolsa@redhat.com>
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: http://lkml.kernel.org/r/1339741902-8449-13-git-send-email-zheng.z.yan@intel.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
tools/perf/util/parse-events.c | 10 +++
tools/perf/util/parse-events.h | 2 +
tools/perf/util/pmu.c | 166 ++++++++++++++++++++++++++++++++++++++++
tools/perf/util/pmu.h | 11 +++-
4 files changed, 188 insertions(+), 1 deletions(-)
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index d002170..3339424 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -701,6 +701,9 @@ int parse_events_add_pmu(struct list_head **list, int *idx,
memset(&attr, 0, sizeof(attr));
+ if (perf_pmu__check_alias(pmu, head_config))
+ return -EINVAL;
+
/*
* Configure hardcoded terms first, no need to check
* return value when called with fail == 0 ;)
@@ -1143,6 +1146,13 @@ int parse_events__term_str(struct parse_events__term **term,
config, str, 0);
}
+int parse_events__term_clone(struct parse_events__term **new,
+ struct parse_events__term *term)
+{
+ return new_term(new, term->type_val, term->type_term, term->config,
+ term->val.str, term->val.num);
+}
+
void parse_events__free_terms(struct list_head *terms)
{
struct parse_events__term *term, *h;
diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h
index 9896eda..a2c7168 100644
--- a/tools/perf/util/parse-events.h
+++ b/tools/perf/util/parse-events.h
@@ -78,6 +78,8 @@ int parse_events__term_num(struct parse_events__term **_term,
int type_term, char *config, long num);
int parse_events__term_str(struct parse_events__term **_term,
int type_term, char *config, char *str);
+int parse_events__term_clone(struct parse_events__term **new,
+ struct parse_events__term *term);
void parse_events__free_terms(struct list_head *terms);
int parse_events_modifier(struct list_head *list, char *str);
int parse_events_add_tracepoint(struct list_head **list, int *idx,
diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
index a119a53..74d0948e 100644
--- a/tools/perf/util/pmu.c
+++ b/tools/perf/util/pmu.c
@@ -80,6 +80,114 @@ static int pmu_format(char *name, struct list_head *format)
return 0;
}
+static int perf_pmu__new_alias(struct list_head *list, char *name, FILE *file)
+{
+ struct perf_pmu__alias *alias;
+ char buf[256];
+ int ret;
+
+ ret = fread(buf, 1, sizeof(buf), file);
+ if (ret == 0)
+ return -EINVAL;
+ buf[ret] = 0;
+
+ alias = malloc(sizeof(*alias));
+ if (!alias)
+ return -ENOMEM;
+
+ INIT_LIST_HEAD(&alias->terms);
+ ret = parse_events_terms(&alias->terms, buf);
+ if (ret) {
+ free(alias);
+ return ret;
+ }
+
+ alias->name = strdup(name);
+ list_add_tail(&alias->list, list);
+ return 0;
+}
+
+/*
+ * Process all the sysfs attributes located under the directory
+ * specified in 'dir' parameter.
+ */
+static int pmu_aliases_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_alias(head, name, file);
+ fclose(file);
+ }
+
+ closedir(event_dir);
+ return ret;
+}
+
+/*
+ * Reading the pmu event aliases definition, which should be located at:
+ * /sys/bus/event_source/devices/<dev>/events as sysfs group attributes.
+ */
+static int pmu_aliases(char *name, struct list_head *head)
+{
+ 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_aliases_parse(path, head))
+ return -1;
+
+ return 0;
+}
+
+static int pmu_alias_terms(struct perf_pmu__alias *alias,
+ struct list_head *terms)
+{
+ struct parse_events__term *term, *clone;
+ LIST_HEAD(list);
+ int ret;
+
+ list_for_each_entry(term, &alias->terms, list) {
+ ret = parse_events__term_clone(&clone, term);
+ if (ret) {
+ parse_events__free_terms(&list);
+ return ret;
+ }
+ list_add_tail(&clone->list, &list);
+ }
+ list_splice(&list, terms);
+ return 0;
+}
+
/*
* Reading/parsing the default pmu type value, which should be
* located at:
@@ -118,6 +226,7 @@ static struct perf_pmu *pmu_lookup(char *name)
{
struct perf_pmu *pmu;
LIST_HEAD(format);
+ LIST_HEAD(aliases);
__u32 type;
/*
@@ -135,8 +244,12 @@ static struct perf_pmu *pmu_lookup(char *name)
if (!pmu)
return NULL;
+ pmu_aliases(name, &aliases);
+
INIT_LIST_HEAD(&pmu->format);
+ INIT_LIST_HEAD(&pmu->aliases);
list_splice(&format, &pmu->format);
+ list_splice(&aliases, &pmu->aliases);
pmu->name = strdup(name);
pmu->type = type;
return pmu;
@@ -279,6 +392,59 @@ int perf_pmu__config(struct perf_pmu *pmu, struct perf_event_attr *attr,
return pmu_config(&pmu->format, attr, head_terms);
}
+static struct perf_pmu__alias *pmu_find_alias(struct perf_pmu *pmu,
+ struct parse_events__term *term)
+{
+ struct perf_pmu__alias *alias;
+ char *name;
+
+ if (parse_events__is_hardcoded_term(term))
+ return NULL;
+
+ if (term->type_val == PARSE_EVENTS__TERM_TYPE_NUM) {
+ if (term->val.num != 1)
+ return NULL;
+ if (pmu_find_format(&pmu->format, term->config))
+ return NULL;
+ name = term->config;
+ } else if (term->type_val == PARSE_EVENTS__TERM_TYPE_STR) {
+ if (strcasecmp(term->config, "event"))
+ return NULL;
+ name = term->val.str;
+ } else {
+ return NULL;
+ }
+
+ list_for_each_entry(alias, &pmu->aliases, list) {
+ if (!strcasecmp(alias->name, name))
+ return alias;
+ }
+ return NULL;
+}
+
+/*
+ * Find alias in the terms list and replace it with the terms
+ * defined for the alias
+ */
+int perf_pmu__check_alias(struct perf_pmu *pmu, struct list_head *head_terms)
+{
+ struct parse_events__term *term, *h;
+ struct perf_pmu__alias *alias;
+ int ret;
+
+ list_for_each_entry_safe(term, h, head_terms, list) {
+ alias = pmu_find_alias(pmu, term);
+ if (!alias)
+ continue;
+ ret = pmu_alias_terms(alias, &term->list);
+ if (ret)
+ return ret;
+ list_del(&term->list);
+ free(term);
+ }
+ return 0;
+}
+
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..535f2c5 100644
--- a/tools/perf/util/pmu.h
+++ b/tools/perf/util/pmu.h
@@ -19,17 +19,26 @@ struct perf_pmu__format {
struct list_head list;
};
+struct perf_pmu__alias {
+ char *name;
+ struct list_head terms;
+ struct list_head list;
+};
+
struct perf_pmu {
char *name;
__u32 type;
struct list_head format;
+ struct list_head aliases;
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__check_alias(struct perf_pmu *pmu, struct list_head *head_terms);
+struct list_head *perf_pmu__alias(struct perf_pmu *pmu,
+ 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-06-20 11:00 UTC|newest]
Thread overview: 74+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-06-15 6:31 [PATCH V6 0/13] perf: Intel uncore pmu counting support Yan, Zheng
2012-06-15 6:31 ` [PATCH V6 01/13] perf: Export perf_assign_events Yan, Zheng
2012-06-20 10:49 ` [tip:perf/core] perf: Export perf_assign_events() tip-bot for Yan, Zheng
2012-06-15 6:31 ` [PATCH V6 02/13] perf: Avoid race between cpu hotplug and installing event Yan, Zheng
2012-06-20 10:50 ` [tip:perf/core] " tip-bot for Yan, Zheng
2012-06-15 6:31 ` [PATCH V6 03/13] perf: Allow pmu to choose cpu on which to install event Yan, Zheng
2012-06-20 10:51 ` [tip:perf/core] perf: Allow the PMU driver to choose the CPU on which to install events tip-bot for Yan, Zheng
2012-06-15 6:31 ` [PATCH V6 04/13] perf: Introduce perf_pmu_migrate_context Yan, Zheng
2012-06-20 10:52 ` [tip:perf/core] perf: Introduce perf_pmu_migrate_context() tip-bot for Yan, Zheng
2012-06-15 6:31 ` [PATCH V6 05/13] perf: Generic intel uncore support Yan, Zheng
2012-06-20 10:54 ` [tip:perf/core] perf/x86: Add generic Intel uncore PMU support tip-bot for Yan, Zheng
2012-06-21 22:43 ` Andrew Morton
2012-06-21 22:46 ` Andrew Morton
2012-06-21 22:47 ` H. Peter Anvin
2012-06-21 22:51 ` Andrew Morton
2012-06-21 23:10 ` H. Peter Anvin
2012-06-21 23:15 ` Andrew Morton
2012-06-21 23:18 ` Andrew Morton
2012-06-21 23:22 ` H. Peter Anvin
2012-06-21 23:29 ` Andrew Morton
2012-06-22 8:05 ` Peter Zijlstra
2012-07-24 3:27 ` [PATCH V6 05/13] perf: Generic intel uncore support Stephane Eranian
2012-07-24 6:00 ` Yan, Zheng
2012-07-24 6:21 ` Stephane Eranian
2012-06-15 6:31 ` [PATCH V6 06/13] perf: Add Nehalem and Sandy Bridge " Yan, Zheng
2012-06-15 15:28 ` Peter Zijlstra
2012-06-15 16:31 ` Peter Zijlstra
2012-06-15 18:43 ` Andi Kleen
2012-06-15 17:18 ` Peter Zijlstra
2012-06-15 18:46 ` Stephane Eranian
2012-06-16 12:46 ` Peter Zijlstra
2012-06-16 12:52 ` Peter Zijlstra
2012-06-18 9:23 ` Stephane Eranian
2012-06-19 1:39 ` Yan, Zheng
2012-06-15 17:29 ` Peter Zijlstra
2012-06-15 18:47 ` Stephane Eranian
2012-06-16 12:46 ` Peter Zijlstra
2012-06-20 10:55 ` [tip:perf/core] perf/x86: Add Intel Nehalem and Sandy Bridge uncore PMU support tip-bot for Yan, Zheng
2012-06-15 6:31 ` [PATCH V6 07/13] perf: Generic pci uncore device support Yan, Zheng
2012-06-15 16:02 ` Peter Zijlstra
2012-06-18 3:06 ` Yan, Zheng
2012-06-18 7:43 ` Peter Zijlstra
2012-06-20 10:56 ` [tip:perf/core] perf: Add generic PCI uncore PMU " tip-bot for Yan, Zheng
2012-06-20 16:39 ` [PATCH] perf, x86: Fix section mismatch in uncore_pci_init() Robert Richter
2012-06-25 11:40 ` [tip:perf/core] perf/x86: Fix section mismatch in uncore_pci_init( ) tip-bot for Robert Richter
2012-08-13 17:10 ` [tip:perf/urgent] perf, x86: Fix uncore_types_exit section mismatch tip-bot for Borislav Petkov
2012-06-15 6:31 ` [PATCH V6 08/13] perf: Add Sandy Bridge-EP uncore support Yan, Zheng
2012-06-15 17:10 ` Peter Zijlstra
2012-06-18 1:47 ` Yan, Zheng
2012-06-18 7:42 ` Peter Zijlstra
2012-06-18 15:28 ` Stephane Eranian
2012-06-19 0:59 ` Yan, Zheng
2012-06-19 7:18 ` Stephane Eranian
2012-06-19 8:17 ` Yan, Zheng
2012-06-20 10:56 ` [tip:perf/core] perf/x86: Add Intel Nehalem and " tip-bot for Yan, Zheng
2012-07-22 19:37 ` [PATCH V6 08/13] perf: Add " Stephane Eranian
2012-06-15 6:31 ` [PATCH V6 09/13] perf, tool: Use data struct for arg passing in event parse function Yan, Zheng
2012-06-20 10:57 ` [tip:perf/core] perf/tool: " tip-bot for Jiri Olsa
2012-06-15 6:31 ` [PATCH V6 10/13] perf, tool: Make the event parser reentrantable Yan, Zheng
2012-06-20 10:58 ` [tip:perf/core] perf/tool: Make the event parser re-entrant tip-bot for Zheng Yan
2012-06-15 6:31 ` [PATCH V6 11/13] perf, tool: Add support to reuse event grammar to parse out terms Yan, Zheng
2012-06-20 10:59 ` [tip:perf/core] perf/tool: " tip-bot for Jiri Olsa
2012-06-15 6:31 ` [PATCH V6 12/13] perf, tool: Add pmu event alias support Yan, Zheng
2012-06-20 11:00 ` tip-bot for Zheng Yan [this message]
2012-06-15 6:31 ` [PATCH V6 13/13] perf, tool: Add automated test for pure terms parsing Yan, Zheng
2012-06-20 11:01 ` [tip:perf/core] perf/tool: " tip-bot for Jiri Olsa
2012-06-20 16:01 ` [PATCH V6 0/13] perf: Intel uncore pmu counting support Peter Zijlstra
2012-06-21 2:34 ` Yan, Zheng
2012-06-21 8:10 ` Stephane Eranian
2012-06-21 8:43 ` Yan, Zheng
2012-06-21 9:13 ` Stephane Eranian
2012-06-21 11:40 ` Peter Zijlstra
2012-06-21 11:48 ` Stephane Eranian
2012-06-21 13:08 ` 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=tip-a6146d5040cce560f700221158d77dd335eed332@git.kernel.org \
--to=zheng.z.yan@intel.com \
--cc=a.p.zijlstra@chello.nl \
--cc=akpm@linux-foundation.org \
--cc=hpa@zytor.com \
--cc=jolsa@redhat.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-tip-commits@vger.kernel.org \
--cc=mingo@kernel.org \
--cc=tglx@linutronix.de \
--cc=torvalds@linux-foundation.org \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Powered by JetHome