linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Arnaldo Carvalho de Melo <acme@kernel.org>
To: Ingo Molnar <mingo@kernel.org>, Thomas Gleixner <tglx@linutronix.de>
Cc: "Jiri Olsa" <jolsa@kernel.org>,
	"Namhyung Kim" <namhyung@kernel.org>,
	"Clark Williams" <williams@redhat.com>,
	linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org,
	"Arnaldo Carvalho de Melo" <acme@redhat.com>,
	"Adrian Hunter" <adrian.hunter@intel.com>,
	"Luis Cláudio Gonçalves" <lclaudio@redhat.com>
Subject: [PATCH 026/107] perf trace: Reuse BPF augmenters from syscalls with similar args signature
Date: Mon, 29 Jul 2019 23:54:49 -0300	[thread overview]
Message-ID: <20190730025610.22603-27-acme@kernel.org> (raw)
In-Reply-To: <20190730025610.22603-1-acme@kernel.org>

From: Arnaldo Carvalho de Melo <acme@redhat.com>

We have an augmenter for the "open" syscall, which has just one pointer,
in the first argument, a "const char *", so any other syscall that has
just one pointer and that is the first can reuse the "open" BPF
augmenter program.

Even more, syscalls that get two pointers with the first being a string
can reuse "open"'s BPF augmenter till we have an augmenter that better
matches that syscall with two pointers.

With this the few augmenters we have, for open (first arg is a string),
openat (2nd arg is a string), renameat (2nd and 4th are strings) can be
reused by a lot of syscalls, ditto for "bind" reusing "connect" because
both have the 2nd argument as a sockaddr and the 3rd as its len.

Lets see how this makes the "bind" syscall reuse the "connect" BPF prog
augmenter found in tools/perf/examples/bpf/augmented_raw_syscalls.c:

  # perf trace -e bind,connect systemctl restart sshd
  connect(3, { .family: PF_LOCAL, path: /run/systemd/private }, 23) = 0
  #

Oh, it just connects to some daemon, so we better do it system wide and then
stop/start sshd:

  # perf trace -e bind,connect
  systemctl/10124 connect(3, { .family: PF_LOCAL, path: /run/systemd/private }, 23) = 0
  sshd/10102 connect(7, { .family: PF_LOCAL, path: /dev/log }, 110) = 0
  systemctl/10126 connect(3, { .family: PF_LOCAL, path: /run/systemd/private }, 23) = 0
  systemd/10128  ... [continued]: connect())            = 0
  (sshd)/10128 connect(3, { .family: PF_LOCAL, path: /run/systemd/journal/stdout }, 30) ...
  sshd/10128 bind(3, { .family: PF_NETLINK }, 12)    = 0
  sshd/10128 connect(4, { .family: PF_LOCAL, path: /var/run/nscd/socket }, 110) = -1 ENOENT (No such file or directory)
  sshd/10128 connect(3, { .family: PF_INET6, port: 22, addr: :: }, 28) = 0
  sshd/10128 connect(3, { .family: PF_UNSPEC }, 16)  = 0
  sshd/10128 connect(3, { .family: PF_INET, port: 22, addr: 0.0.0.0 }, 16) = 0
  sshd/10128 connect(3, { .family: PF_LOCAL, path: /var/run/nscd/socket }, 110) = -1 ENOENT (No such file or directory)
  sshd/10128 connect(3, { .family: PF_LOCAL, path: /var/run/nscd/socket }, 110) = -1 ENOENT (No such file or directory)
  sshd/10128 connect(5, { .family: PF_LOCAL, path: /var/run/nscd/socket }, 110) = -1 ENOENT (No such file or directory)
  sshd/10128 connect(5, { .family: PF_LOCAL, path: /var/run/nscd/socket }, 110) = -1 ENOENT (No such file or directory)
  sshd/10128 bind(4, { .family: PF_INET, port: 22, addr: 0.0.0.0 }, 16) = 0
  sshd/10128 connect(6, { .family: PF_LOCAL, path: /dev/log }, 110) = 0
  sshd/10128 bind(6, { .family: PF_INET6, port: 22, addr: :: }, 28) = 0
  sshd/10128 connect(7, { .family: PF_LOCAL, path: /dev/log }, 110) = 0
  ^C#

Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Luis Cláudio Gonçalves <lclaudio@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Link: https://lkml.kernel.org/n/tip-zfley2ghs4nim1uq4nu6ed3l@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/builtin-trace.c | 154 ++++++++++++++++++++++++++++++++++++-
 1 file changed, 152 insertions(+), 2 deletions(-)

diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index d8565c9a18a2..200fbe33d5de 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -709,7 +709,6 @@ static struct syscall_fmt {
 	  .arg = { [0] = { .scnprintf = SCA_X86_ARCH_PRCTL_CODE, /* code */ },
 		   [1] = { .scnprintf = SCA_PTR, /* arg2 */ }, }, },
 	{ .name	    = "bind",
-	  .bpf_prog_name = { .sys_enter = "!syscalls:sys_enter_connect", },
 	  .arg = { [0] = { .scnprintf = SCA_INT, /* fd */ },
 		   [1] = { .scnprintf = SCA_SOCKADDR, /* umyaddr */ },
 		   [2] = { .scnprintf = SCA_INT, /* addrlen */ }, }, },
@@ -879,7 +878,6 @@ static struct syscall_fmt {
 	  .arg = { [0] = { .scnprintf = SCA_FDAT, /* olddirfd */ },
 		   [2] = { .scnprintf = SCA_FDAT, /* newdirfd */ }, }, },
 	{ .name	    = "renameat2",
-	  .bpf_prog_name = { .sys_enter = "!syscalls:sys_enter_renameat", },
 	  .arg = { [0] = { .scnprintf = SCA_FDAT, /* olddirfd */ },
 		   [2] = { .scnprintf = SCA_FDAT, /* newdirfd */ },
 		   [4] = { .scnprintf = SCA_RENAMEAT2_FLAGS, /* flags */ }, }, },
@@ -2910,6 +2908,94 @@ static int trace__init_syscalls_bpf_map(struct trace *trace)
 	return __trace__init_syscalls_bpf_map(trace, enabled);
 }
 
+static struct bpf_program *trace__find_usable_bpf_prog_entry(struct trace *trace, struct syscall *sc)
+{
+	struct tep_format_field *field, *candidate_field;
+	int id;
+
+	/*
+	 * We're only interested in syscalls that have a pointer:
+	 */
+	for (field = sc->args; field; field = field->next) {
+		if (field->flags & TEP_FIELD_IS_POINTER)
+			goto try_to_find_pair;
+	}
+
+	return NULL;
+
+try_to_find_pair:
+	for (id = 0; id < trace->sctbl->syscalls.nr_entries; ++id) {
+		struct syscall *pair = trace__syscall_info(trace, NULL, id);
+		struct bpf_program *pair_prog;
+		bool is_candidate = false;
+
+		if (pair == NULL || pair == sc ||
+		    pair->bpf_prog.sys_enter == trace->syscalls.unaugmented_prog)
+			continue;
+
+		for (field = sc->args, candidate_field = pair->args;
+		     field && candidate_field; field = field->next, candidate_field = candidate_field->next) {
+			bool is_pointer = field->flags & TEP_FIELD_IS_POINTER,
+			     candidate_is_pointer = candidate_field->flags & TEP_FIELD_IS_POINTER;
+
+			if (is_pointer) {
+			       if (!candidate_is_pointer) {
+					// The candidate just doesn't copies our pointer arg, might copy other pointers we want.
+					continue;
+			       }
+			} else {
+				if (candidate_is_pointer) {
+					// The candidate might copy a pointer we don't have, skip it.
+					goto next_candidate;
+				}
+				continue;
+			}
+
+			if (strcmp(field->type, candidate_field->type))
+				goto next_candidate;
+
+			is_candidate = true;
+		}
+
+		if (!is_candidate)
+			goto next_candidate;
+
+		/*
+		 * Check if the tentative pair syscall augmenter has more pointers, if it has,
+		 * then it may be collecting that and we then can't use it, as it would collect
+		 * more than what is common to the two syscalls.
+		 */
+		if (candidate_field) {
+			for (candidate_field = candidate_field->next; candidate_field; candidate_field = candidate_field->next)
+				if (candidate_field->flags & TEP_FIELD_IS_POINTER)
+					goto next_candidate;
+		}
+
+		pair_prog = pair->bpf_prog.sys_enter;
+		/*
+		 * If the pair isn't enabled, then its bpf_prog.sys_enter will not
+		 * have been searched for, so search it here and if it returns the
+		 * unaugmented one, then ignore it, otherwise we'll reuse that BPF
+		 * program for a filtered syscall on a non-filtered one.
+		 *
+		 * For instance, we have "!syscalls:sys_enter_renameat" and that is
+		 * useful for "renameat2".
+		 */
+		if (pair_prog == NULL) {
+			pair_prog = trace__find_syscall_bpf_prog(trace, pair, pair->fmt ? pair->fmt->bpf_prog_name.sys_enter : NULL, "enter");
+			if (pair_prog == trace->syscalls.unaugmented_prog)
+				goto next_candidate;
+		}
+
+		pr_debug("Reusing \"%s\" BPF sys_enter augmenter for \"%s\"\n", pair->name, sc->name);
+		return pair_prog;
+	next_candidate:
+		continue;
+	}
+
+	return NULL;
+}
+
 static int trace__init_syscalls_bpf_prog_array_maps(struct trace *trace)
 {
 	int map_enter_fd = bpf_map__fd(trace->syscalls.prog_array.sys_enter),
@@ -2935,6 +3021,70 @@ static int trace__init_syscalls_bpf_prog_array_maps(struct trace *trace)
 			break;
 	}
 
+	/*
+	 * Now lets do a second pass looking for enabled syscalls without
+	 * an augmenter that have a signature that is a superset of another
+	 * syscall with an augmenter so that we can auto-reuse it.
+	 *
+	 * I.e. if we have an augmenter for the "open" syscall that has
+	 * this signature:
+	 *
+	 *   int open(const char *pathname, int flags, mode_t mode);
+	 *
+	 * I.e. that will collect just the first string argument, then we
+	 * can reuse it for the 'creat' syscall, that has this signature:
+	 *
+	 *   int creat(const char *pathname, mode_t mode);
+	 *
+	 * and for:
+	 *
+	 *   int stat(const char *pathname, struct stat *statbuf);
+	 *   int lstat(const char *pathname, struct stat *statbuf);
+	 *
+	 * Because the 'open' augmenter will collect the first arg as a string,
+	 * and leave alone all the other args, which already helps with
+	 * beautifying 'stat' and 'lstat''s pathname arg.
+	 *
+	 * Then, in time, when 'stat' gets an augmenter that collects both
+	 * first and second arg (this one on the raw_syscalls:sys_exit prog
+	 * array tail call, then that one will be used.
+	 */
+	for (key = 0; key < trace->sctbl->syscalls.nr_entries; ++key) {
+		struct syscall *sc = trace__syscall_info(trace, NULL, key);
+		struct bpf_program *pair_prog;
+		int prog_fd;
+
+		if (sc == NULL || sc->bpf_prog.sys_enter == NULL)
+			continue;
+
+		/*
+		 * For now we're just reusing the sys_enter prog, and if it
+		 * already has an augmenter, we don't need to find one.
+		 */
+		if (sc->bpf_prog.sys_enter != trace->syscalls.unaugmented_prog)
+			continue;
+
+		/*
+		 * Look at all the other syscalls for one that has a signature
+		 * that is close enough that we can share:
+		 */
+		pair_prog = trace__find_usable_bpf_prog_entry(trace, sc);
+		if (pair_prog == NULL)
+			continue;
+
+		sc->bpf_prog.sys_enter = pair_prog;
+
+		/*
+		 * Update the BPF_MAP_TYPE_PROG_SHARED for raw_syscalls:sys_enter
+		 * with the fd for the program we're reusing:
+		 */
+		prog_fd = bpf_program__fd(sc->bpf_prog.sys_enter);
+		err = bpf_map_update_elem(map_enter_fd, &key, &prog_fd, BPF_ANY);
+		if (err)
+			break;
+	}
+
+
 	return err;
 }
 #else
-- 
2.21.0


  parent reply	other threads:[~2019-07-30  2:57 UTC|newest]

Thread overview: 112+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-07-30  2:54 [GIT PULL 000/107] perf/core improvements and fixes Arnaldo Carvalho de Melo
2019-07-30  2:54 ` [PATCH 001/107] perf include bpf: Add bpf_tail_call() prototype Arnaldo Carvalho de Melo
2019-07-30  2:54 ` [PATCH 002/107] perf bpf: Do not attach a BPF prog to a tracepoint if its name starts with ! Arnaldo Carvalho de Melo
2019-07-30  2:54 ` [PATCH 003/107] perf evsel: Store backpointer to attached bpf_object Arnaldo Carvalho de Melo
2019-07-30  2:54 ` [PATCH 004/107] perf trace: Add pointer to BPF object containing __augmented_syscalls__ Arnaldo Carvalho de Melo
2019-07-30  2:54 ` [PATCH 005/107] perf trace: Look up maps just on the __augmented_syscalls__ BPF object Arnaldo Carvalho de Melo
2019-07-30  2:54 ` [PATCH 006/107] perf trace: Order -e syscalls table Arnaldo Carvalho de Melo
2019-07-30  2:54 ` [PATCH 007/107] perf trace: Add BPF handler for unaugmented syscalls Arnaldo Carvalho de Melo
2019-07-30  2:54 ` [PATCH 008/107] perf trace: Allow specifying the bpf prog to augment specific syscalls Arnaldo Carvalho de Melo
2019-07-30  2:54 ` [PATCH 009/107] perf trace: Put the per-syscall entry/exit prog_array BPF map infrastructure in place Arnaldo Carvalho de Melo
2019-07-30  2:54 ` [PATCH 010/107] perf trace: Handle raw_syscalls:sys_enter just like the BPF_OUTPUT augmented event Arnaldo Carvalho de Melo
2019-07-30  2:54 ` [PATCH 011/107] perf augmented_raw_syscalls: Add handler for "openat" Arnaldo Carvalho de Melo
2019-07-30  2:54 ` [PATCH 012/107] perf augmented_raw_syscalls: Switch to using BPF_MAP_TYPE_PROG_ARRAY Arnaldo Carvalho de Melo
2019-07-30  2:54 ` [PATCH 013/107] perf augmented_raw_syscalls: Support copying two string syscall args Arnaldo Carvalho de Melo
2019-07-30  2:54 ` [PATCH 014/107] perf trace: Look for default name for entries in the syscalls prog array Arnaldo Carvalho de Melo
2019-07-30  2:54 ` [PATCH 015/107] perf augmented_raw_syscalls: Rename augmented_args_filename to augmented_args_payload Arnaldo Carvalho de Melo
2019-07-30  2:54 ` [PATCH 016/107] perf augmented_raw_syscalls: Augment sockaddr arg in 'connect' Arnaldo Carvalho de Melo
2019-07-30  2:54 ` [PATCH 017/107] perf trace beauty: Make connect's addrlen be printed as an int, not hex Arnaldo Carvalho de Melo
2019-07-30  2:54 ` [PATCH 018/107] perf trace beauty: Disable fd->pathname when close() not enabled Arnaldo Carvalho de Melo
2019-07-30  2:54 ` [PATCH 019/107] perf trace beauty: Do not try to use the fd->pathname beautifier for bind/connect fd arg Arnaldo Carvalho de Melo
2019-07-30  2:54 ` [PATCH 020/107] perf trace beauty: Beautify 'sendto's sockaddr arg Arnaldo Carvalho de Melo
2019-07-30  2:54 ` [PATCH 021/107] perf trace beauty: Beautify bind's " Arnaldo Carvalho de Melo
2019-07-30  2:54 ` [PATCH 022/107] perf trace beauty: Add BPF augmenter for the 'rename' syscall Arnaldo Carvalho de Melo
2019-07-30  2:54 ` [PATCH 023/107] perf trace: Forward error codes when trying to read syscall info Arnaldo Carvalho de Melo
2019-07-30  2:54 ` [PATCH 024/107] perf trace: Mark syscall ids that are not allocated to avoid unnecessary error messages Arnaldo Carvalho de Melo
2019-07-30  2:54 ` [PATCH 025/107] perf trace: Preallocate the syscall table Arnaldo Carvalho de Melo
2019-07-30  2:54 ` Arnaldo Carvalho de Melo [this message]
2019-07-30  2:54 ` [PATCH 027/107] perf trace: Add "sendfile64" alias to the "sendfile" syscall Arnaldo Carvalho de Melo
2019-07-30  2:54 ` [PATCH 028/107] perf stat: Move loaded out of struct perf_counts_values Arnaldo Carvalho de Melo
2019-07-30  2:54 ` [PATCH 029/107] perf cpu_map: Rename struct cpu_map to struct perf_cpu_map Arnaldo Carvalho de Melo
2019-07-30  2:54 ` [PATCH 030/107] perf tools: Rename struct thread_map to struct perf_thread_map Arnaldo Carvalho de Melo
2019-07-30  2:54 ` [PATCH 031/107] perf evsel: Rename struct perf_evsel to struct evsel Arnaldo Carvalho de Melo
2019-07-30  2:54 ` [PATCH 032/107] perf evlist: Rename struct perf_evlist to struct evlist Arnaldo Carvalho de Melo
2019-07-30  2:54 ` [PATCH 033/107] perf evsel: Rename perf_evsel__init() to evsel__init() Arnaldo Carvalho de Melo
2019-07-30  2:54 ` [PATCH 034/107] perf evlist: Rename perf_evlist__init() to evlist__init() Arnaldo Carvalho de Melo
2019-07-30  2:54 ` [PATCH 035/107] perf evlist: Rename perf_evlist__new() to evlist__new() Arnaldo Carvalho de Melo
2019-07-30  2:54 ` [PATCH 036/107] perf evlist: Rename perf_evlist__delete() to evlist__delete() Arnaldo Carvalho de Melo
2019-07-30  2:55 ` [PATCH 037/107] perf evsel: Rename perf_evsel__delete() to evsel__delete() Arnaldo Carvalho de Melo
2019-07-30  2:55 ` [PATCH 038/107] perf evsel: Rename perf_evsel__new() to evsel__new() Arnaldo Carvalho de Melo
2019-07-30  2:55 ` [PATCH 039/107] perf evlist: Rename perf_evlist__add() to evlist__add() Arnaldo Carvalho de Melo
2019-07-30  2:55 ` [PATCH 040/107] perf evlist: Rename perf_evlist__remove() to evlist__remove() Arnaldo Carvalho de Melo
2019-07-30  2:55 ` [PATCH 041/107] perf evsel: Rename perf_evsel__open() to evsel__open() Arnaldo Carvalho de Melo
2019-07-30  2:55 ` [PATCH 042/107] perf evsel: Rename perf_evsel__enable() to evsel__enable() Arnaldo Carvalho de Melo
2019-07-30  2:55 ` [PATCH 043/107] perf evsel: Rename perf_evsel__disable() to evsel__disable() Arnaldo Carvalho de Melo
2019-07-30  2:55 ` [PATCH 044/107] perf evsel: Rename perf_evsel__apply_filter() to evsel__apply_filter() Arnaldo Carvalho de Melo
2019-07-30  2:55 ` [PATCH 045/107] perf evsel: Rename perf_evsel__cpus() to evsel__cpus() Arnaldo Carvalho de Melo
2019-07-30  2:55 ` [PATCH 046/107] perf evlist: Rename perf_evlist__open() to evlist__open() Arnaldo Carvalho de Melo
2019-07-30  2:55 ` [PATCH 047/107] perf evlist: Rename perf_evlist__close() to evlist__close() Arnaldo Carvalho de Melo
2019-07-30  2:55 ` [PATCH 048/107] perf evlist: Rename perf_evlist__enable() to evlist__enable() Arnaldo Carvalho de Melo
2019-07-30  2:55 ` [PATCH 049/107] perf evlist: Rename perf_evlist__disable() to evlist__disable() Arnaldo Carvalho de Melo
2019-07-30  2:55 ` [PATCH 050/107] libperf: Make libperf.a part of the perf build Arnaldo Carvalho de Melo
2019-07-30  2:55 ` [PATCH 051/107] libperf: Add build version support Arnaldo Carvalho de Melo
2019-07-30  2:55 ` [PATCH 052/107] libperf: Add libperf to the python.so build Arnaldo Carvalho de Melo
2019-07-30  2:55 ` [PATCH 053/107] libperf: Add perf/core.h header Arnaldo Carvalho de Melo
2019-07-30  2:55 ` [PATCH 054/107] libperf: Add debug output support Arnaldo Carvalho de Melo
2019-07-30  2:55 ` [PATCH 055/107] libperf: Add perf_cpu_map struct Arnaldo Carvalho de Melo
2019-07-30  2:55 ` [PATCH 056/107] libperf: Add perf_cpu_map__dummy_new() function Arnaldo Carvalho de Melo
2019-07-30  2:55 ` [PATCH 057/107] libperf: Add perf_cpu_map__get()/perf_cpu_map__put() Arnaldo Carvalho de Melo
2019-07-30  2:55 ` [PATCH 058/107] libperf: Add perf_thread_map struct Arnaldo Carvalho de Melo
2019-07-30  2:55 ` [PATCH 059/107] libperf: Add perf_thread_map__new_dummy() function Arnaldo Carvalho de Melo
2019-07-30  2:55 ` [PATCH 060/107] libperf: Add perf_thread_map__get()/perf_thread_map__put() Arnaldo Carvalho de Melo
2019-07-30  2:55 ` [PATCH 061/107] libperf: Add perf_evlist and perf_evsel structs Arnaldo Carvalho de Melo
2019-07-30  2:55 ` [PATCH 062/107] libperf: Include perf_evsel in evsel object Arnaldo Carvalho de Melo
2019-07-30  2:55 ` [PATCH 063/107] libperf: Include perf_evlist in evlist object Arnaldo Carvalho de Melo
2019-07-30  2:55 ` [PATCH 064/107] libperf: Add perf_evsel__init function Arnaldo Carvalho de Melo
2019-07-30  2:55 ` [PATCH 065/107] libperf: Add perf_evlist__init() function Arnaldo Carvalho de Melo
2019-07-30  2:55 ` [PATCH 066/107] libperf: Add perf_evlist__add() function Arnaldo Carvalho de Melo
2019-07-30  2:55 ` [PATCH 067/107] libperf: Add perf_evlist__remove() function Arnaldo Carvalho de Melo
2019-07-30  2:55 ` [PATCH 068/107] libperf: Add nr_entries to struct perf_evlist Arnaldo Carvalho de Melo
2019-07-30  2:55 ` [PATCH 069/107] libperf: Move perf_event_attr field from perf's evsel to libperf's perf_evsel Arnaldo Carvalho de Melo
2019-07-30  2:55 ` [PATCH 070/107] libperf: Add perf_cpu_map__new()/perf_cpu_map__read() functions Arnaldo Carvalho de Melo
2019-07-30  2:55 ` [PATCH 071/107] libperf: Move zalloc.o into libperf Arnaldo Carvalho de Melo
2019-07-30  2:55 ` [PATCH 072/107] libperf: Add perf_evlist__new() function Arnaldo Carvalho de Melo
2019-07-30  2:55 ` [PATCH 073/107] libperf: Add perf_evsel__new() function Arnaldo Carvalho de Melo
2019-07-30  2:55 ` [PATCH 074/107] libperf: Add perf_evlist__for_each_evsel() iterator Arnaldo Carvalho de Melo
2019-07-30  2:55 ` [PATCH 075/107] libperf: Add perf_evlist__delete() function Arnaldo Carvalho de Melo
2019-07-30  2:55 ` [PATCH 076/107] libperf: Add perf_evsel__delete() function Arnaldo Carvalho de Melo
2019-07-30  2:55 ` [PATCH 077/107] libperf: Add cpus to struct perf_evsel Arnaldo Carvalho de Melo
2019-07-30  2:55 ` [PATCH 078/107] libperf: Add own_cpus " Arnaldo Carvalho de Melo
2019-07-30  2:55 ` [PATCH 079/107] libperf: Add threads " Arnaldo Carvalho de Melo
2019-07-30  2:55 ` [PATCH 080/107] libperf: Add has_user_cpus to struct perf_evlist Arnaldo Carvalho de Melo
2019-07-30  2:55 ` [PATCH 081/107] libperf: Add cpus " Arnaldo Carvalho de Melo
2019-07-30  2:55 ` [PATCH 082/107] libperf: Add threads " Arnaldo Carvalho de Melo
2019-07-30  2:55 ` [PATCH 083/107] libperf: Add perf_evlist__set_maps() function Arnaldo Carvalho de Melo
2019-07-30  2:55 ` [PATCH 084/107] libperf: Adopt xyarray class from perf Arnaldo Carvalho de Melo
2019-07-30  2:55 ` [PATCH 085/107] libperf: Move fd array from perf's evsel to lobperf's perf_evsel class Arnaldo Carvalho de Melo
2019-07-30  2:55 ` [PATCH 086/107] libperf: Move nr_members from perf's evsel to libperf's perf_evsel Arnaldo Carvalho de Melo
2019-07-30  2:55 ` [PATCH 087/107] libperf: Adopt the readn()/writen() functions from tools/perf Arnaldo Carvalho de Melo
2019-07-30  2:55 ` [PATCH 088/107] libperf: Adopt perf_evsel__alloc_fd() function " Arnaldo Carvalho de Melo
2019-07-30  2:55 ` [PATCH 089/107] libperf: Adopt simplified perf_evsel__open() " Arnaldo Carvalho de Melo
2019-07-30  2:55 ` [PATCH 090/107] libperf: Adopt simplified perf_evsel__close() " Arnaldo Carvalho de Melo
2019-07-30  2:55 ` [PATCH 091/107] libperf: Adopt perf_evsel__read() " Arnaldo Carvalho de Melo
2019-07-30  2:55 ` [PATCH 092/107] libperf: Adopt perf_evsel__enable()/disable()/apply_filter() functions Arnaldo Carvalho de Melo
2019-07-30  2:55 ` [PATCH 093/107] libperf: Add perf_cpu_map__for_each_cpu() macro Arnaldo Carvalho de Melo
2019-07-30  2:55 ` [PATCH 094/107] libperf: Add perf_evsel__cpus()/threads() functions Arnaldo Carvalho de Melo
2019-07-30  2:55 ` [PATCH 095/107] libperf: Adopt simplified perf_evlist__open()/close() functions from tools/perf Arnaldo Carvalho de Melo
2019-07-30  2:55 ` [PATCH 096/107] libperf: Adopt perf_evlist__enable()/disable() functions from perf Arnaldo Carvalho de Melo
2019-07-30  2:56 ` [PATCH 097/107] libperf: Add perf_evsel__attr() function Arnaldo Carvalho de Melo
2019-07-30  2:56 ` [PATCH 098/107] libperf: Add install targets Arnaldo Carvalho de Melo
2019-07-30  2:56 ` [PATCH 099/107] libperf: Add tests support Arnaldo Carvalho de Melo
2019-07-30  2:56 ` [PATCH 100/107] libperf: Add perf_cpu_map test Arnaldo Carvalho de Melo
2019-07-30  2:56 ` [PATCH 101/107] libperf: Add perf_thread_map test Arnaldo Carvalho de Melo
2019-07-30  2:56 ` [PATCH 102/107] libperf: Add perf_evlist test Arnaldo Carvalho de Melo
2019-07-30  2:56 ` [PATCH 103/107] libperf: Add perf_evsel tests Arnaldo Carvalho de Melo
2019-07-30  2:56 ` [PATCH 104/107] libperf: Add perf_evlist__enable/disable test Arnaldo Carvalho de Melo
2019-07-30  2:56 ` [PATCH 105/107] libperf: Add perf_evsel__enable/disable test Arnaldo Carvalho de Melo
2019-07-30  2:56 ` [PATCH 106/107] libperf: Initial documentation Arnaldo Carvalho de Melo
2019-07-30  2:56 ` [PATCH 107/107] perf vendor events power9: Added missing event descriptions Arnaldo Carvalho de Melo
2019-07-31 11:56   ` Michael Ellerman
2019-07-30  8:03 ` [GIT PULL 000/107] perf/core improvements and fixes Ingo Molnar
2019-07-30  8:50   ` Thomas Gleixner
2019-07-30 10:13     ` Ingo Molnar

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=20190730025610.22603-27-acme@kernel.org \
    --to=acme@kernel.org \
    --cc=acme@redhat.com \
    --cc=adrian.hunter@intel.com \
    --cc=jolsa@kernel.org \
    --cc=lclaudio@redhat.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-perf-users@vger.kernel.org \
    --cc=mingo@kernel.org \
    --cc=namhyung@kernel.org \
    --cc=tglx@linutronix.de \
    --cc=williams@redhat.com \
    /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;
as well as URLs for NNTP newsgroup(s).