Skip to contentSkip to conversation

perf/core improvements and fixes

GIT PULL New Arnaldo Carvalho de Melo 2 participants 15 messages Jul 20, 2015 – Jul 21, 2015

Subsystems (2)
lore
Share & tools
lore

Arnaldo Carvalho de Melo

author maintainer
#0 lore raw

Hi Ingo,

Please consider pulling,

- Arnaldo

The following changes since commit 60cd37eb100c4880b28078a47f3062fac7572095:

Merge tag 'perf-core-for-mingo' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core (2015-07-06 17:46:15 +0200)

are available in the git repository at:

git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux.git tags/perf-core-for-mingo

for you to fetch changes up to d2f3f5d2e9cae6e73f9642a5ddc8c8a07c35e79b:

perf bench futex: Add lock_pi stresser (2015-07-20 17:49:51 -0300)

----------------------------------------------------------------
perf/core improvements and fixes:

New features:

- Allow filtering perf's pid via 'perf record --exclude-perf' (Wang Nan)

- 'perf trace' now supports syscall groups, like strace, i.e:

    $ trace -e file touch file

Will expand 'file' into multiple, file related, syscalls. More work needed to add extra groups for other syscall groups, and also to complement what was added for the 'file' group, included as a proof of concept. (Arnaldo Carvalho de Melo)

- Add lock_pi stresser to 'perf bench futex', to test the kernel code related to FUTEX_(UN)LOCK_PI (Davidlohr Bueso)

User visible fixes:

- Apply --filter to all events in a glob matching, not just the last one (Wang Nan)

Documentation:

- Document setting '-e pmu/period=N/' in the 'perf record' man page (Kan Liang)

Infrastructure:

- 'perf probe' code simplifications and movements to separate files (Masami Hiramatsu)

- Fix makefile generation under 'dash' (Sergei Trofimovich)

----------------------------------------------------------------
Arnaldo Carvalho de Melo (5):
perf strlist: load() should return a negative errno
perf strlist: Make dupstr be the default and part of an extensible config parm perf strlist: Allow substitutions from file contents in a given directory perf strlist: Make parse_list() private
perf trace: Support 'strace' syscall event groups

Davidlohr Bueso (1):
perf bench futex: Add lock_pi stresser

Kan Liang (1):
perf record: Document setting '-e pmu/period=N/' in man page

Masami Hiramatsu (3):
perf probe: Simplify __add_probe_trace_events code perf probe: Move ftrace probe-event operations to probe-file.c perf buildid: Use SBUILD_ID_SIZE macro

Sergei Trofimovich (1):
perf tools: Fix makefile generation under dash

Wang Nan (2):
perf record: Apply filter to all events in a glob matching perf record: Allow filtering perf's pid via --exclude-perf

 tools/perf/Build                         |   1 +
 tools/perf/Documentation/perf-bench.txt  |   4 +
 tools/perf/Documentation/perf-record.txt |  19 +-
 tools/perf/Makefile.perf                 |   5 +
 tools/perf/bench/Build                   |   1 +
 tools/perf/bench/bench.h                 |   2 +
 tools/perf/bench/futex-lock-pi.c         | 219 +++++++++++++++++
 tools/perf/bench/futex.h                 |  20 ++
 tools/perf/builtin-bench.c               |   2 +
 tools/perf/builtin-buildid-cache.c       |  16 +-
 tools/perf/builtin-buildid-list.c        |   4 +-
 tools/perf/builtin-record.c              |   3 +
 tools/perf/builtin-trace.c               |   6 +-
 tools/perf/config/Makefile               |   8 +-
 tools/perf/trace/strace/groups/file      |  18 ++
 tools/perf/util/Build                    |   1 +
 tools/perf/util/build-id.c               |   6 +-
 tools/perf/util/build-id.h               |   3 +-
 tools/perf/util/evsel.c                  |   1 +
 tools/perf/util/evsel.h                  |   1 +
 tools/perf/util/machine.c                |   2 +-
 tools/perf/util/parse-events.c           |  81 ++++++-
 tools/perf/util/parse-events.h           |   1 +
 tools/perf/util/probe-event.c            | 388 ++++++-------------------------
 tools/perf/util/probe-event.h            |   7 +
 tools/perf/util/probe-file.c             | 301 ++++++++++++++++++++++++
 tools/perf/util/probe-file.h             |  18 ++
 tools/perf/util/probe-finder.c           |   2 +-
 tools/perf/util/strlist.c                |  43 +++-
 tools/perf/util/strlist.h                |   9 +-
 tools/perf/util/symbol.c                 |   2 +-
 tools/perf/util/thread_map.c             |   6 +-
 32 files changed, 842 insertions(+), 358 deletions(-)
 create mode 100644 tools/perf/bench/futex-lock-pi.c
 create mode 100644 tools/perf/trace/strace/groups/file
 create mode 100644 tools/perf/util/probe-file.c
 create mode 100644 tools/perf/util/probe-file.h
author maintainer
#1 lore raw

PATCH 1/13 perf record: Document setting '-e pmu/period=N/' in man page

From: Kan Liang <[email protected]>

The 'period' param is not defined in /sys/bus/event_sources/devices/<pmu>/format/*, but can be used, document it.

---
 tools/perf/Documentation/perf-record.txt | 8 ++++++++
 1 file changed, 8 insertions(+)
tools/perf/Documentation/perf-record.txt +8 -0
index 9b9d9d086680..5b47b2c88223 100644
@@ -45,6 +45,14 @@ OPTIONS
           param1 and param2 are defined as formats for the PMU in:
           /sys/bus/event_sources/devices/<pmu>/format/*
 
+	  There are also some params which are not defined in .../<pmu>/format/*.
+	  These params can be used to set event defaults.
+	  Here is a list of the params.
+	  - 'period': Set event sampling period
+
+	  Note: If user explicitly sets options which conflict with the params,
+	  the value set by the params will be overridden.
+
         - a hardware breakpoint event in the form of '\mem:addr[/len][:access]'
           where addr is the address in memory you want to break in.
           Access is the memory access type (read, write, execute) it can
Signature · 1 line
2.1.0
author maintainer
#2 lore raw

PATCH 2/13 perf strlist: load() should return a negative errno

In reply to Arnaldo Carvalho de Melo

From: Arnaldo Carvalho de Melo <[email protected]>

To match what its users return.

Cc Adrian Hunter <[email protected]>
Cc Borislav Petkov <[email protected]>
Cc David Ahern <[email protected]>
Cc Frederic Weisbecker <[email protected]>
Cc Jiri Olsa <[email protected]>
Cc Namhyung Kim <[email protected]>
Cc Stephane Eranian <[email protected]>
---
 tools/perf/util/strlist.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
tools/perf/util/strlist.c +1 -1
index 71f9d102b96f..68ae673f9fb6 100644
@@ -72,7 +72,7 @@ int strlist__load(struct strlist *slist, const char *filename)
 	FILE *fp = fopen(filename, "r");
 
 	if (fp == NULL)
-		return errno;
+		return -errno;
 
 	while (fgets(entry, sizeof(entry), fp) != NULL) {
 		const size_t len = strlen(entry);
Signature · 1 line
2.1.0
author maintainer
#3 lore raw

PATCH 3/13 perf strlist: Make dupstr be the default and part of an extensible config parm

In reply to Arnaldo Carvalho de Melo

From: Arnaldo Carvalho de Melo <[email protected]>

So that we can pass more info to strlist__new() without having to change its function signature, just adding entries to the strlist_config struct with sensible defaults for when those fields are not specified.

Cc Adrian Hunter <[email protected]>
Cc Borislav Petkov <[email protected]>
Cc David Ahern <[email protected]>
Cc Frederic Weisbecker <[email protected]>
Cc Jiri Olsa <[email protected]>
Cc Namhyung Kim <[email protected]>
Cc Stephane Eranian <[email protected]>
---
 tools/perf/builtin-buildid-cache.c | 8 ++++----
 tools/perf/builtin-trace.c         | 2 +-
 tools/perf/util/build-id.c         | 2 +-
 tools/perf/util/machine.c          | 2 +-
 tools/perf/util/probe-event.c      | 4 ++--
 tools/perf/util/probe-finder.c     | 2 +-
 tools/perf/util/strlist.c          | 4 ++--
 tools/perf/util/strlist.h          | 6 +++++-
 tools/perf/util/symbol.c           | 2 +-
 tools/perf/util/thread_map.c       | 6 ++++--
 10 files changed, 22 insertions(+), 16 deletions(-)
tools/perf/builtin-buildid-cache.c +4 -4
index d47a0cdc71c9..ddca990bcc00 100644
@@ -363,7 +363,7 @@ int cmd_buildid_cache(int argc, const char **argv,
 	setup_pager();
 
 	if (add_name_list_str) {
-		list = strlist__new(true, add_name_list_str);
+		list = strlist__new(add_name_list_str, NULL);
 		if (list) {
 			strlist__for_each(pos, list)
 				if (build_id_cache__add_file(pos->s)) {
@@ -381,7 +381,7 @@ int cmd_buildid_cache(int argc, const char **argv,
 	}
 
 	if (remove_name_list_str) {
-		list = strlist__new(true, remove_name_list_str);
+		list = strlist__new(remove_name_list_str, NULL);
 		if (list) {
 			strlist__for_each(pos, list)
 				if (build_id_cache__remove_file(pos->s)) {
@@ -399,7 +399,7 @@ int cmd_buildid_cache(int argc, const char **argv,
 	}
 
 	if (purge_name_list_str) {
-		list = strlist__new(true, purge_name_list_str);
+		list = strlist__new(purge_name_list_str, NULL);
 		if (list) {
 			strlist__for_each(pos, list)
 				if (build_id_cache__purge_path(pos->s)) {
@@ -420,7 +420,7 @@ int cmd_buildid_cache(int argc, const char **argv,
 		ret = build_id_cache__fprintf_missing(session, stdout);
 
 	if (update_name_list_str) {
-		list = strlist__new(true, update_name_list_str);
+		list = strlist__new(update_name_list_str, NULL);
 		if (list) {
 			strlist__for_each(pos, list)
 				if (build_id_cache__update_file(pos->s)) {
tools/perf/builtin-trace.c +1 -1
index 0ebf55bf20b3..3a3173c186c0 100644
@@ -2931,7 +2931,7 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused)
 		trace.not_ev_qualifier = *s == '!';
 		if (trace.not_ev_qualifier)
 			++s;
-		trace.ev_qualifier = strlist__new(true, s);
+		trace.ev_qualifier = strlist__new(s, NULL);
 		if (trace.ev_qualifier == NULL) {
 			fputs("Not enough memory to parse event qualifier",
 			      trace.output);
tools/perf/util/build-id.c +1 -1
index 1f6fc2323ef9..f98c2ffafba7 100644
@@ -291,7 +291,7 @@ int build_id_cache__list_build_ids(const char *pathname,
 	struct dirent *d;
 	int ret = 0;
 
-	list = strlist__new(true, NULL);
+	list = strlist__new(NULL, NULL);
 	dir_name = build_id_cache__dirname_from_path(pathname, false, false);
 	if (!list || !dir_name) {
 		ret = -ENOMEM;
tools/perf/util/machine.c +1 -1
index 7ff682770fdb..d0bf1e590479 100644
@@ -250,7 +250,7 @@ struct machine *machines__findnew(struct machines *machines, pid_t pid)
 			static struct strlist *seen;
 
 			if (!seen)
-				seen = strlist__new(true, NULL);
+				seen = strlist__new(NULL, NULL);
 
 			if (!strlist__has_entry(seen, path)) {
 				pr_err("Can't access file %s\n", path);
tools/perf/util/probe-event.c +2 -2
index 381f23a443c7..7abaac4ec866 100644
@@ -2066,7 +2066,7 @@ static struct strlist *get_probe_trace_command_rawlist(int fd)
 	char *p;
 	struct strlist *sl;
 
-	sl = strlist__new(true, NULL);
+	sl = strlist__new(NULL, NULL);
 
 	fp = fdopen(dup(fd), "r");
 	while (!feof(fp)) {
@@ -2362,7 +2362,7 @@ static struct strlist *get_probe_trace_event_names(int fd, bool include_group)
 	rawlist = get_probe_trace_command_rawlist(fd);
 	if (!rawlist)
 		return NULL;
-	sl = strlist__new(true, NULL);
+	sl = strlist__new(NULL, NULL);
 	strlist__for_each(ent, rawlist) {
 		ret = parse_probe_trace_command(ent->s, &tev);
 		if (ret < 0)
tools/perf/util/probe-finder.c +1 -1
index 2da65a710893..7b80f8cb62b9 100644
@@ -1355,7 +1355,7 @@ static int add_available_vars(Dwarf_Die *sc_die, struct probe_finder *pf)
 		 vl->point.offset);
 
 	/* Find local variables */
-	vl->vars = strlist__new(true, NULL);
+	vl->vars = strlist__new(NULL, NULL);
 	if (vl->vars == NULL)
 		return -ENOMEM;
 	af->child = true;
tools/perf/util/strlist.c +2 -2
index 68ae673f9fb6..dd403850dfab 100644
@@ -133,7 +133,7 @@ int strlist__parse_list(struct strlist *slist, const char *s)
 	return *s ? strlist__parse_list_entry(slist, s) : 0;
 }
 
-struct strlist *strlist__new(bool dupstr, const char *list)
+struct strlist *strlist__new(const char *list, const struct strlist_config *config)
 {
 	struct strlist *slist = malloc(sizeof(*slist));
 
@@ -143,7 +143,7 @@ struct strlist *strlist__new(bool dupstr, const char *list)
 		slist->rblist.node_new    = strlist__node_new;
 		slist->rblist.node_delete = strlist__node_delete;
 
-		slist->dupstr	 = dupstr;
+		slist->dupstr	 = config ? !config->dont_dupstr : true;
 		if (list && strlist__parse_list(slist, list) != 0)
 			goto out_error;
 	}
tools/perf/util/strlist.h +5 -1
index 5c7f87069d9c..a182785d9428 100644
@@ -16,7 +16,11 @@ struct strlist {
 	bool	       dupstr;
 };
 
-struct strlist *strlist__new(bool dupstr, const char *slist);
+struct strlist_config {
+	bool dont_dupstr;
+};
+
+struct strlist *strlist__new(const char *slist, const struct strlist_config *config);
 void strlist__delete(struct strlist *slist);
 
 void strlist__remove(struct strlist *slist, struct str_node *sn);
tools/perf/util/symbol.c +1 -1
index 48b588c6951a..db39388188bf 100644
@@ -1906,7 +1906,7 @@ int setup_list(struct strlist **list, const char *list_str,
 	if (list_str == NULL)
 		return 0;
 
-	*list = strlist__new(true, list_str);
+	*list = strlist__new(list_str, NULL);
 	if (!*list) {
 		pr_err("problems parsing %s list\n", list_name);
 		return -1;
tools/perf/util/thread_map.c +4 -2
index da7646d767fe..d526dea80128 100644
@@ -196,7 +196,8 @@ static struct thread_map *thread_map__new_by_pid_str(const char *pid_str)
 	pid_t pid, prev_pid = INT_MAX;
 	char *end_ptr;
 	struct str_node *pos;
-	struct strlist *slist = strlist__new(false, pid_str);
+	struct strlist_config slist_config = { .dont_dupstr = true, };
+	struct strlist *slist = strlist__new(pid_str, &slist_config);
 
 	if (!slist)
 		return NULL;
@@ -266,13 +267,14 @@ static struct thread_map *thread_map__new_by_tid_str(const char *tid_str)
 	pid_t tid, prev_tid = INT_MAX;
 	char *end_ptr;
 	struct str_node *pos;
+	struct strlist_config slist_config = { .dont_dupstr = true, };
 	struct strlist *slist;
 
 	/* perf-stat expects threads to be generated even if tid not given */
 	if (!tid_str)
 		return thread_map__new_dummy();
 
-	slist = strlist__new(false, tid_str);
+	slist = strlist__new(tid_str, &slist_config);
 	if (!slist)
 		return NULL;
 
Signature · 1 line
2.1.0
author maintainer
#4 lore raw

PATCH 4/13 perf strlist: Allow substitutions from file contents in a given directory

In reply to Arnaldo Carvalho de Melo

From: Arnaldo Carvalho de Melo <[email protected]>

So, if we have an strlist equal to:

"file,close"

And we call it as:

   struct strlist_config *config = { .dirname = "~/strace/groups", };
   struct strlist *slist = strlist__new("file, close", &config);

And we have:

  $ cat ~/strace/groups/file
  access
  open
  openat
  statfs

Then the resulting strlist will have these contents:

[ "access", "open", "openat", "statfs", "close" ]

This will be used to implement strace syscall groups in 'perf trace', but can be used in some other tool, thus being implemented in 'strlist'.

Cc Adrian Hunter <[email protected]>
Cc Borislav Petkov <[email protected]>
Cc David Ahern <[email protected]>
Cc Frederic Weisbecker <[email protected]>
Cc Jiri Olsa <[email protected]>
Cc Namhyung Kim <[email protected]>
Cc Stephane Eranian <[email protected]>
---
 tools/perf/util/strlist.c | 41 ++++++++++++++++++++++++++++++++++-------
 tools/perf/util/strlist.h |  3 ++-
 2 files changed, 36 insertions(+), 8 deletions(-)
tools/perf/util/strlist.c +34 -7
index dd403850dfab..7abc75a0abf3 100644
@@ -108,29 +108,47 @@ struct str_node *strlist__find(struct strlist *slist, const char *entry)
 	return snode;
 }
 
-static int strlist__parse_list_entry(struct strlist *slist, const char *s)
+static int strlist__parse_list_entry(struct strlist *slist, const char *s,
+				     const char *subst_dir)
 {
+	int err;
+	char *subst = NULL;
+
 	if (strncmp(s, "file://", 7) == 0)
 		return strlist__load(slist, s + 7);
 
-	return strlist__add(slist, s);
+	if (subst_dir) {
+		err = -ENOMEM;
+		if (asprintf(&subst, "%s/%s", subst_dir, s) < 0)
+			goto out;
+
+		if (access(subst, F_OK) == 0) {
+			err = strlist__load(slist, subst);
+			goto out;
+		}
+	}
+
+	err = strlist__add(slist, s);
+out:
+	free(subst);
+	return err;
 }
 
-int strlist__parse_list(struct strlist *slist, const char *s)
+int strlist__parse_list(struct strlist *slist, const char *s, const char *subst_dir)
 {
 	char *sep;
 	int err;
 
 	while ((sep = strchr(s, ',')) != NULL) {
 		*sep = '\0';
-		err = strlist__parse_list_entry(slist, s);
+		err = strlist__parse_list_entry(slist, s, subst_dir);
 		*sep = ',';
 		if (err != 0)
 			return err;
 		s = sep + 1;
 	}
 
-	return *s ? strlist__parse_list_entry(slist, s) : 0;
+	return *s ? strlist__parse_list_entry(slist, s, subst_dir) : 0;
 }
 
 struct strlist *strlist__new(const char *list, const struct strlist_config *config)
@@ -138,13 +156,22 @@ struct strlist *strlist__new(const char *list, const struct strlist_config *conf
 	struct strlist *slist = malloc(sizeof(*slist));
 
 	if (slist != NULL) {
+		bool dupstr = true;
+		const char *dirname = NULL;
+
+		if (config) {
+			dupstr = !config->dont_dupstr;
+			dirname = config->dirname;
+		}
+
 		rblist__init(&slist->rblist);
 		slist->rblist.node_cmp    = strlist__node_cmp;
 		slist->rblist.node_new    = strlist__node_new;
 		slist->rblist.node_delete = strlist__node_delete;
 
-		slist->dupstr	 = config ? !config->dont_dupstr : true;
-		if (list && strlist__parse_list(slist, list) != 0)
+		slist->dupstr	 = dupstr;
+
+		if (list && strlist__parse_list(slist, list, dirname) != 0)
 			goto out_error;
 	}
 
tools/perf/util/strlist.h +2 -1
index a182785d9428..9bb9823268b8 100644
@@ -18,6 +18,7 @@ struct strlist {
 
 struct strlist_config {
 	bool dont_dupstr;
+	const char *dirname;
 };
 
 struct strlist *strlist__new(const char *slist, const struct strlist_config *config);
@@ -79,5 +80,5 @@ static inline struct str_node *strlist__next(struct str_node *sn)
 	for (pos = strlist__first(slist), n = strlist__next(pos); pos;\
 	     pos = n, n = strlist__next(n))
 
-int strlist__parse_list(struct strlist *slist, const char *s);
+int strlist__parse_list(struct strlist *slist, const char *s, const char *subst_dir);
 #endif /* __PERF_STRLIST_H */
Signature · 1 line
2.1.0
author maintainer
#5 lore raw

PATCH 5/13 perf strlist: Make parse_list() private

In reply to Arnaldo Carvalho de Melo

From: Arnaldo Carvalho de Melo <[email protected]>

It is not used anywhere, expose it when/if needed.

Cc Adrian Hunter <[email protected]>
Cc Borislav Petkov <[email protected]>
Cc David Ahern <[email protected]>
Cc Frederic Weisbecker <[email protected]>
Cc Jiri Olsa <[email protected]>
Cc Namhyung Kim <[email protected]>
Cc Stephane Eranian <[email protected]>
---
 tools/perf/util/strlist.c | 2 +-
 tools/perf/util/strlist.h | 2 --
 2 files changed, 1 insertion(+), 3 deletions(-)
tools/perf/util/strlist.c +1 -1
index 7abc75a0abf3..bdf98f6f27bb 100644
@@ -134,7 +134,7 @@ out:
 	return err;
 }
 
-int strlist__parse_list(struct strlist *slist, const char *s, const char *subst_dir)
+static int strlist__parse_list(struct strlist *slist, const char *s, const char *subst_dir)
 {
 	char *sep;
 	int err;
tools/perf/util/strlist.h +0 -2
index 9bb9823268b8..297565aa7535 100644
@@ -79,6 +79,4 @@ static inline struct str_node *strlist__next(struct str_node *sn)
 #define strlist__for_each_safe(pos, n, slist)	\
 	for (pos = strlist__first(slist), n = strlist__next(pos); pos;\
 	     pos = n, n = strlist__next(n))
-
-int strlist__parse_list(struct strlist *slist, const char *s, const char *subst_dir);
 #endif /* __PERF_STRLIST_H */
Signature · 1 line
2.1.0
author maintainer
#6 lore raw

PATCH 6/13 perf trace: Support 'strace' syscall event groups

In reply to Arnaldo Carvalho de Melo

From: Arnaldo Carvalho de Melo <[email protected]>

I.e.:

  $ cat ~/share/perf-core/strace/groups/file
  access
  chmod
  creat
  execve
  faccessat
  getcwd
  lstat
  mkdir
  open
  openat
  quotactl
  readlink
  rename
  rmdir
  stat
  statfs
  symlink
  unlink
  $

Then, on a quiet desktop, try running this and then moving your mouse to see the deluge of mouse related activity:

  # perf probe 'vfs_getname=getname_flags:72 pathname=filename:string'
  Added new event:
    probe:vfs_getname    (on getname_flags:72 with pathname=filename:string)

You can now use it in all perf tools, such as:

perf record -e probe:vfs_getname -aR sleep 1
#

  # trace --ev probe:vfs_getname --filter-pids 2232 -e file
   0.042 (0.042 ms): mousetweaks/2235 open(filename: 0x14e3910, mode: 438                                   ) ...
   0.042 (        ): probe:vfs_getname:(ffffffff812230bc) pathname="/home/acme/.icons/Adwaita/cursors/xterm")
   0.100 (0.100 ms): mousetweaks/2235  ... [continued]: open()) = -1 ENOENT No such file or directory
   0.142 (0.018 ms): mousetweaks/2235 open(filename: 0x14c3c10, mode: 438                                   ) ...
   0.142 (        ): probe:vfs_getname:(ffffffff812230bc) pathname="/home/acme/.icons/Adwaita/index.theme")
   0.192 (0.069 ms): mousetweaks/2235  ... [continued]: open()) = -1 ENOENT No such file or directory
   0.230 (0.017 ms): mousetweaks/2235 open(filename: 0x14c3c10, mode: 438                                   ) ...
   0.230 (        ): probe:vfs_getname:(ffffffff812230bc) pathname="/usr/share/icons/Adwaita/cursors/xterm")
   0.253 (0.041 ms): mousetweaks/2235  ... [continued]: open()) = 14
   0.459 (0.008 ms): mousetweaks/2235 open(filename: 0x14e3910, mode: 438                                   ) ...
   0.459 (        ): probe:vfs_getname:(ffffffff812230bc) pathname="/home/acme/.icons/Adwaita/cursors/left_side")
   0.468 (0.017 ms): mousetweaks/2235  ... [continued]: open()) = -1 ENOENT No such file or directory

Need to combine that raw_syscalls:sys_enter(open) + probe:vfs_getname + raw_syscalls:sys_exit(open) sequence...

Now, if you're bored, please write some more syscall groups, like the ones in 'strace' and send it our way :-)

Cc Adrian Hunter <[email protected]>
Cc Borislav Petkov <[email protected]>
Cc David Ahern <[email protected]>
Cc Frederic Weisbecker <[email protected]>
Cc Jiri Olsa <[email protected]>
Cc Milian Wolff <[email protected]>
Cc Namhyung Kim <[email protected]>
Cc Stephane Eranian <[email protected]>
---
 tools/perf/Build                    |  1 +
 tools/perf/Makefile.perf            |  5 +++++
 tools/perf/builtin-trace.c          |  6 +++++-
 tools/perf/config/Makefile          |  6 ++++++
 tools/perf/trace/strace/groups/file | 18 ++++++++++++++++++
 5 files changed, 35 insertions(+), 1 deletion(-)
 create mode 100644 tools/perf/trace/strace/groups/file
tools/perf/Build +1 -0
index b77370ef7005..72237455b400 100644
@@ -35,6 +35,7 @@ paths += -DPERF_MAN_PATH="BUILD_STR($(mandir_SQ))"
 CFLAGS_builtin-help.o      += $(paths)
 CFLAGS_builtin-timechart.o += $(paths)
 CFLAGS_perf.o              += -DPERF_HTML_PATH="BUILD_STR($(htmldir_SQ))" -include $(OUTPUT)PERF-VERSION-FILE
+CFLAGS_builtin-trace.o	   += -DSTRACE_GROUPS_DIR="BUILD_STR($(STRACE_GROUPS_DIR_SQ))"
 
 libperf-y += util/
 libperf-y += arch/
tools/perf/Makefile.perf +5 -0
index 7a4b549214e3..04170fc65861 100644
@@ -494,6 +494,11 @@ endif
 		$(INSTALL) $(OUTPUT)perf-archive -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)'
 	$(call QUIET_INSTALL, perf-with-kcore) \
 		$(INSTALL) $(OUTPUT)perf-with-kcore -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)'
+ifndef NO_LIBAUDIT
+	$(call QUIET_INSTALL, strace/groups) \
+		$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(STRACE_GROUPS_INSTDIR_SQ)'; \
+		$(INSTALL) trace/strace/groups/* -t '$(DESTDIR_SQ)$(STRACE_GROUPS_INSTDIR_SQ)'
+endif
 ifndef NO_LIBPERL
 	$(call QUIET_INSTALL, perl-scripts) \
 		$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/Perf-Trace-Util/lib/Perf/Trace'; \
tools/perf/builtin-trace.c +5 -1
index 3a3173c186c0..32b4d280af4f 100644
@@ -3,6 +3,7 @@
 #include "util/color.h"
 #include "util/debug.h"
 #include "util/evlist.h"
+#include "util/exec_cmd.h"
 #include "util/machine.h"
 #include "util/session.h"
 #include "util/thread.h"
@@ -2927,11 +2928,14 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused)
 
 	if (ev_qualifier_str != NULL) {
 		const char *s = ev_qualifier_str;
+		struct strlist_config slist_config = {
+			.dirname = system_path(STRACE_GROUPS_DIR),
+		};
 
 		trace.not_ev_qualifier = *s == '!';
 		if (trace.not_ev_qualifier)
 			++s;
-		trace.ev_qualifier = strlist__new(s, NULL);
+		trace.ev_qualifier = strlist__new(s, &slist_config);
 		if (trace.ev_qualifier == NULL) {
 			fputs("Not enough memory to parse event qualifier",
 			      trace.output);
tools/perf/config/Makefile +6 -0
index 094ddaee104c..a9b93d1ecefa 100644
@@ -644,6 +644,7 @@ infodir = share/info
 perfexecdir = libexec/perf-core
 sharedir = $(prefix)/share
 template_dir = share/perf-core/templates
+STRACE_GROUPS_DIR = share/perf-core/strace/groups
 htmldir = share/doc/perf-doc
 ifeq ($(prefix),/usr)
 sysconfdir = /etc
@@ -663,6 +664,7 @@ libdir = $(prefix)/$(lib)
 
 # Shell quote (do not use $(call) to accommodate ancient setups);
 ETC_PERFCONFIG_SQ = $(subst ','\'',$(ETC_PERFCONFIG))
+STRACE_GROUPS_DIR_SQ = $(subst ','\'',$(STRACE_GROUPS_DIR))
 DESTDIR_SQ = $(subst ','\'',$(DESTDIR))
 bindir_SQ = $(subst ','\'',$(bindir))
 mandir_SQ = $(subst ','\'',$(mandir))
@@ -676,10 +678,13 @@ libdir_SQ = $(subst ','\'',$(libdir))
 
 ifneq ($(filter /%,$(firstword $(perfexecdir))),)
 perfexec_instdir = $(perfexecdir)
+STRACE_GROUPS_INSTDIR = $(STRACE_GROUPS_DIR)
 else
 perfexec_instdir = $(prefix)/$(perfexecdir)
+STRACE_GROUPS_INSTDIR = $(prefix)/$(STRACE_GROUPS_DIR)
 endif
 perfexec_instdir_SQ = $(subst ','\'',$(perfexec_instdir))
+STRACE_GROUPS_INSTDIR_SQ = $(subst ','\'',$(STRACE_GROUPS_INSTDIR))
 
 # If we install to $(HOME) we keep the traceevent default:
 # $(HOME)/.traceevent/plugins
@@ -713,6 +718,7 @@ $(call detected_var,htmldir_SQ)
 $(call detected_var,infodir_SQ)
 $(call detected_var,mandir_SQ)
 $(call detected_var,ETC_PERFCONFIG_SQ)
+$(call detected_var,STRACE_GROUPS_DIR_SQ)
 $(call detected_var,prefix_SQ)
 $(call detected_var,perfexecdir_SQ)
 $(call detected_var,LIBDIR)
tools/perf/trace/strace/groups/file new file +18 -0
new file mode 100644
index 000000000000..62378a899d79
@@ -0,0 +1,18 @@
+access
+chmod
+creat
+execve
+faccessat
+getcwd
+lstat
+mkdir
+open
+openat
+quotactl
+readlink
+rename
+rmdir
+stat
+statfs
+symlink
+unlink
Signature · 1 line
2.1.0
author maintainer
#7 lore raw

PATCH 7/13 perf record: Apply filter to all events in a glob matching

In reply to Arnaldo Carvalho de Melo

From: Wang Nan <[email protected]>

There is an old problem in perf's filter applying which first posted at Sep. 2014 at https://lkml.org/lkml/2014/9/9/944 that, if passing multiple events in a glob matching expression in cmdline then add '--filter' after them, the filter will be applied on only the last one.

For example:

 # dd if=/dev/zero of=/dev/null &
 [1] 464
 # perf record -a -e 'syscalls:sys_*_read' --filter 'common_pid != 464' sleep 0.1
 [ perf record: Woken up 1 times to write data ]
 [ perf record: Captured and wrote 0.239 MB perf.data (2094 samples) ]
 # perf report --stdio | tee
 ...
 # Samples: 2K of event 'syscalls:sys_enter_read'
 # Event count (approx.): 2092
 ...
 # Samples: 2  of event 'syscalls:sys_exit_read'
 # Event count (approx.): 2
 ...

In this example, filter only applied on 'syscalls:sys_exit_read', and there's no way to set filter for ''syscalls:sys_enter_read'.

This patch adds a 'cmdline_group_boundary' for 'struct evsel', and apply filter on all events between two boundary marks.

After applying this patch:

 # perf record -a -e 'syscalls:sys_*_read' --filter 'common_pid != 464' sleep 0.1
 [ perf record: Woken up 1 times to write data ]
 [ perf record: Captured and wrote 0.031 MB perf.data (3 samples) ]
 # perf report --stdio | tee
 ...
 # Samples: 1  of event 'syscalls:sys_enter_read'
 # Event count (approx.): 1
 ...
 # Samples: 2  of event 'syscalls:sys_exit_read'
 # Event count (approx.): 2
 ...
---
 tools/perf/util/evsel.c        |  1 +
 tools/perf/util/evsel.h        |  1 +
 tools/perf/util/parse-events.c | 30 +++++++++++++++++++++---------
 3 files changed, 23 insertions(+), 9 deletions(-)
tools/perf/util/evsel.c +1 -0
index 83c08037e7e2..49fb7b5feb09 100644
@@ -210,6 +210,7 @@ void perf_evsel__init(struct perf_evsel *evsel,
 	perf_evsel__object.init(evsel);
 	evsel->sample_size = __perf_evsel__sample_size(attr->sample_type);
 	perf_evsel__calc_id_pos(evsel);
+	evsel->cmdline_group_boundary = false;
 }
 
 struct perf_evsel *perf_evsel__new_idx(struct perf_event_attr *attr, int idx)
tools/perf/util/evsel.h +1 -0
index fe9f3279632b..1fc263a80d91 100644
@@ -86,6 +86,7 @@ struct perf_evsel {
 	unsigned long		*per_pkg_mask;
 	struct perf_evsel	*leader;
 	char			*group_name;
+	bool			cmdline_group_boundary;
 };
 
 union u64_swap {
tools/perf/util/parse-events.c +21 -9
index a71eeb279ed2..bbb7fbc2857e 100644
@@ -1065,8 +1065,13 @@ int parse_events(struct perf_evlist *evlist, const char *str,
 	perf_pmu__parse_cleanup();
 	if (!ret) {
 		int entries = data.idx - evlist->nr_entries;
+		struct perf_evsel *last;
+
 		perf_evlist__splice_list_tail(evlist, &data.list, entries);
 		evlist->nr_groups += data.nr_groups;
+		last = perf_evlist__last(evlist);
+		last->cmdline_group_boundary = true;
+
 		return 0;
 	}
 
@@ -1171,16 +1176,23 @@ int parse_filter(const struct option *opt, const char *str,
 	if (evlist->nr_entries > 0)
 		last = perf_evlist__last(evlist);
 
-	if (last == NULL || last->attr.type != PERF_TYPE_TRACEPOINT) {
-		fprintf(stderr,
-			"--filter option should follow a -e tracepoint option\n");
-		return -1;
-	}
+	do {
+		if (last == NULL || last->attr.type != PERF_TYPE_TRACEPOINT) {
+			fprintf(stderr,
+				"--filter option should follow a -e tracepoint option\n");
+			return -1;
+		}
 
-	if (perf_evsel__set_filter(last, str) < 0) {
-		fprintf(stderr, "not enough memory to hold filter string\n");
-		return -1;
-	}
+		if (perf_evsel__set_filter(last, str) < 0) {
+			fprintf(stderr,
+				"not enough memory to hold filter string\n");
+			return -1;
+		}
+
+		if (last->node.prev == &evlist->entries)
+			return 0;
+		last = list_entry(last->node.prev, struct perf_evsel, node);
+	} while (!last->cmdline_group_boundary);
 
 	return 0;
 }
Signature · 1 line
2.1.0
author maintainer
#8 lore raw

PATCH 8/13 perf record: Allow filtering perf's pid via --exclude-perf

In reply to Arnaldo Carvalho de Melo

From: Wang Nan <[email protected]>

This patch allows 'perf record' to exclude events issued by perf itself by '--exclude-perf' option.

Before this patch, when doing something like:

 # perf record -a -e syscalls:sys_enter_write <cmd>

One could easily get result like this:

 # /tmp/perf report --stdio
 ...
  # Overhead  Command  Shared Object       Symbol
  # ........  .......  ..................  ....................
  #
      99.99%  perf     libpthread-2.18.so  [.] __write_nocancel
      0.01%   ls       libc-2.18.so        [.] write
      0.01%   sshd     libc-2.18.so        [.] write
 ...

Where most events are generated by perf itself.

A shell trick can be done to filter perf itself out:

 # cat << EOF > ./tmp
Quoted 3 lines

#!/bin/sh
exec perf record -e ... --filter="common_pid != \$\$" -a sleep 10 EOF

 # chmod a+x ./tmp
 # ./tmp

However, doing so is user unfriendly.

This patch extracts evsel iteration framework introduced by patch 'perf
record: Apply filter to all events in a glob matching' into foreach_evsel_in_last_glob(), and makes exclude_perf() function append new filter expression to each evsel selected by a '-e' selector.

To avoid losing filters if user pass '--filter' after '--exclude-perf', this patch uses perf_evsel__append_filter() in both case, instead of perf_evsel__set_filter() which removes old filter. As a side effect, now it is possible to use multiple '--filter' option for one selector. They are combinded with '&&'.

---
 tools/perf/Documentation/perf-record.txt | 11 ++++-
 tools/perf/builtin-record.c              |  3 ++
 tools/perf/util/parse-events.c           | 83 +++++++++++++++++++++++++++-----
 tools/perf/util/parse-events.h           |  1 +
 4 files changed, 84 insertions(+), 14 deletions(-)
tools/perf/Documentation/perf-record.txt +10 -1
index 5b47b2c88223..29e5307945bf 100644
@@ -69,7 +69,16 @@ OPTIONS
 	  "perf report" to view group events together.
 
 --filter=<filter>::
-        Event filter.
+        Event filter. This option should follow a event selector (-e) which
+	selects tracepoint event(s). Multiple '--filter' options are combined
+	using '&&'.
+
+--exclude-perf::
+	Don't record events issued by perf itself. This option should follow
+	a event selector (-e) which selects tracepoint event(s). It adds a
+	filter expression 'common_pid != $PERFPID' to filters. If other
+	'--filter' exists, the new filter expression will be combined with
+	them by '&&'.
 
 -a::
 --all-cpus::
tools/perf/builtin-record.c +3 -0
index 283fe96bdfc1..1932e27c00d8 100644
@@ -992,6 +992,9 @@ struct option __record_options[] = {
 		     parse_events_option),
 	OPT_CALLBACK(0, "filter", &record.evlist, "filter",
 		     "event filter", parse_filter),
+	OPT_CALLBACK_NOOPT(0, "exclude-perf", &record.evlist,
+			   NULL, "don't record events from perf itself",
+			   exclude_perf),
 	OPT_STRING('p', "pid", &record.opts.target.pid, "pid",
 		    "record events on existing process id"),
 	OPT_STRING('t', "tid", &record.opts.target.tid, "tid",
tools/perf/util/parse-events.c +70 -13

103 lines not on this page · raw message

tools/perf/util/parse-events.h +1 -0
index 131f29b2f132..2063048a4354 100644
@@ -34,6 +34,7 @@ extern int parse_events(struct perf_evlist *evlist, const char *str,
 			struct parse_events_error *error);
 extern int parse_events_terms(struct list_head *terms, const char *str);
 extern int parse_filter(const struct option *opt, const char *str, int unset);
+extern int exclude_perf(const struct option *opt, const char *arg, int unset);
 
 #define EVENTS_HELP_MAX (128*1024)
 
Signature · 1 line
2.1.0
author maintainer
#9 lore raw

PATCH 9/13 perf probe: Simplify __add_probe_trace_events code

In reply to Arnaldo Carvalho de Melo

From: Masami Hiramatsu <[email protected]>

Simplify the __add_probe_trace_events() code by taking out the probe_trace_event__set_name() and updating show_perf_probe_event()

---
 tools/perf/util/probe-event.c | 70 ++++++++++++++++++++++++++-----------------
 1 file changed, 43 insertions(+), 27 deletions(-)
tools/perf/util/probe-event.c +43 -27
index 7abaac4ec866..54a91d765791 100644
@@ -2478,16 +2478,54 @@ out:
 	free(buf);
 }
 
+/* Set new name from original perf_probe_event and namelist */
+static int probe_trace_event__set_name(struct probe_trace_event *tev,
+				       struct perf_probe_event *pev,
+				       struct strlist *namelist,
+				       bool allow_suffix)
+{
+	const char *event, *group;
+	char buf[64];
+	int ret;
+
+	if (pev->event)
+		event = pev->event;
+	else
+		if (pev->point.function && !strisglob(pev->point.function))
+			event = pev->point.function;
+		else
+			event = tev->point.realname;
+	if (pev->group)
+		group = pev->group;
+	else
+		group = PERFPROBE_GROUP;
+
+	/* Get an unused new event name */
+	ret = get_new_event_name(buf, 64, event,
+				 namelist, allow_suffix);
+	if (ret < 0)
+		return ret;
+
+	event = buf;
+
+	tev->event = strdup(event);
+	tev->group = strdup(group);
+	if (tev->event == NULL || tev->group == NULL)
+		return -ENOMEM;
+
+	/* Add added event name to namelist */
+	strlist__add(namelist, event);
+	return 0;
+}
+
 static int __add_probe_trace_events(struct perf_probe_event *pev,
 				     struct probe_trace_event *tevs,
 				     int ntevs, bool allow_suffix)
 {
 	int i, fd, ret;
 	struct probe_trace_event *tev = NULL;
-	char buf[64];
 	const char *event = NULL, *group = NULL;
 	struct strlist *namelist;
-	bool safename;
 
 	if (pev->uprobes)
 		fd = open_uprobe_events(true);
@@ -2507,7 +2545,6 @@ static int __add_probe_trace_events(struct perf_probe_event *pev,
 		goto close_out;
 	}
 
-	safename = (pev->point.function && !strisglob(pev->point.function));
 	ret = 0;
 	pr_info("Added new event%s\n", (ntevs > 1) ? "s:" : ":");
 	for (i = 0; i < ntevs; i++) {
@@ -2516,36 +2553,15 @@ static int __add_probe_trace_events(struct perf_probe_event *pev,
 		if (!tev->point.symbol)
 			continue;
 
-		if (pev->event)
-			event = pev->event;
-		else
-			if (safename)
-				event = pev->point.function;
-			else
-				event = tev->point.realname;
-		if (pev->group)
-			group = pev->group;
-		else
-			group = PERFPROBE_GROUP;
-
-		/* Get an unused new event name */
-		ret = get_new_event_name(buf, 64, event,
-					 namelist, allow_suffix);
+		/* Set new name for tev (and update namelist) */
+		ret = probe_trace_event__set_name(tev, pev, namelist,
+						  allow_suffix);
 		if (ret < 0)
 			break;
-		event = buf;
 
-		tev->event = strdup(event);
-		tev->group = strdup(group);
-		if (tev->event == NULL || tev->group == NULL) {
-			ret = -ENOMEM;
-			break;
-		}
 		ret = write_probe_trace_event(fd, tev);
 		if (ret < 0)
 			break;
-		/* Add added event name to namelist */
-		strlist__add(namelist, event);
 
 		/* We use tev's name for showing new events */
 		show_perf_probe_event(tev->group, tev->event, pev,
Signature · 1 line
2.1.0
author maintainer
#10 lore raw

PATCH 10/13 perf probe: Move ftrace probe-event operations to probe-file.c

In reply to Arnaldo Carvalho de Melo

From: Masami Hiramatsu <[email protected]>

Move ftrace probe-event operations to probe-file.c from probe-event.c.

Cc Adrian Hunter <[email protected]>
Cc Borislav Petkov <[email protected]>
Cc Hemant Kumar <[email protected]>
Cc Jiri Olsa <[email protected]>
Cc Namhyung Kim <[email protected]>
Cc Paul Mackerras <[email protected]>
Cc Peter Zijlstra <[email protected]>
[ Fixed up strlist__new() calls wrt 4a77e2183fc0 ("perf strlist: Make dupstr be the...") ]
---
 tools/perf/util/Build         |   1 +
 tools/perf/util/probe-event.c | 318 ++++--------------------------------------
 tools/perf/util/probe-event.h |   7 +
 tools/perf/util/probe-file.c  | 301 +++++++++++++++++++++++++++++++++++++++
 tools/perf/util/probe-file.h  |  18 +++
 5 files changed, 353 insertions(+), 292 deletions(-)
 create mode 100644 tools/perf/util/probe-file.c
 create mode 100644 tools/perf/util/probe-file.h
tools/perf/util/Build +1 -0
index 601d11440596..8d1bdf878b20 100644
@@ -79,6 +79,7 @@ libperf-$(CONFIG_AUXTRACE) += auxtrace.o
 libperf-y += parse-branch-options.o
 
 libperf-$(CONFIG_LIBELF) += symbol-elf.o
+libperf-$(CONFIG_LIBELF) += probe-file.o
 libperf-$(CONFIG_LIBELF) += probe-event.o
 
 ifndef CONFIG_LIBELF
tools/perf/util/probe-event.c +26 -292

413 lines not on this page · raw message

tools/perf/util/probe-event.h +7 -0
index 31db6ee7db54..20f555d1ae1c 100644
@@ -109,6 +109,8 @@ struct variable_list {
 /* Command string to events */
 extern int parse_perf_probe_command(const char *cmd,
 				    struct perf_probe_event *pev);
+extern int parse_probe_trace_command(const char *cmd,
+				     struct probe_trace_event *tev);
 
 /* Events to command string */
 extern char *synthesize_perf_probe_command(struct perf_probe_event *pev);
@@ -121,6 +123,7 @@ extern bool perf_probe_event_need_dwarf(struct perf_probe_event *pev);
 
 /* Release event contents */
 extern void clear_perf_probe_event(struct perf_probe_event *pev);
+extern void clear_probe_trace_event(struct probe_trace_event *tev);
 
 /* Command string to line-range */
 extern int parse_line_range_desc(const char *cmd, struct line_range *lr);
@@ -144,6 +147,10 @@ bool arch__prefers_symtab(void);
 void arch__fix_tev_from_maps(struct perf_probe_event *pev,
 			     struct probe_trace_event *tev, struct map *map);
 
+/* If there is no space to write, returns -E2BIG. */
+int e_snprintf(char *str, size_t size, const char *format, ...)
+	__attribute__((format(printf, 3, 4)));
+
 /* Maximum index number of event-name postfix */
 #define MAX_EVENT_INDEX	1024
 
tools/perf/util/probe-file.c new file +301 -0

301 lines not on this page · raw message

tools/perf/util/probe-file.h new file +18 -0
new file mode 100644
index 000000000000..ada94a242a17
@@ -0,0 +1,18 @@
+#ifndef __PROBE_FILE_H
+#define __PROBE_FILE_H
+
+#include "strlist.h"
+#include "strfilter.h"
+#include "probe-event.h"
+
+#define PF_FL_UPROBE	1
+#define PF_FL_RW	2
+
+int probe_file__open(int flag);
+int probe_file__open_both(int *kfd, int *ufd, int flag);
+struct strlist *probe_file__get_namelist(int fd);
+struct strlist *probe_file__get_rawlist(int fd);
+int probe_file__add_event(int fd, struct probe_trace_event *tev);
+int probe_file__del_events(int fd, struct strfilter *filter);
+
+#endif
Signature · 1 line
2.1.0
author maintainer
#11 lore raw

PATCH 11/13 perf buildid: Use SBUILD_ID_SIZE macro

In reply to Arnaldo Carvalho de Melo

From: Masami Hiramatsu <[email protected]>

Introduce SBUILD_ID_SIZE macro and use it instead of using BUILD_ID_SIZE
* 2 + 1.

---
 tools/perf/builtin-buildid-cache.c | 8 ++++----
 tools/perf/builtin-buildid-list.c  | 4 ++--
 tools/perf/util/build-id.c         | 4 ++--
 tools/perf/util/build-id.h         | 3 ++-
 4 files changed, 10 insertions(+), 9 deletions(-)
tools/perf/builtin-buildid-cache.c +4 -4
index ddca990bcc00..65b4835309c7 100644
@@ -127,7 +127,7 @@ static int build_id_cache__kcore_existing(const char *from_dir, char *to_dir,
 
 static int build_id_cache__add_kcore(const char *filename, bool force)
 {
-	char dir[32], sbuildid[BUILD_ID_SIZE * 2 + 1];
+	char dir[32], sbuildid[SBUILD_ID_SIZE];
 	char from_dir[PATH_MAX], to_dir[PATH_MAX];
 	char *p;
 
@@ -184,7 +184,7 @@ static int build_id_cache__add_kcore(const char *filename, bool force)
 
 static int build_id_cache__add_file(const char *filename)
 {
-	char sbuild_id[BUILD_ID_SIZE * 2 + 1];
+	char sbuild_id[SBUILD_ID_SIZE];
 	u8 build_id[BUILD_ID_SIZE];
 	int err;
 
@@ -204,7 +204,7 @@ static int build_id_cache__add_file(const char *filename)
 static int build_id_cache__remove_file(const char *filename)
 {
 	u8 build_id[BUILD_ID_SIZE];
-	char sbuild_id[BUILD_ID_SIZE * 2 + 1];
+	char sbuild_id[SBUILD_ID_SIZE];
 
 	int err;
 
@@ -276,7 +276,7 @@ static int build_id_cache__fprintf_missing(struct perf_session *session, FILE *f
 static int build_id_cache__update_file(const char *filename)
 {
 	u8 build_id[BUILD_ID_SIZE];
-	char sbuild_id[BUILD_ID_SIZE * 2 + 1];
+	char sbuild_id[SBUILD_ID_SIZE];
 
 	int err = 0;
 
tools/perf/builtin-buildid-list.c +2 -2
index 9fe93c8d4fcf..b5ca988ebfbe 100644
@@ -20,7 +20,7 @@
 static int sysfs__fprintf_build_id(FILE *fp)
 {
 	u8 kallsyms_build_id[BUILD_ID_SIZE];
-	char sbuild_id[BUILD_ID_SIZE * 2 + 1];
+	char sbuild_id[SBUILD_ID_SIZE];
 
 	if (sysfs__read_build_id("/sys/kernel/notes", kallsyms_build_id,
 				 sizeof(kallsyms_build_id)) != 0)
@@ -35,7 +35,7 @@ static int sysfs__fprintf_build_id(FILE *fp)
 static int filename__fprintf_build_id(const char *name, FILE *fp)
 {
 	u8 build_id[BUILD_ID_SIZE];
-	char sbuild_id[BUILD_ID_SIZE * 2 + 1];
+	char sbuild_id[SBUILD_ID_SIZE];
 
 	if (filename__read_build_id(name, build_id,
 				    sizeof(build_id)) != sizeof(build_id))
tools/perf/util/build-id.c +2 -2
index f98c2ffafba7..4a2c2f0ead41 100644
@@ -124,7 +124,7 @@ static char *build_id__filename(const char *sbuild_id, char *bf, size_t size)
 
 char *dso__build_id_filename(const struct dso *dso, char *bf, size_t size)
 {
-	char build_id_hex[BUILD_ID_SIZE * 2 + 1];
+	char build_id_hex[SBUILD_ID_SIZE];
 
 	if (!dso->has_build_id)
 		return NULL;
@@ -384,7 +384,7 @@ static int build_id_cache__add_b(const u8 *build_id, size_t build_id_size,
 				 const char *name, bool is_kallsyms,
 				 bool is_vdso)
 {
-	char sbuild_id[BUILD_ID_SIZE * 2 + 1];
+	char sbuild_id[SBUILD_ID_SIZE];
 
 	build_id__sprintf(build_id, build_id_size, sbuild_id);
 
tools/perf/util/build-id.h +2 -1
index 85011222cc14..ce2f493f057a 100644
@@ -1,7 +1,8 @@
 #ifndef PERF_BUILD_ID_H_
 #define PERF_BUILD_ID_H_ 1
 
-#define BUILD_ID_SIZE 20
+#define BUILD_ID_SIZE	20
+#define SBUILD_ID_SIZE	(BUILD_ID_SIZE * 2 + 1)
 
 #include "tool.h"
 #include "strlist.h"
Signature · 1 line
2.1.0
author maintainer
#12 lore raw

PATCH 12/13 perf tools: Fix makefile generation under dash

In reply to Arnaldo Carvalho de Melo

From: Sergei Trofimovich <[email protected]>

Under dash 'echo -n' yields '-n' to stdout. Use printf "" instead.

---
 tools/perf/config/Makefile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
tools/perf/config/Makefile +1 -1
index a9b93d1ecefa..8768f84e42a5 100644
@@ -11,7 +11,7 @@ ifneq ($(obj-perf),)
 obj-perf := $(abspath $(obj-perf))/
 endif
 
-$(shell echo -n > $(OUTPUT).config-detected)
+$(shell printf "" > $(OUTPUT).config-detected)
 detected     = $(shell echo "$(1)=y"       >> $(OUTPUT).config-detected)
 detected_var = $(shell echo "$(1)=$($(1))" >> $(OUTPUT).config-detected)
 
Signature · 1 line
2.1.0
author maintainer
#13 lore raw

PATCH 13/13 perf bench futex: Add lock_pi stresser

In reply to Arnaldo Carvalho de Melo

From: Davidlohr Bueso <[email protected]>

Allows a way of measuring low level kernel implementation of FUTEX_LOCK_PI and FUTEX_UNLOCK_PI.

The program comes in two flavors:

(i) single futex (default), all threads contend on the same uaddr. For the sake of the benchmark, we call into kernel space even when the lock is uncontended. The kernel will set it to TID, any waters that come in and contend for the pi futex will be handled respectively by the kernel.

(ii) -M option for multiple futexes, each thread deals with its own futex. This is a trivial scenario and only measures kernel handling of 0->TID transition.

---
 tools/perf/Documentation/perf-bench.txt |   4 +
 tools/perf/bench/Build                  |   1 +
 tools/perf/bench/bench.h                |   2 +
 tools/perf/bench/futex-lock-pi.c        | 219 ++++++++++++++++++++++++++++++++
 tools/perf/bench/futex.h                |  20 +++
 tools/perf/builtin-bench.c              |   2 +
 6 files changed, 248 insertions(+)
 create mode 100644 tools/perf/bench/futex-lock-pi.c
tools/perf/Documentation/perf-bench.txt +4 -0
index bf3d0644bf10..ab632d9fbd7d 100644
@@ -216,6 +216,10 @@ Suite for evaluating parallel wake calls.
 *requeue*::
 Suite for evaluating requeue calls.
 
+*lock-pi*::
+Suite for evaluating futex lock_pi calls.
+
+
 SEE ALSO
 --------
 linkperf:perf[1]
tools/perf/bench/Build +1 -0
index c3ab760e06b4..573e28896038 100644
@@ -5,6 +5,7 @@ perf-y += futex-hash.o
 perf-y += futex-wake.o
 perf-y += futex-wake-parallel.o
 perf-y += futex-requeue.o
+perf-y += futex-lock-pi.o
 
 perf-$(CONFIG_X86_64) += mem-memcpy-x86-64-asm.o
 perf-$(CONFIG_X86_64) += mem-memset-x86-64-asm.o
tools/perf/bench/bench.h +2 -0
index 70b2f718cc21..a50df86f2b9b 100644
@@ -36,6 +36,8 @@ extern int bench_futex_wake(int argc, const char **argv, const char *prefix);
 extern int bench_futex_wake_parallel(int argc, const char **argv,
 				     const char *prefix);
 extern int bench_futex_requeue(int argc, const char **argv, const char *prefix);
+/* pi futexes */
+extern int bench_futex_lock_pi(int argc, const char **argv, const char *prefix);
 
 #define BENCH_FORMAT_DEFAULT_STR	"default"
 #define BENCH_FORMAT_DEFAULT		0
tools/perf/bench/futex-lock-pi.c new file +219 -0

219 lines not on this page · raw message

tools/perf/bench/futex.h +20 -0
index 7ed22ff1e1ac..d44de9f44281 100644
@@ -56,6 +56,26 @@ futex_wake(u_int32_t *uaddr, int nr_wake, int opflags)
 }
 
 /**
+ * futex_lock_pi() - block on uaddr as a PI mutex
+ * @detect:	whether (1) or not (0) to perform deadlock detection
+ */
+static inline int
+futex_lock_pi(u_int32_t *uaddr, struct timespec *timeout, int detect,
+	      int opflags)
+{
+	return futex(uaddr, FUTEX_LOCK_PI, detect, timeout, NULL, 0, opflags);
+}
+
+/**
+ * futex_unlock_pi() - release uaddr as a PI mutex, waking the top waiter
+ */
+static inline int
+futex_unlock_pi(u_int32_t *uaddr, int opflags)
+{
+	return futex(uaddr, FUTEX_UNLOCK_PI, 0, NULL, NULL, 0, opflags);
+}
+
+/**
 * futex_cmp_requeue() - requeue tasks from uaddr to uaddr2
 * @nr_wake:        wake up to this many tasks
 * @nr_requeue:        requeue up to this many tasks
tools/perf/builtin-bench.c +2 -0
index b5314e452ec7..f67934d46d40 100644
@@ -60,6 +60,8 @@ static struct bench futex_benchmarks[] = {
 	{ "wake",	"Benchmark for futex wake calls",               bench_futex_wake	},
 	{ "wake-parallel", "Benchmark for parallel futex wake calls",   bench_futex_wake_parallel },
 	{ "requeue",	"Benchmark for futex requeue calls",            bench_futex_requeue	},
+	/* pi-futexes */
+	{ "lock-pi",	"Benchmark for futex lock_pi calls",            bench_futex_lock_pi	},
 	{ "all",	"Test all futex benchmarks",			NULL			},
 	{ NULL,		NULL,						NULL			}
 };
Signature · 1 line
2.1.0
#14 lore raw
In reply to Arnaldo Carvalho de Melo
Quoted 107 lines · Arnaldo Carvalho de Melo

Hi Ingo,

Please consider pulling,

- Arnaldo

The following changes since commit 60cd37eb100c4880b28078a47f3062fac7572095:

Merge tag 'perf-core-for-mingo' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core (2015-07-06 17:46:15 +0200)

are available in the git repository at:

git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux.git tags/perf-core-for-mingo

for you to fetch changes up to d2f3f5d2e9cae6e73f9642a5ddc8c8a07c35e79b:

perf bench futex: Add lock_pi stresser (2015-07-20 17:49:51 -0300)

----------------------------------------------------------------
perf/core improvements and fixes:

New features:

- Allow filtering perf's pid via 'perf record --exclude-perf' (Wang Nan)

- 'perf trace' now supports syscall groups, like strace, i.e:

    $ trace -e file touch file

Will expand 'file' into multiple, file related, syscalls. More work needed to add extra groups for other syscall groups, and also to complement what was added for the 'file' group, included as a proof of concept. (Arnaldo Carvalho de Melo)

- Add lock_pi stresser to 'perf bench futex', to test the kernel code related to FUTEX_(UN)LOCK_PI (Davidlohr Bueso)

User visible fixes:

- Apply --filter to all events in a glob matching, not just the last one (Wang Nan)

Documentation:

- Document setting '-e pmu/period=N/' in the 'perf record' man page (Kan Liang)

Infrastructure:

- 'perf probe' code simplifications and movements to separate files (Masami Hiramatsu)

- Fix makefile generation under 'dash' (Sergei Trofimovich)

----------------------------------------------------------------
Arnaldo Carvalho de Melo (5):
perf strlist: load() should return a negative errno
perf strlist: Make dupstr be the default and part of an extensible config parm perf strlist: Allow substitutions from file contents in a given directory perf strlist: Make parse_list() private
perf trace: Support 'strace' syscall event groups

Davidlohr Bueso (1):
perf bench futex: Add lock_pi stresser

Kan Liang (1):
perf record: Document setting '-e pmu/period=N/' in man page

Masami Hiramatsu (3):
perf probe: Simplify __add_probe_trace_events code perf probe: Move ftrace probe-event operations to probe-file.c perf buildid: Use SBUILD_ID_SIZE macro

Sergei Trofimovich (1):
perf tools: Fix makefile generation under dash

Wang Nan (2):
perf record: Apply filter to all events in a glob matching perf record: Allow filtering perf's pid via --exclude-perf

 tools/perf/Build                         |   1 +
 tools/perf/Documentation/perf-bench.txt  |   4 +
 tools/perf/Documentation/perf-record.txt |  19 +-
 tools/perf/Makefile.perf                 |   5 +
 tools/perf/bench/Build                   |   1 +
 tools/perf/bench/bench.h                 |   2 +
 tools/perf/bench/futex-lock-pi.c         | 219 +++++++++++++++++
 tools/perf/bench/futex.h                 |  20 ++
 tools/perf/builtin-bench.c               |   2 +
 tools/perf/builtin-buildid-cache.c       |  16 +-
 tools/perf/builtin-buildid-list.c        |   4 +-
 tools/perf/builtin-record.c              |   3 +
 tools/perf/builtin-trace.c               |   6 +-
 tools/perf/config/Makefile               |   8 +-
 tools/perf/trace/strace/groups/file      |  18 ++
 tools/perf/util/Build                    |   1 +
 tools/perf/util/build-id.c               |   6 +-
 tools/perf/util/build-id.h               |   3 +-
 tools/perf/util/evsel.c                  |   1 +
 tools/perf/util/evsel.h                  |   1 +
 tools/perf/util/machine.c                |   2 +-
 tools/perf/util/parse-events.c           |  81 ++++++-
 tools/perf/util/parse-events.h           |   1 +
 tools/perf/util/probe-event.c            | 388 ++++++-------------------------
 tools/perf/util/probe-event.h            |   7 +
 tools/perf/util/probe-file.c             | 301 ++++++++++++++++++++++++
 tools/perf/util/probe-file.h             |  18 ++
 tools/perf/util/probe-finder.c           |   2 +-
 tools/perf/util/strlist.c                |  43 +++-
Quoted 8 lines
 tools/perf/util/strlist.h                |   9 +-
 tools/perf/util/symbol.c                 |   2 +-
 tools/perf/util/thread_map.c             |   6 +-
 32 files changed, 842 insertions(+), 358 deletions(-)
 create mode 100644 tools/perf/bench/futex-lock-pi.c
 create mode 100644 tools/perf/trace/strace/groups/file
 create mode 100644 tools/perf/util/probe-file.c
 create mode 100644 tools/perf/util/probe-file.h

Pulled, thanks a lot Arnaldo!

Ingo