All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/41] perf tools: Preparation for call graph from Intel BTS
@ 2014-07-14 10:02 Adrian Hunter
  2014-07-14 10:02 ` [PATCH 01/41] perf tools: Fix the value used for unknown pids Adrian Hunter
                   ` (40 more replies)
  0 siblings, 41 replies; 122+ messages in thread
From: Adrian Hunter @ 2014-07-14 10:02 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Peter Zijlstra, linux-kernel, David Ahern, Frederic Weisbecker,
	Jiri Olsa, Namhyung Kim, Paul Mackerras, Stephane Eranian

Hi

As we discussed here:

	http://marc.info/?l=linux-kernel&m=140509286032125&w=4

here are a selection of patches based on tip/perf/core.

They can also be found here:

	http://git.infradead.org/users/ahunter/linux-perf.git/shortlog/refs/heads/for-acme


Adrian Hunter (41):
      perf tools: Fix the value used for unknown pids
      perf tools: Fix map groups of threads with unknown pids
      perf script: Display PERF_RECORD_MISC_COMM_EXEC flag
      perf record: Select comm_exec flag if supported
      perf tools: Identify which comms are from exec
      perf tools: Add machine__thread_exec_comm()
      perf tools: Fix missing kernel map load
      perf tools: Fix missing label symbols
      perf tools: Fix missing GNU IFUNC symbols
      perf inject: Fix build id injection
      perf tools: Fix appending a callchain from a previous sample
      perf tools: Fix leak of 'struct thread' on error path
      perf tools: Add machine__kernel_ip()
      perf buildid-cache: Apply force option to copying kcore
      perf script: Improve srcline display for BTS
      perf script: Do not print dangling '=>' for BTS
      perf tools: Record whether a dso is 64-bit
      perf tools: Record whether a dso has data
      perf tools: Do not attempt to read data from kallsyms
      perf tools: Let a user specify a PMU event without any config terms
      perf tools: Let default config be defined for a PMU
      perf tools: Add perf_pmu__scan_file()
      perf tools: Add dsos__hit_all()
      perf tools: Add cpu to struct thread
      perf tools: Add ability to record the current tid for each cpu
      perf tools: Add ability to iterate over a dso's symbols
      perf session: Flag if the event stream is entirely in memory
      perf evlist: Pass mmap parameters in a struct
      perf tools: Add feature test for __sync_val_compare_and_swap
      perf tools: Add option macro OPT_CALLBACK_OPTARG
      perf evlist: Add perf_evlist__set_tracking_event()
      perf evsel: Add 'no_aux_samples' option
      perf evsel: Add 'immediate' option
      perf evlist: Add 'system_wide' option
      perf tools: Add id index
      perf pmu: Let pmu's with no events show up on perf list
      perf session: Add ability to skip 4GiB or more
      perf session: Add perf_session__deliver_synth_event()
      perf tools: Allow TSC conversion on any arch
      perf tools: Move rdtsc() function
      perf evlist: Add perf_evlist__enable_event_idx()

 tools/perf/Makefile.perf                           |   2 +
 tools/perf/arch/x86/util/tsc.c                     |  31 ++--
 tools/perf/arch/x86/util/tsc.h                     |   3 -
 tools/perf/builtin-buildid-cache.c                 |   8 +-
 tools/perf/builtin-inject.c                        |   4 +
 tools/perf/builtin-sched.c                         |  12 +-
 tools/perf/builtin-script.c                        |  26 ++-
 tools/perf/config/Makefile                         |   6 +
 tools/perf/config/feature-checks/Makefile          |   4 +
 tools/perf/config/feature-checks/test-all.c        |   5 +
 .../feature-checks/test-sync-compare-and-swap.c    |  14 ++
 tools/perf/tests/perf-time-to-tsc.c                |  12 +-
 tools/perf/tests/pmu.c                             |   2 +-
 tools/perf/util/callchain.c                        |   2 +-
 tools/perf/util/comm.c                             |   7 +-
 tools/perf/util/comm.h                             |   6 +-
 tools/perf/util/dso.c                              |   6 +-
 tools/perf/util/dso.h                              |   2 +
 tools/perf/util/event.c                            |  17 +-
 tools/perf/util/event.h                            |  15 ++
 tools/perf/util/evlist.c                           | 184 +++++++++++++++----
 tools/perf/util/evlist.h                           |   5 +
 tools/perf/util/evsel.c                            |  45 ++++-
 tools/perf/util/evsel.h                            |   6 +
 tools/perf/util/header.c                           |  41 +++++
 tools/perf/util/header.h                           |   2 +
 tools/perf/util/machine.c                          | 127 +++++++++++++-
 tools/perf/util/machine.h                          |  26 +++
 tools/perf/util/map.c                              |  14 ++
 tools/perf/util/map.h                              |   1 +
 tools/perf/util/parse-events.c                     |  13 +-
 tools/perf/util/parse-events.y                     |  10 ++
 tools/perf/util/parse-options.h                    |   5 +
 tools/perf/util/pmu.c                              |  92 ++++++++--
 tools/perf/util/pmu.h                              |  13 +-
 tools/perf/util/record.c                           |  18 +-
 tools/perf/util/session.c                          | 194 +++++++++++++++++++--
 tools/perf/util/session.h                          |  18 ++
 tools/perf/util/symbol-elf.c                       |   8 +-
 tools/perf/util/symbol-minimal.c                   |  22 +++
 tools/perf/util/symbol.c                           |  20 ++-
 tools/perf/util/symbol.h                           |   4 +
 tools/perf/util/thread.c                           |  68 +++++++-
 tools/perf/util/thread.h                           |  12 +-
 tools/perf/util/tool.h                             |   3 +-
 tools/perf/util/tsc.c                              |  30 ++++
 tools/perf/util/tsc.h                              |  12 ++
 47 files changed, 1020 insertions(+), 157 deletions(-)
 create mode 100644 tools/perf/config/feature-checks/test-sync-compare-and-swap.c
 create mode 100644 tools/perf/util/tsc.c
 create mode 100644 tools/perf/util/tsc.h

 
 Regards
 Adrian

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

* [PATCH 01/41] perf tools: Fix the value used for unknown pids
  2014-07-14 10:02 [PATCH 00/41] perf tools: Preparation for call graph from Intel BTS Adrian Hunter
@ 2014-07-14 10:02 ` Adrian Hunter
  2014-07-18  4:23   ` [tip:perf/core] perf machine: " tip-bot for Adrian Hunter
  2014-07-14 10:02 ` [PATCH 02/41] perf tools: Fix map groups of threads with " Adrian Hunter
                   ` (39 subsequent siblings)
  40 siblings, 1 reply; 122+ messages in thread
From: Adrian Hunter @ 2014-07-14 10:02 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Peter Zijlstra, linux-kernel, David Ahern, Frederic Weisbecker,
	Jiri Olsa, Namhyung Kim, Paul Mackerras, Stephane Eranian

The value used for unknown pids cannot be zero
because that is used by the "idle" task.
Use -1 instead.  Also handle the unknown pid
case when creating map groups.

Note that, threads with an unknown pid should not
occur because fork (or synthesized) events precede
the thread's existence.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
 tools/perf/builtin-sched.c | 12 ++++++------
 tools/perf/util/machine.c  |  6 +++---
 tools/perf/util/session.c  |  5 +++--
 tools/perf/util/thread.c   |  2 +-
 4 files changed, 13 insertions(+), 12 deletions(-)

diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c
index c38d06c..b7f555a 100644
--- a/tools/perf/builtin-sched.c
+++ b/tools/perf/builtin-sched.c
@@ -935,8 +935,8 @@ static int latency_switch_event(struct perf_sched *sched,
 		return -1;
 	}
 
-	sched_out = machine__findnew_thread(machine, 0, prev_pid);
-	sched_in = machine__findnew_thread(machine, 0, next_pid);
+	sched_out = machine__findnew_thread(machine, -1, prev_pid);
+	sched_in = machine__findnew_thread(machine, -1, next_pid);
 
 	out_events = thread_atoms_search(&sched->atom_root, sched_out, &sched->cmp_pid);
 	if (!out_events) {
@@ -979,7 +979,7 @@ static int latency_runtime_event(struct perf_sched *sched,
 {
 	const u32 pid	   = perf_evsel__intval(evsel, sample, "pid");
 	const u64 runtime  = perf_evsel__intval(evsel, sample, "runtime");
-	struct thread *thread = machine__findnew_thread(machine, 0, pid);
+	struct thread *thread = machine__findnew_thread(machine, -1, pid);
 	struct work_atoms *atoms = thread_atoms_search(&sched->atom_root, thread, &sched->cmp_pid);
 	u64 timestamp = sample->time;
 	int cpu = sample->cpu;
@@ -1012,7 +1012,7 @@ static int latency_wakeup_event(struct perf_sched *sched,
 	struct thread *wakee;
 	u64 timestamp = sample->time;
 
-	wakee = machine__findnew_thread(machine, 0, pid);
+	wakee = machine__findnew_thread(machine, -1, pid);
 	atoms = thread_atoms_search(&sched->atom_root, wakee, &sched->cmp_pid);
 	if (!atoms) {
 		if (thread_atoms_insert(sched, wakee))
@@ -1072,7 +1072,7 @@ static int latency_migrate_task_event(struct perf_sched *sched,
 	if (sched->profile_cpu == -1)
 		return 0;
 
-	migrant = machine__findnew_thread(machine, 0, pid);
+	migrant = machine__findnew_thread(machine, -1, pid);
 	atoms = thread_atoms_search(&sched->atom_root, migrant, &sched->cmp_pid);
 	if (!atoms) {
 		if (thread_atoms_insert(sched, migrant))
@@ -1290,7 +1290,7 @@ static int map_switch_event(struct perf_sched *sched, struct perf_evsel *evsel,
 		return -1;
 	}
 
-	sched_in = machine__findnew_thread(machine, 0, next_pid);
+	sched_in = machine__findnew_thread(machine, -1, next_pid);
 
 	sched->curr_thread[this_cpu] = sched_in;
 
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index e9b943a..5b80877 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -34,7 +34,7 @@ int machine__init(struct machine *machine, const char *root_dir, pid_t pid)
 		return -ENOMEM;
 
 	if (pid != HOST_KERNEL_ID) {
-		struct thread *thread = machine__findnew_thread(machine, 0,
+		struct thread *thread = machine__findnew_thread(machine, -1,
 								pid);
 		char comm[64];
 
@@ -286,7 +286,7 @@ static struct thread *__machine__findnew_thread(struct machine *machine,
 	 * the full rbtree:
 	 */
 	if (machine->last_match && machine->last_match->tid == tid) {
-		if (pid && pid != machine->last_match->pid_)
+		if (pid != -1 && pid != machine->last_match->pid_)
 			machine->last_match->pid_ = pid;
 		return machine->last_match;
 	}
@@ -297,7 +297,7 @@ static struct thread *__machine__findnew_thread(struct machine *machine,
 
 		if (th->tid == tid) {
 			machine->last_match = th;
-			if (pid && pid != th->pid_)
+			if (pid != -1 && pid != th->pid_)
 				th->pid_ = pid;
 			return th;
 		}
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 64a186e..c2f4ca9 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -1083,13 +1083,14 @@ void perf_event_header__bswap(struct perf_event_header *hdr)
 
 struct thread *perf_session__findnew(struct perf_session *session, pid_t pid)
 {
-	return machine__findnew_thread(&session->machines.host, 0, pid);
+	return machine__findnew_thread(&session->machines.host, -1, pid);
 }
 
 static struct thread *perf_session__register_idle_thread(struct perf_session *session)
 {
-	struct thread *thread = perf_session__findnew(session, 0);
+	struct thread *thread;
 
+	thread = machine__findnew_thread(&session->machines.host, 0, 0);
 	if (thread == NULL || thread__set_comm(thread, "swapper", 0)) {
 		pr_err("problem inserting idle task.\n");
 		thread = NULL;
diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c
index 2fde0d5..7a32f44 100644
--- a/tools/perf/util/thread.c
+++ b/tools/perf/util/thread.c
@@ -13,7 +13,7 @@ int thread__init_map_groups(struct thread *thread, struct machine *machine)
 	struct thread *leader;
 	pid_t pid = thread->pid_;
 
-	if (pid == thread->tid) {
+	if (pid == thread->tid || pid == -1) {
 		thread->mg = map_groups__new();
 	} else {
 		leader = machine__findnew_thread(machine, pid, pid);
-- 
1.8.3.2


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

* [PATCH 02/41] perf tools: Fix map groups of threads with unknown pids
  2014-07-14 10:02 [PATCH 00/41] perf tools: Preparation for call graph from Intel BTS Adrian Hunter
  2014-07-14 10:02 ` [PATCH 01/41] perf tools: Fix the value used for unknown pids Adrian Hunter
@ 2014-07-14 10:02 ` Adrian Hunter
  2014-07-14 20:18   ` Arnaldo Carvalho de Melo
  2014-07-14 10:02 ` [PATCH 03/41] perf script: Display PERF_RECORD_MISC_COMM_EXEC flag Adrian Hunter
                   ` (38 subsequent siblings)
  40 siblings, 1 reply; 122+ messages in thread
From: Adrian Hunter @ 2014-07-14 10:02 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Peter Zijlstra, linux-kernel, David Ahern, Frederic Weisbecker,
	Jiri Olsa, Namhyung Kim, Paul Mackerras, Stephane Eranian

Events like sched_switch do not provide a pid (tgid)
which can result in threads with an unknown pid.  If
the pid is later discovered, join the map groups.
Note the thread's map groups should be empty because
they are populated by MMAP events which do provide the
pid and tid.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
 tools/perf/util/machine.c | 22 ++++++++++++++++------
 tools/perf/util/map.c     | 14 ++++++++++++++
 tools/perf/util/map.h     |  1 +
 tools/perf/util/thread.c  | 35 +++++++++++++++++++++++++++++++++++
 tools/perf/util/thread.h  |  1 +
 5 files changed, 67 insertions(+), 6 deletions(-)

diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index 5b80877..0fa93c1 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -272,6 +272,17 @@ void machines__set_id_hdr_size(struct machines *machines, u16 id_hdr_size)
 	return;
 }
 
+static void machine__update_thread_pid(struct machine *machine,
+				       struct thread *th, pid_t pid)
+{
+	if (pid != th->pid_ && pid != -1 && th->pid_ == -1) {
+		th->pid_ = pid;
+		if (thread__join_map_groups(th, machine))
+			pr_err("Failed to join map groups for %d:%d\n",
+			       th->pid_, th->tid);
+	}
+}
+
 static struct thread *__machine__findnew_thread(struct machine *machine,
 						pid_t pid, pid_t tid,
 						bool create)
@@ -285,10 +296,10 @@ static struct thread *__machine__findnew_thread(struct machine *machine,
 	 * so most of the time we dont have to look up
 	 * the full rbtree:
 	 */
-	if (machine->last_match && machine->last_match->tid == tid) {
-		if (pid != -1 && pid != machine->last_match->pid_)
-			machine->last_match->pid_ = pid;
-		return machine->last_match;
+	th = machine->last_match;
+	if (th && th->tid == tid) {
+		machine__update_thread_pid(machine, th, pid);
+		return th;
 	}
 
 	while (*p != NULL) {
@@ -297,8 +308,7 @@ static struct thread *__machine__findnew_thread(struct machine *machine,
 
 		if (th->tid == tid) {
 			machine->last_match = th;
-			if (pid != -1 && pid != th->pid_)
-				th->pid_ = pid;
+			machine__update_thread_pid(machine, th, pid);
 			return th;
 		}
 
diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c
index 25c571f..7af1480 100644
--- a/tools/perf/util/map.c
+++ b/tools/perf/util/map.c
@@ -454,6 +454,20 @@ void map_groups__exit(struct map_groups *mg)
 	}
 }
 
+bool map_groups__empty(struct map_groups *mg)
+{
+	int i;
+
+	for (i = 0; i < MAP__NR_TYPES; ++i) {
+		if (maps__first(&mg->maps[i]))
+			return false;
+		if (!list_empty(&mg->removed_maps[i]))
+			return false;
+	}
+
+	return true;
+}
+
 struct map_groups *map_groups__new(void)
 {
 	struct map_groups *mg = malloc(sizeof(*mg));
diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h
index 7758c72..5806a90 100644
--- a/tools/perf/util/map.h
+++ b/tools/perf/util/map.h
@@ -66,6 +66,7 @@ struct map_groups {
 
 struct map_groups *map_groups__new(void);
 void map_groups__delete(struct map_groups *mg);
+bool map_groups__empty(struct map_groups *mg);
 
 static inline struct map_groups *map_groups__get(struct map_groups *mg)
 {
diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c
index 7a32f44..ca94295 100644
--- a/tools/perf/util/thread.c
+++ b/tools/perf/util/thread.c
@@ -24,6 +24,41 @@ int thread__init_map_groups(struct thread *thread, struct machine *machine)
 	return thread->mg ? 0 : -1;
 }
 
+int thread__join_map_groups(struct thread *thread, struct machine *machine)
+{
+	struct thread *leader;
+	pid_t pid = thread->pid_;
+
+	if (pid == thread->tid)
+		return 0;
+
+	leader = machine__findnew_thread(machine, pid, pid);
+	if (!leader)
+		return -ENOMEM;
+
+	if (!leader->mg)
+		leader->mg = map_groups__new();
+
+	if (!leader->mg)
+		return -ENOMEM;
+
+	if (thread->mg) {
+		/*
+		 * Maps are created from MMAP events which provide the pid and
+		 * tid.  Consequently there never should be any maps on a thread
+		 * with an unknown pid.  Just print an error if there are.
+		 */
+		if (!map_groups__empty(thread->mg))
+			pr_err("Discarding thread maps for %d:%d\n",
+			       thread->pid_, thread->tid);
+		map_groups__delete(thread->mg);
+	}
+
+	thread->mg = map_groups__get(leader->mg);
+
+	return 0;
+}
+
 struct thread *thread__new(pid_t pid, pid_t tid)
 {
 	char *comm_str;
diff --git a/tools/perf/util/thread.h b/tools/perf/util/thread.h
index 3c0c272..9de0629 100644
--- a/tools/perf/util/thread.h
+++ b/tools/perf/util/thread.h
@@ -31,6 +31,7 @@ struct comm;
 
 struct thread *thread__new(pid_t pid, pid_t tid);
 int thread__init_map_groups(struct thread *thread, struct machine *machine);
+int thread__join_map_groups(struct thread *thread, struct machine *machine);
 void thread__delete(struct thread *thread);
 static inline void thread__exited(struct thread *thread)
 {
-- 
1.8.3.2


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

* [PATCH 03/41] perf script: Display PERF_RECORD_MISC_COMM_EXEC flag
  2014-07-14 10:02 [PATCH 00/41] perf tools: Preparation for call graph from Intel BTS Adrian Hunter
  2014-07-14 10:02 ` [PATCH 01/41] perf tools: Fix the value used for unknown pids Adrian Hunter
  2014-07-14 10:02 ` [PATCH 02/41] perf tools: Fix map groups of threads with " Adrian Hunter
@ 2014-07-14 10:02 ` Adrian Hunter
  2014-07-18  4:23   ` [tip:perf/core] " tip-bot for Adrian Hunter
  2014-07-14 10:02 ` [PATCH 04/41] perf record: Select comm_exec flag if supported Adrian Hunter
                   ` (37 subsequent siblings)
  40 siblings, 1 reply; 122+ messages in thread
From: Adrian Hunter @ 2014-07-14 10:02 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Peter Zijlstra, linux-kernel, David Ahern, Frederic Weisbecker,
	Jiri Olsa, Namhyung Kim, Paul Mackerras, Stephane Eranian

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
 tools/perf/util/event.c | 9 ++++++++-
 tools/perf/util/evsel.c | 3 ++-
 2 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index d0281bd..198c4cc 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -603,7 +603,14 @@ int perf_event__synthesize_kernel_mmap(struct perf_tool *tool,
 
 size_t perf_event__fprintf_comm(union perf_event *event, FILE *fp)
 {
-	return fprintf(fp, ": %s:%d\n", event->comm.comm, event->comm.tid);
+	const char *s;
+
+	if (event->header.misc & PERF_RECORD_MISC_COMM_EXEC)
+		s = " exec";
+	else
+		s = "";
+
+	return fprintf(fp, "%s: %s:%d\n", s, event->comm.comm, event->comm.tid);
 }
 
 int perf_event__process_comm(struct perf_tool *tool __maybe_unused,
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 8606175..b760d32 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -960,6 +960,7 @@ static size_t perf_event_attr__fprintf(struct perf_event_attr *attr, FILE *fp)
 	ret += PRINT_ATTR2(exclude_user, exclude_kernel);
 	ret += PRINT_ATTR2(exclude_hv, exclude_idle);
 	ret += PRINT_ATTR2(mmap, comm);
+	ret += PRINT_ATTR2(mmap2, comm_exec);
 	ret += PRINT_ATTR2(freq, inherit_stat);
 	ret += PRINT_ATTR2(enable_on_exec, task);
 	ret += PRINT_ATTR2(watermark, precise_ip);
@@ -967,7 +968,6 @@ static size_t perf_event_attr__fprintf(struct perf_event_attr *attr, FILE *fp)
 	ret += PRINT_ATTR2(exclude_host, exclude_guest);
 	ret += PRINT_ATTR2N("excl.callchain_kern", exclude_callchain_kernel,
 			    "excl.callchain_user", exclude_callchain_user);
-	ret += PRINT_ATTR_U32(mmap2);
 
 	ret += PRINT_ATTR_U32(wakeup_events);
 	ret += PRINT_ATTR_U32(wakeup_watermark);
@@ -1940,6 +1940,7 @@ int perf_evsel__fprintf(struct perf_evsel *evsel,
 		if_print(mmap);
 		if_print(mmap2);
 		if_print(comm);
+		if_print(comm_exec);
 		if_print(freq);
 		if_print(inherit_stat);
 		if_print(enable_on_exec);
-- 
1.8.3.2


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

* [PATCH 04/41] perf record: Select comm_exec flag if supported
  2014-07-14 10:02 [PATCH 00/41] perf tools: Preparation for call graph from Intel BTS Adrian Hunter
                   ` (2 preceding siblings ...)
  2014-07-14 10:02 ` [PATCH 03/41] perf script: Display PERF_RECORD_MISC_COMM_EXEC flag Adrian Hunter
@ 2014-07-14 10:02 ` Adrian Hunter
  2014-07-18  4:23   ` [tip:perf/core] " tip-bot for Adrian Hunter
  2014-07-14 10:02 ` [PATCH 05/41] perf tools: Identify which comms are from exec Adrian Hunter
                   ` (36 subsequent siblings)
  40 siblings, 1 reply; 122+ messages in thread
From: Adrian Hunter @ 2014-07-14 10:02 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Peter Zijlstra, linux-kernel, David Ahern, Frederic Weisbecker,
	Jiri Olsa, Namhyung Kim, Paul Mackerras, Stephane Eranian

The comm_exec flag on the attribute can later
be found in the perf.data file allowing a
tool to know in advance if the captured data
has the flag.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
 tools/perf/util/record.c | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/tools/perf/util/record.c b/tools/perf/util/record.c
index 049e0a0..1657231 100644
--- a/tools/perf/util/record.c
+++ b/tools/perf/util/record.c
@@ -69,15 +69,26 @@ static void perf_probe_sample_identifier(struct perf_evsel *evsel)
 	evsel->attr.sample_type |= PERF_SAMPLE_IDENTIFIER;
 }
 
+static void perf_probe_comm_exec(struct perf_evsel *evsel)
+{
+	evsel->attr.comm_exec = 1;
+}
+
 bool perf_can_sample_identifier(void)
 {
 	return perf_probe_api(perf_probe_sample_identifier);
 }
 
+static bool perf_can_comm_exec(void)
+{
+	return perf_probe_api(perf_probe_comm_exec);
+}
+
 void perf_evlist__config(struct perf_evlist *evlist, struct record_opts *opts)
 {
 	struct perf_evsel *evsel;
 	bool use_sample_identifier = false;
+	bool use_comm_exec;
 
 	/*
 	 * Set the evsel leader links before we configure attributes,
@@ -89,8 +100,13 @@ void perf_evlist__config(struct perf_evlist *evlist, struct record_opts *opts)
 	if (evlist->cpus->map[0] < 0)
 		opts->no_inherit = true;
 
-	evlist__for_each(evlist, evsel)
+	use_comm_exec = perf_can_comm_exec();
+
+	evlist__for_each(evlist, evsel) {
 		perf_evsel__config(evsel, opts);
+		if (!evsel->idx && use_comm_exec)
+			evsel->attr.comm_exec = 1;
+	}
 
 	if (evlist->nr_entries > 1) {
 		struct perf_evsel *first = perf_evlist__first(evlist);
-- 
1.8.3.2


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

* [PATCH 05/41] perf tools: Identify which comms are from exec
  2014-07-14 10:02 [PATCH 00/41] perf tools: Preparation for call graph from Intel BTS Adrian Hunter
                   ` (3 preceding siblings ...)
  2014-07-14 10:02 ` [PATCH 04/41] perf record: Select comm_exec flag if supported Adrian Hunter
@ 2014-07-14 10:02 ` Adrian Hunter
  2014-07-14 20:32   ` Arnaldo Carvalho de Melo
  2014-07-14 10:02 ` [PATCH 06/41] perf tools: Add machine__thread_exec_comm() Adrian Hunter
                   ` (35 subsequent siblings)
  40 siblings, 1 reply; 122+ messages in thread
From: Adrian Hunter @ 2014-07-14 10:02 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Peter Zijlstra, linux-kernel, David Ahern, Frederic Weisbecker,
	Jiri Olsa, Namhyung Kim, Paul Mackerras, Stephane Eranian

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
 tools/perf/util/comm.c    |  7 +++++--
 tools/perf/util/comm.h    |  6 ++++--
 tools/perf/util/machine.c |  4 +++-
 tools/perf/util/thread.c  | 24 +++++++++++++++++++-----
 tools/perf/util/thread.h  | 10 +++++++++-
 5 files changed, 40 insertions(+), 11 deletions(-)

diff --git a/tools/perf/util/comm.c b/tools/perf/util/comm.c
index f9e7776..5e1e80e 100644
--- a/tools/perf/util/comm.c
+++ b/tools/perf/util/comm.c
@@ -74,7 +74,7 @@ static struct comm_str *comm_str__findnew(const char *str, struct rb_root *root)
 	return new;
 }
 
-struct comm *comm__new(const char *str, u64 timestamp)
+struct comm *comm__new(const char *str, u64 timestamp, bool exec)
 {
 	struct comm *comm = zalloc(sizeof(*comm));
 
@@ -82,6 +82,7 @@ struct comm *comm__new(const char *str, u64 timestamp)
 		return NULL;
 
 	comm->start = timestamp;
+	comm->exec = exec;
 
 	comm->comm_str = comm_str__findnew(str, &comm_str_root);
 	if (!comm->comm_str) {
@@ -94,7 +95,7 @@ struct comm *comm__new(const char *str, u64 timestamp)
 	return comm;
 }
 
-int comm__override(struct comm *comm, const char *str, u64 timestamp)
+int comm__override(struct comm *comm, const char *str, u64 timestamp, bool exec)
 {
 	struct comm_str *new, *old = comm->comm_str;
 
@@ -106,6 +107,8 @@ int comm__override(struct comm *comm, const char *str, u64 timestamp)
 	comm_str__put(old);
 	comm->comm_str = new;
 	comm->start = timestamp;
+	if (exec && !comm->exec)
+		comm->exec = true;
 
 	return 0;
 }
diff --git a/tools/perf/util/comm.h b/tools/perf/util/comm.h
index fac5bd5..51c10ab 100644
--- a/tools/perf/util/comm.h
+++ b/tools/perf/util/comm.h
@@ -11,11 +11,13 @@ struct comm {
 	struct comm_str *comm_str;
 	u64 start;
 	struct list_head list;
+	bool exec;
 };
 
 void comm__free(struct comm *comm);
-struct comm *comm__new(const char *str, u64 timestamp);
+struct comm *comm__new(const char *str, u64 timestamp, bool exec);
 const char *comm__str(const struct comm *comm);
-int comm__override(struct comm *comm, const char *str, u64 timestamp);
+int comm__override(struct comm *comm, const char *str, u64 timestamp,
+		   bool exec);
 
 #endif  /* __PERF_COMM_H */
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index 0fa93c1..2513204 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -360,11 +360,13 @@ int machine__process_comm_event(struct machine *machine, union perf_event *event
 	struct thread *thread = machine__findnew_thread(machine,
 							event->comm.pid,
 							event->comm.tid);
+	bool exec = event->header.misc & PERF_RECORD_MISC_COMM_EXEC;
 
 	if (dump_trace)
 		perf_event__fprintf_comm(event, stdout);
 
-	if (thread == NULL || thread__set_comm(thread, event->comm.comm, sample->time)) {
+	if (thread == NULL ||
+	    __thread__set_comm(thread, event->comm.comm, sample->time, exec)) {
 		dump_printf("problem processing PERF_RECORD_COMM, skipping event.\n");
 		return -1;
 	}
diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c
index ca94295..149e417 100644
--- a/tools/perf/util/thread.c
+++ b/tools/perf/util/thread.c
@@ -76,7 +76,7 @@ struct thread *thread__new(pid_t pid, pid_t tid)
 			goto err_thread;
 
 		snprintf(comm_str, 32, ":%d", tid);
-		comm = comm__new(comm_str, 0);
+		comm = comm__new(comm_str, 0, false);
 		free(comm_str);
 		if (!comm)
 			goto err_thread;
@@ -113,19 +113,33 @@ struct comm *thread__comm(const struct thread *thread)
 	return list_first_entry(&thread->comm_list, struct comm, list);
 }
 
+struct comm *thread__exec_comm(const struct thread *thread)
+{
+	struct comm *comm, *last = NULL;
+
+	list_for_each_entry(comm, &thread->comm_list, list) {
+		if (comm->exec)
+			return comm;
+		last = comm;
+	}
+
+	return last;
+}
+
 /* CHECKME: time should always be 0 if event aren't ordered */
-int thread__set_comm(struct thread *thread, const char *str, u64 timestamp)
+int __thread__set_comm(struct thread *thread, const char *str, u64 timestamp,
+		       bool exec)
 {
 	struct comm *new, *curr = thread__comm(thread);
 	int err;
 
 	/* Override latest entry if it had no specific time coverage */
-	if (!curr->start) {
-		err = comm__override(curr, str, timestamp);
+	if (!curr->start && !curr->exec) {
+		err = comm__override(curr, str, timestamp, exec);
 		if (err)
 			return err;
 	} else {
-		new = comm__new(str, timestamp);
+		new = comm__new(str, timestamp, exec);
 		if (!new)
 			return -ENOMEM;
 		list_add(&new->list, &thread->comm_list);
diff --git a/tools/perf/util/thread.h b/tools/perf/util/thread.h
index 9de0629..b4269af 100644
--- a/tools/perf/util/thread.h
+++ b/tools/perf/util/thread.h
@@ -38,9 +38,17 @@ static inline void thread__exited(struct thread *thread)
 	thread->dead = true;
 }
 
-int thread__set_comm(struct thread *thread, const char *comm, u64 timestamp);
+int __thread__set_comm(struct thread *thread, const char *comm, u64 timestamp,
+		       bool exec);
+static inline int thread__set_comm(struct thread *thread, const char *comm,
+				   u64 timestamp)
+{
+	return __thread__set_comm(thread, comm, timestamp, false);
+}
+
 int thread__comm_len(struct thread *thread);
 struct comm *thread__comm(const struct thread *thread);
+struct comm *thread__exec_comm(const struct thread *thread);
 const char *thread__comm_str(const struct thread *thread);
 void thread__insert_map(struct thread *thread, struct map *map);
 int thread__fork(struct thread *thread, struct thread *parent, u64 timestamp);
-- 
1.8.3.2


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

* [PATCH 06/41] perf tools: Add machine__thread_exec_comm()
  2014-07-14 10:02 [PATCH 00/41] perf tools: Preparation for call graph from Intel BTS Adrian Hunter
                   ` (4 preceding siblings ...)
  2014-07-14 10:02 ` [PATCH 05/41] perf tools: Identify which comms are from exec Adrian Hunter
@ 2014-07-14 10:02 ` Adrian Hunter
  2014-07-14 10:02 ` [PATCH 07/41] perf tools: Fix missing kernel map load Adrian Hunter
                   ` (34 subsequent siblings)
  40 siblings, 0 replies; 122+ messages in thread
From: Adrian Hunter @ 2014-07-14 10:02 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Peter Zijlstra, linux-kernel, David Ahern, Frederic Weisbecker,
	Jiri Olsa, Namhyung Kim, Paul Mackerras, Stephane Eranian

Add machine__thread_exec_comm() to return the comm
that matches the last exec, if the comm_exec flag
is present, or the last comm otherwise.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
 tools/perf/util/machine.c | 26 ++++++++++++++++++++++++++
 tools/perf/util/machine.h |  4 ++++
 tools/perf/util/session.c | 24 +++++++++++++++++++++++-
 3 files changed, 53 insertions(+), 1 deletion(-)

diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index 2513204..c1c5ca3 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -28,6 +28,7 @@ int machine__init(struct machine *machine, const char *root_dir, pid_t pid)
 
 	machine->symbol_filter = NULL;
 	machine->id_hdr_size = 0;
+	machine->comm_exec = false;
 
 	machine->root_dir = strdup(root_dir);
 	if (machine->root_dir == NULL)
@@ -172,6 +173,19 @@ void machines__set_symbol_filter(struct machines *machines,
 	}
 }
 
+void machines__set_comm_exec(struct machines *machines, bool comm_exec)
+{
+	struct rb_node *nd;
+
+	machines->host.comm_exec = comm_exec;
+
+	for (nd = rb_first(&machines->guests); nd; nd = rb_next(nd)) {
+		struct machine *machine = rb_entry(nd, struct machine, rb_node);
+
+		machine->comm_exec = comm_exec;
+	}
+}
+
 struct machine *machines__find(struct machines *machines, pid_t pid)
 {
 	struct rb_node **p = &machines->guests.rb_node;
@@ -354,6 +368,15 @@ struct thread *machine__find_thread(struct machine *machine, pid_t pid,
 	return __machine__findnew_thread(machine, pid, tid, false);
 }
 
+struct comm *machine__thread_exec_comm(struct machine *machine,
+				       struct thread *thread)
+{
+	if (machine->comm_exec)
+		return thread__exec_comm(thread);
+	else
+		return thread__comm(thread);
+}
+
 int machine__process_comm_event(struct machine *machine, union perf_event *event,
 				struct perf_sample *sample)
 {
@@ -362,6 +385,9 @@ int machine__process_comm_event(struct machine *machine, union perf_event *event
 							event->comm.tid);
 	bool exec = event->header.misc & PERF_RECORD_MISC_COMM_EXEC;
 
+	if (exec)
+		machine->comm_exec = true;
+
 	if (dump_trace)
 		perf_event__fprintf_comm(event, stdout);
 
diff --git a/tools/perf/util/machine.h b/tools/perf/util/machine.h
index c8c74a1..383c725 100644
--- a/tools/perf/util/machine.h
+++ b/tools/perf/util/machine.h
@@ -24,6 +24,7 @@ struct machine {
 	struct rb_node	  rb_node;
 	pid_t		  pid;
 	u16		  id_hdr_size;
+	bool		  comm_exec;
 	char		  *root_dir;
 	struct rb_root	  threads;
 	struct list_head  dead_threads;
@@ -43,6 +44,8 @@ struct map *machine__kernel_map(struct machine *machine, enum map_type type)
 
 struct thread *machine__find_thread(struct machine *machine, pid_t pid,
 				    pid_t tid);
+struct comm *machine__thread_exec_comm(struct machine *machine,
+				       struct thread *thread);
 
 int machine__process_comm_event(struct machine *machine, union perf_event *event,
 				struct perf_sample *sample);
@@ -84,6 +87,7 @@ char *machine__mmap_name(struct machine *machine, char *bf, size_t size);
 
 void machines__set_symbol_filter(struct machines *machines,
 				 symbol_filter_t symbol_filter);
+void machines__set_comm_exec(struct machines *machines, bool comm_exec);
 
 struct machine *machine__new_host(void);
 int machine__init(struct machine *machine, const char *root_dir, pid_t pid);
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index c2f4ca9..c1abe6b 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -67,6 +67,25 @@ static void perf_session__destroy_kernel_maps(struct perf_session *session)
 	machines__destroy_kernel_maps(&session->machines);
 }
 
+static bool perf_session__has_comm_exec(struct perf_session *session)
+{
+	struct perf_evsel *evsel;
+
+	evlist__for_each(session->evlist, evsel) {
+		if (evsel->attr.comm_exec)
+			return true;
+	}
+
+	return false;
+}
+
+static void perf_session__set_comm_exec(struct perf_session *session)
+{
+	bool comm_exec = perf_session__has_comm_exec(session);
+
+	machines__set_comm_exec(&session->machines, comm_exec);
+}
+
 struct perf_session *perf_session__new(struct perf_data_file *file,
 				       bool repipe, struct perf_tool *tool)
 {
@@ -92,6 +111,7 @@ struct perf_session *perf_session__new(struct perf_data_file *file,
 				goto out_close;
 
 			perf_session__set_id_hdr_size(session);
+			perf_session__set_comm_exec(session);
 		}
 	}
 
@@ -1006,8 +1026,10 @@ static int perf_session__process_user_event(struct perf_session *session, union
 	switch (event->header.type) {
 	case PERF_RECORD_HEADER_ATTR:
 		err = tool->attr(tool, event, &session->evlist);
-		if (err == 0)
+		if (err == 0) {
 			perf_session__set_id_hdr_size(session);
+			perf_session__set_comm_exec(session);
+		}
 		return err;
 	case PERF_RECORD_HEADER_EVENT_TYPE:
 		/*
-- 
1.8.3.2


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

* [PATCH 07/41] perf tools: Fix missing kernel map load
  2014-07-14 10:02 [PATCH 00/41] perf tools: Preparation for call graph from Intel BTS Adrian Hunter
                   ` (5 preceding siblings ...)
  2014-07-14 10:02 ` [PATCH 06/41] perf tools: Add machine__thread_exec_comm() Adrian Hunter
@ 2014-07-14 10:02 ` Adrian Hunter
  2014-07-18  4:23   ` [tip:perf/core] " tip-bot for Adrian Hunter
  2014-07-14 10:02 ` [PATCH 08/41] perf tools: Fix missing label symbols Adrian Hunter
                   ` (33 subsequent siblings)
  40 siblings, 1 reply; 122+ messages in thread
From: Adrian Hunter @ 2014-07-14 10:02 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Peter Zijlstra, linux-kernel, David Ahern, Frederic Weisbecker,
	Jiri Olsa, Namhyung Kim, Paul Mackerras, Stephane Eranian

thread__find_addr_map() falls back to trying
the kernel maps if the address is negative and
is not found in userspace maps.  As commented
in the code, the kernel maps must be "loaded"
before use.  This patch ensures that happens
under the fallback condition also.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
 tools/perf/util/event.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index 198c4cc..7e0e8ae 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -788,6 +788,7 @@ try_again:
 		    cpumode == PERF_RECORD_MISC_USER &&
 		    machine && mg != &machine->kmaps) {
 			mg = &machine->kmaps;
+			load_map = true;
 			goto try_again;
 		}
 	} else {
-- 
1.8.3.2


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

* [PATCH 08/41] perf tools: Fix missing label symbols
  2014-07-14 10:02 [PATCH 00/41] perf tools: Preparation for call graph from Intel BTS Adrian Hunter
                   ` (6 preceding siblings ...)
  2014-07-14 10:02 ` [PATCH 07/41] perf tools: Fix missing kernel map load Adrian Hunter
@ 2014-07-14 10:02 ` Adrian Hunter
  2014-07-14 20:38   ` Arnaldo Carvalho de Melo
  2014-07-14 10:02 ` [PATCH 09/41] perf tools: Fix missing GNU IFUNC symbols Adrian Hunter
                   ` (32 subsequent siblings)
  40 siblings, 1 reply; 122+ messages in thread
From: Adrian Hunter @ 2014-07-14 10:02 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Peter Zijlstra, linux-kernel, David Ahern, Frederic Weisbecker,
	Jiri Olsa, Namhyung Kim, Paul Mackerras, Stephane Eranian

label symbols are missing because elf_sec__is_a() fails
to find the section because the section strings do not
match the section headers because the sections headers
are from the 'runtime' object and the sections strings
are from the 'symbol source' object.

Fix by getting the section strings from the 'runtime'
object so that they match the section headers.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
 tools/perf/util/symbol-elf.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c
index 6864661..8c96817 100644
--- a/tools/perf/util/symbol-elf.c
+++ b/tools/perf/util/symbol-elf.c
@@ -732,7 +732,7 @@ int dso__load_sym(struct dso *dso, struct map *map,
 	if (symstrs == NULL)
 		goto out_elf_end;
 
-	sec_strndx = elf_getscn(elf, ehdr.e_shstrndx);
+	sec_strndx = elf_getscn(runtime_ss->elf, runtime_ss->ehdr.e_shstrndx);
 	if (sec_strndx == NULL)
 		goto out_elf_end;
 
-- 
1.8.3.2


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

* [PATCH 09/41] perf tools: Fix missing GNU IFUNC symbols
  2014-07-14 10:02 [PATCH 00/41] perf tools: Preparation for call graph from Intel BTS Adrian Hunter
                   ` (7 preceding siblings ...)
  2014-07-14 10:02 ` [PATCH 08/41] perf tools: Fix missing label symbols Adrian Hunter
@ 2014-07-14 10:02 ` Adrian Hunter
  2014-07-18  4:24   ` [tip:perf/core] perf symbols: " tip-bot for Adrian Hunter
  2014-07-14 10:02 ` [PATCH 10/41] perf inject: Fix build id injection Adrian Hunter
                   ` (31 subsequent siblings)
  40 siblings, 1 reply; 122+ messages in thread
From: Adrian Hunter @ 2014-07-14 10:02 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Peter Zijlstra, linux-kernel, David Ahern, Frederic Weisbecker,
	Jiri Olsa, Namhyung Kim, Paul Mackerras, Stephane Eranian

Symbols of type STT_GNU_IFUNC are functions
so accept them as such.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
 tools/perf/util/symbol-elf.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c
index 8c96817..477596c 100644
--- a/tools/perf/util/symbol-elf.c
+++ b/tools/perf/util/symbol-elf.c
@@ -49,7 +49,8 @@ static inline uint8_t elf_sym__type(const GElf_Sym *sym)
 
 static inline int elf_sym__is_function(const GElf_Sym *sym)
 {
-	return elf_sym__type(sym) == STT_FUNC &&
+	return (elf_sym__type(sym) == STT_FUNC ||
+		elf_sym__type(sym) == STT_GNU_IFUNC) &&
 	       sym->st_name != 0 &&
 	       sym->st_shndx != SHN_UNDEF;
 }
-- 
1.8.3.2


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

* [PATCH 10/41] perf inject: Fix build id injection
  2014-07-14 10:02 [PATCH 00/41] perf tools: Preparation for call graph from Intel BTS Adrian Hunter
                   ` (8 preceding siblings ...)
  2014-07-14 10:02 ` [PATCH 09/41] perf tools: Fix missing GNU IFUNC symbols Adrian Hunter
@ 2014-07-14 10:02 ` Adrian Hunter
  2014-07-18  4:24   ` [tip:perf/core] " tip-bot for Adrian Hunter
  2014-07-14 10:02 ` [PATCH 11/41] perf tools: Fix appending a callchain from a previous sample Adrian Hunter
                   ` (30 subsequent siblings)
  40 siblings, 1 reply; 122+ messages in thread
From: Adrian Hunter @ 2014-07-14 10:02 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Peter Zijlstra, linux-kernel, David Ahern, Frederic Weisbecker,
	Jiri Olsa, Namhyung Kim, Paul Mackerras, Stephane Eranian

Build Ids won't be injected unless the build id
feature flag is set.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
 tools/perf/builtin-inject.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c
index 16c7c11..cf6a605 100644
--- a/tools/perf/builtin-inject.c
+++ b/tools/perf/builtin-inject.c
@@ -389,6 +389,9 @@ static int __cmd_inject(struct perf_inject *inject)
 	ret = perf_session__process_events(session, &inject->tool);
 
 	if (!file_out->is_pipe) {
+		if (inject->build_ids)
+			perf_header__set_feat(&session->header,
+					      HEADER_BUILD_ID);
 		session->header.data_size = inject->bytes_written;
 		perf_session__write_header(session, session->evlist, file_out->fd, true);
 	}
-- 
1.8.3.2


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

* [PATCH 11/41] perf tools: Fix appending a callchain from a previous sample
  2014-07-14 10:02 [PATCH 00/41] perf tools: Preparation for call graph from Intel BTS Adrian Hunter
                   ` (9 preceding siblings ...)
  2014-07-14 10:02 ` [PATCH 10/41] perf inject: Fix build id injection Adrian Hunter
@ 2014-07-14 10:02 ` Adrian Hunter
  2014-07-18  4:24   ` [tip:perf/core] perf callchain: " tip-bot for Adrian Hunter
  2014-07-14 10:02 ` [PATCH 12/41] perf tools: Fix leak of 'struct thread' on error path Adrian Hunter
                   ` (29 subsequent siblings)
  40 siblings, 1 reply; 122+ messages in thread
From: Adrian Hunter @ 2014-07-14 10:02 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Peter Zijlstra, linux-kernel, David Ahern, Frederic Weisbecker,
	Jiri Olsa, Namhyung Kim, Paul Mackerras, Stephane Eranian

hist_entry__append_callchain() must check if the sample
has a callcahin or it will append the callchain from
a previous sample.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
 tools/perf/util/callchain.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c
index 48b6d3f..437ee09 100644
--- a/tools/perf/util/callchain.c
+++ b/tools/perf/util/callchain.c
@@ -626,7 +626,7 @@ int sample__resolve_callchain(struct perf_sample *sample, struct symbol **parent
 
 int hist_entry__append_callchain(struct hist_entry *he, struct perf_sample *sample)
 {
-	if (!symbol_conf.use_callchain)
+	if (!symbol_conf.use_callchain || sample->callchain == NULL)
 		return 0;
 	return callchain_append(he->callchain, &callchain_cursor, sample->period);
 }
-- 
1.8.3.2


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

* [PATCH 12/41] perf tools: Fix leak of 'struct thread' on error path
  2014-07-14 10:02 [PATCH 00/41] perf tools: Preparation for call graph from Intel BTS Adrian Hunter
                   ` (10 preceding siblings ...)
  2014-07-14 10:02 ` [PATCH 11/41] perf tools: Fix appending a callchain from a previous sample Adrian Hunter
@ 2014-07-14 10:02 ` Adrian Hunter
  2014-07-14 20:43   ` Arnaldo Carvalho de Melo
  2014-07-16 14:02   ` [PATCH 12/41] perf tools: " Jiri Olsa
  2014-07-14 10:02 ` [PATCH 13/41] perf tools: Add machine__kernel_ip() Adrian Hunter
                   ` (28 subsequent siblings)
  40 siblings, 2 replies; 122+ messages in thread
From: Adrian Hunter @ 2014-07-14 10:02 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Peter Zijlstra, linux-kernel, David Ahern, Frederic Weisbecker,
	Jiri Olsa, Namhyung Kim, Paul Mackerras, Stephane Eranian

__machine__findnew_thread() creates a 'struct thread'
but does not free it on the error path.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
 tools/perf/util/machine.c | 4 +++-
 tools/perf/util/thread.c  | 6 ++++--
 2 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index c1c5ca3..18eaf31 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -349,8 +349,10 @@ static struct thread *__machine__findnew_thread(struct machine *machine,
 		 * within thread__init_map_groups to find the thread
 		 * leader and that would screwed the rb tree.
 		 */
-		if (thread__init_map_groups(th, machine))
+		if (thread__init_map_groups(th, machine)) {
+			thread__delete(th);
 			return NULL;
+		}
 	}
 
 	return th;
diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c
index 149e417..b9a3ee4 100644
--- a/tools/perf/util/thread.c
+++ b/tools/perf/util/thread.c
@@ -95,8 +95,10 @@ void thread__delete(struct thread *thread)
 {
 	struct comm *comm, *tmp;
 
-	map_groups__put(thread->mg);
-	thread->mg = NULL;
+	if (thread->mg) {
+		map_groups__put(thread->mg);
+		thread->mg = NULL;
+	}
 	list_for_each_entry_safe(comm, tmp, &thread->comm_list, list) {
 		list_del(&comm->list);
 		comm__free(comm);
-- 
1.8.3.2


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

* [PATCH 13/41] perf tools: Add machine__kernel_ip()
  2014-07-14 10:02 [PATCH 00/41] perf tools: Preparation for call graph from Intel BTS Adrian Hunter
                   ` (11 preceding siblings ...)
  2014-07-14 10:02 ` [PATCH 12/41] perf tools: Fix leak of 'struct thread' on error path Adrian Hunter
@ 2014-07-14 10:02 ` Adrian Hunter
  2014-07-16 14:15   ` Jiri Olsa
  2014-07-14 10:02 ` [PATCH 14/41] perf buildid-cache: Apply force option to copying kcore Adrian Hunter
                   ` (27 subsequent siblings)
  40 siblings, 1 reply; 122+ messages in thread
From: Adrian Hunter @ 2014-07-14 10:02 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Peter Zijlstra, linux-kernel, David Ahern, Frederic Weisbecker,
	Jiri Olsa, Namhyung Kim, Paul Mackerras, Stephane Eranian

Add a function to determine if an address is in
the kernel.  This is based on the kernel function
kernel_ip().

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
 tools/perf/util/event.c   |  6 +++---
 tools/perf/util/machine.c | 23 +++++++++++++++++++++++
 tools/perf/util/machine.h | 17 +++++++++++++++++
 3 files changed, 43 insertions(+), 3 deletions(-)

diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index 7e0e8ae..d1283cc 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -784,9 +784,9 @@ try_again:
 		 * "[vdso]" dso, but for now lets use the old trick of looking
 		 * in the whole kernel symbol list.
 		 */
-		if ((long long)al->addr < 0 &&
-		    cpumode == PERF_RECORD_MISC_USER &&
-		    machine && mg != &machine->kmaps) {
+		if (cpumode == PERF_RECORD_MISC_USER && machine &&
+		    mg != &machine->kmaps &&
+		    machine__kernel_ip(machine, al->addr)) {
 			mg = &machine->kmaps;
 			load_map = true;
 			goto try_again;
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index 18eaf31..347ac65 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -29,6 +29,7 @@ int machine__init(struct machine *machine, const char *root_dir, pid_t pid)
 	machine->symbol_filter = NULL;
 	machine->id_hdr_size = 0;
 	machine->comm_exec = false;
+	machine->kernel_start = 0;
 
 	machine->root_dir = strdup(root_dir);
 	if (machine->root_dir == NULL)
@@ -1474,3 +1475,25 @@ int __machine__synthesize_threads(struct machine *machine, struct perf_tool *too
 	/* command specified */
 	return 0;
 }
+
+int machine__get_kernel_start(struct machine *machine)
+{
+	struct map *map = machine__kernel_map(machine, MAP__FUNCTION);
+	int err = 0;
+
+	/*
+	 * The only addresses above 2^63 are kernel addresses of a 64-bit
+	 * kernel.  Note that addresses are unsigned so that on a 32-bit system
+	 * all addresses including kernel addresses are less than 2^32.  In
+	 * that case (32-bit system), if the kernel mapping is unknown, all
+	 * addresses will be assumed to be in user space - see
+	 * machine__kernel_ip().
+	 */
+	machine->kernel_start = 1ULL << 63;
+	if (map) {
+		err = map__load(map, machine->symbol_filter);
+		if (map->start)
+			machine->kernel_start = map->start;
+	}
+	return err;
+}
diff --git a/tools/perf/util/machine.h b/tools/perf/util/machine.h
index 383c725..be97021 100644
--- a/tools/perf/util/machine.h
+++ b/tools/perf/util/machine.h
@@ -33,6 +33,7 @@ struct machine {
 	struct list_head  kernel_dsos;
 	struct map_groups kmaps;
 	struct map	  *vmlinux_maps[MAP__NR_TYPES];
+	u64		  kernel_start;
 	symbol_filter_t	  symbol_filter;
 };
 
@@ -42,6 +43,22 @@ struct map *machine__kernel_map(struct machine *machine, enum map_type type)
 	return machine->vmlinux_maps[type];
 }
 
+int machine__get_kernel_start(struct machine *machine);
+
+static inline u64 machine__kernel_start(struct machine *machine)
+{
+	if (!machine->kernel_start)
+		machine__get_kernel_start(machine);
+	return machine->kernel_start;
+}
+
+static inline bool machine__kernel_ip(struct machine *machine, u64 ip)
+{
+	u64 kernel_start = machine__kernel_start(machine);
+
+	return ip >= kernel_start;
+}
+
 struct thread *machine__find_thread(struct machine *machine, pid_t pid,
 				    pid_t tid);
 struct comm *machine__thread_exec_comm(struct machine *machine,
-- 
1.8.3.2


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

* [PATCH 14/41] perf buildid-cache: Apply force option to copying kcore
  2014-07-14 10:02 [PATCH 00/41] perf tools: Preparation for call graph from Intel BTS Adrian Hunter
                   ` (12 preceding siblings ...)
  2014-07-14 10:02 ` [PATCH 13/41] perf tools: Add machine__kernel_ip() Adrian Hunter
@ 2014-07-14 10:02 ` Adrian Hunter
  2014-07-18  4:24   ` [tip:perf/core] " tip-bot for Adrian Hunter
  2014-07-14 10:02 ` [PATCH 15/41] perf script: Improve srcline display for BTS Adrian Hunter
                   ` (26 subsequent siblings)
  40 siblings, 1 reply; 122+ messages in thread
From: Adrian Hunter @ 2014-07-14 10:02 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Peter Zijlstra, linux-kernel, David Ahern, Frederic Weisbecker,
	Jiri Olsa, Namhyung Kim, Paul Mackerras, Stephane Eranian

Currently a copy of kcore is not made if there is one
already with the same modules at the same addresses.
Change this to make a copy anyway if the force (-f)
option is also used.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
 tools/perf/builtin-buildid-cache.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/tools/perf/builtin-buildid-cache.c b/tools/perf/builtin-buildid-cache.c
index b22dbb1..2a2c78f 100644
--- a/tools/perf/builtin-buildid-cache.c
+++ b/tools/perf/builtin-buildid-cache.c
@@ -125,7 +125,8 @@ static int build_id_cache__kcore_existing(const char *from_dir, char *to_dir,
 	return ret;
 }
 
-static int build_id_cache__add_kcore(const char *filename, const char *debugdir)
+static int build_id_cache__add_kcore(const char *filename, const char *debugdir,
+				     bool force)
 {
 	char dir[32], sbuildid[BUILD_ID_SIZE * 2 + 1];
 	char from_dir[PATH_MAX], to_dir[PATH_MAX];
@@ -144,7 +145,8 @@ static int build_id_cache__add_kcore(const char *filename, const char *debugdir)
 	scnprintf(to_dir, sizeof(to_dir), "%s/[kernel.kcore]/%s",
 		  debugdir, sbuildid);
 
-	if (!build_id_cache__kcore_existing(from_dir, to_dir, sizeof(to_dir))) {
+	if (!force &&
+	    !build_id_cache__kcore_existing(from_dir, to_dir, sizeof(to_dir))) {
 		pr_debug("same kcore found in %s\n", to_dir);
 		return 0;
 	}
@@ -389,7 +391,7 @@ int cmd_buildid_cache(int argc, const char **argv,
 	}
 
 	if (kcore_filename &&
-	    build_id_cache__add_kcore(kcore_filename, debugdir))
+	    build_id_cache__add_kcore(kcore_filename, debugdir, force))
 		pr_warning("Couldn't add %s\n", kcore_filename);
 
 	return ret;
-- 
1.8.3.2


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

* [PATCH 15/41] perf script: Improve srcline display for BTS
  2014-07-14 10:02 [PATCH 00/41] perf tools: Preparation for call graph from Intel BTS Adrian Hunter
                   ` (13 preceding siblings ...)
  2014-07-14 10:02 ` [PATCH 14/41] perf buildid-cache: Apply force option to copying kcore Adrian Hunter
@ 2014-07-14 10:02 ` Adrian Hunter
  2014-07-15 14:16   ` Arnaldo Carvalho de Melo
  2014-07-14 10:02 ` [PATCH 16/41] perf script: Do not print dangling '=>' " Adrian Hunter
                   ` (25 subsequent siblings)
  40 siblings, 1 reply; 122+ messages in thread
From: Adrian Hunter @ 2014-07-14 10:02 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Peter Zijlstra, linux-kernel, David Ahern, Frederic Weisbecker,
	Jiri Olsa, Namhyung Kim, Paul Mackerras, Stephane Eranian

Change the order of the output to put the srcline last.
e.g. old format:

          4028fc main+0x2c (/bin/ls)
  /build/buildd/coreutils-8.20/src/ls.c:1269 =>           40d8a0 set_program_name+0x0 (/bin/ls)

new format:

          4028fc main+0x2c (/bin/ls) =>           40d8a0 set_program_name+0x0 (/bin/ls)
  /build/buildd/coreutils-8.20/src/ls.c:1269

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
 tools/perf/builtin-script.c | 20 +++++++++++++++-----
 1 file changed, 15 insertions(+), 5 deletions(-)

diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index 9e9c91f..333b15e 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -427,15 +427,22 @@ static void print_sample_bts(union perf_event *event,
 			     struct addr_location *al)
 {
 	struct perf_event_attr *attr = &evsel->attr;
+	bool print_srcline_last = false;
 
 	/* print branch_from information */
 	if (PRINT_FIELD(IP)) {
-		if (!symbol_conf.use_callchain)
-			printf(" ");
-		else
+		unsigned int print_opts = output[attr->type].print_ip_opts;
+
+		if (symbol_conf.use_callchain && sample->callchain) {
 			printf("\n");
-		perf_evsel__print_ip(evsel, sample, al,
-				     output[attr->type].print_ip_opts,
+		} else {
+			printf(" ");
+			if (print_opts & PRINT_IP_OPT_SRCLINE) {
+				print_srcline_last = true;
+				print_opts &= ~PRINT_IP_OPT_SRCLINE;
+			}
+		}
+		perf_evsel__print_ip(evsel, sample, al, print_opts,
 				     PERF_MAX_STACK_DEPTH);
 	}
 
@@ -447,6 +454,9 @@ static void print_sample_bts(union perf_event *event,
 	     !output[attr->type].user_set))
 		print_sample_addr(event, sample, al->machine, thread, attr);
 
+	if (print_srcline_last)
+		map__fprintf_srcline(al->map, al->addr, "\n  ", stdout);
+
 	printf("\n");
 }
 
-- 
1.8.3.2


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

* [PATCH 16/41] perf script: Do not print dangling '=>' for BTS
  2014-07-14 10:02 [PATCH 00/41] perf tools: Preparation for call graph from Intel BTS Adrian Hunter
                   ` (14 preceding siblings ...)
  2014-07-14 10:02 ` [PATCH 15/41] perf script: Improve srcline display for BTS Adrian Hunter
@ 2014-07-14 10:02 ` Adrian Hunter
  2014-07-14 10:02 ` [PATCH 17/41] perf tools: Record whether a dso is 64-bit Adrian Hunter
                   ` (24 subsequent siblings)
  40 siblings, 0 replies; 122+ messages in thread
From: Adrian Hunter @ 2014-07-14 10:02 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Peter Zijlstra, linux-kernel, David Ahern, Frederic Weisbecker,
	Jiri Olsa, Namhyung Kim, Paul Mackerras, Stephane Eranian

When using:

	perf record -e branches:u -c1
	perf script -f ip

lines are displayed like:

	ffffffff813b23d5 =>

Change so that the dangling '=>' does not appear.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
 tools/perf/builtin-script.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index 333b15e..582da97 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -446,13 +446,13 @@ static void print_sample_bts(union perf_event *event,
 				     PERF_MAX_STACK_DEPTH);
 	}
 
-	printf(" => ");
-
 	/* print branch_to information */
 	if (PRINT_FIELD(ADDR) ||
 	    ((evsel->attr.sample_type & PERF_SAMPLE_ADDR) &&
-	     !output[attr->type].user_set))
+	     !output[attr->type].user_set)) {
+		printf(" => ");
 		print_sample_addr(event, sample, al->machine, thread, attr);
+	}
 
 	if (print_srcline_last)
 		map__fprintf_srcline(al->map, al->addr, "\n  ", stdout);
-- 
1.8.3.2


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

* [PATCH 17/41] perf tools: Record whether a dso is 64-bit
  2014-07-14 10:02 [PATCH 00/41] perf tools: Preparation for call graph from Intel BTS Adrian Hunter
                   ` (15 preceding siblings ...)
  2014-07-14 10:02 ` [PATCH 16/41] perf script: Do not print dangling '=>' " Adrian Hunter
@ 2014-07-14 10:02 ` Adrian Hunter
  2014-07-18  4:24   ` [tip:perf/core] perf symbols: " tip-bot for Adrian Hunter
  2014-07-14 10:02 ` [PATCH 18/41] perf tools: Record whether a dso has data Adrian Hunter
                   ` (23 subsequent siblings)
  40 siblings, 1 reply; 122+ messages in thread
From: Adrian Hunter @ 2014-07-14 10:02 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Peter Zijlstra, linux-kernel, David Ahern, Frederic Weisbecker,
	Jiri Olsa, Namhyung Kim, Paul Mackerras, Stephane Eranian

Add a flag to 'struct dso' to record if the dso is 64-bit
or not.  Update the flag when reading the ELF.

This is needed for instruction decoding.  For
example, x86 instruction decoding depends on
whether or not the 64-bit instruction set is
used.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
 tools/perf/util/dso.c            |  1 +
 tools/perf/util/dso.h            |  1 +
 tools/perf/util/symbol-elf.c     |  3 +++
 tools/perf/util/symbol-minimal.c | 22 ++++++++++++++++++++++
 tools/perf/util/symbol.c         |  1 +
 tools/perf/util/symbol.h         |  1 +
 6 files changed, 29 insertions(+)

diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c
index 819f104..fc006fe 100644
--- a/tools/perf/util/dso.c
+++ b/tools/perf/util/dso.c
@@ -703,6 +703,7 @@ struct dso *dso__new(const char *name)
 		dso->data.fd = -1;
 		dso->symtab_type = DSO_BINARY_TYPE__NOT_FOUND;
 		dso->binary_type = DSO_BINARY_TYPE__NOT_FOUND;
+		dso->is_64_bit = (sizeof(void *) == 8);
 		dso->loaded = 0;
 		dso->rel = 0;
 		dso->sorted_by_name = 0;
diff --git a/tools/perf/util/dso.h b/tools/perf/util/dso.h
index ad553ba..c239e86 100644
--- a/tools/perf/util/dso.h
+++ b/tools/perf/util/dso.h
@@ -90,6 +90,7 @@ struct dso {
 	u8		 annotate_warned:1;
 	u8		 short_name_allocated:1;
 	u8		 long_name_allocated:1;
+	u8		 is_64_bit:1;
 	u8		 sorted_by_name;
 	u8		 loaded;
 	u8		 rel;
diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c
index 477596c..84f5e2a 100644
--- a/tools/perf/util/symbol-elf.c
+++ b/tools/perf/util/symbol-elf.c
@@ -599,6 +599,8 @@ int symsrc__init(struct symsrc *ss, struct dso *dso, const char *name,
 			goto out_elf_end;
 	}
 
+	ss->is_64_bit = (gelf_getclass(elf) == ELFCLASS64);
+
 	ss->symtab = elf_section_by_name(elf, &ehdr, &ss->symshdr, ".symtab",
 			NULL);
 	if (ss->symshdr.sh_type != SHT_SYMTAB)
@@ -699,6 +701,7 @@ int dso__load_sym(struct dso *dso, struct map *map,
 	bool remap_kernel = false, adjust_kernel_syms = false;
 
 	dso->symtab_type = syms_ss->type;
+	dso->is_64_bit = syms_ss->is_64_bit;
 	dso->rel = syms_ss->ehdr.e_type == ET_REL;
 
 	/*
diff --git a/tools/perf/util/symbol-minimal.c b/tools/perf/util/symbol-minimal.c
index bd15f49..101f55d 100644
--- a/tools/perf/util/symbol-minimal.c
+++ b/tools/perf/util/symbol-minimal.c
@@ -288,6 +288,23 @@ int dso__synthesize_plt_symbols(struct dso *dso __maybe_unused,
 	return 0;
 }
 
+static int fd__is_64_bit(int fd)
+{
+	u8 e_ident[EI_NIDENT];
+
+	if (lseek(fd, 0, SEEK_SET))
+		return -1;
+
+	if (readn(fd, e_ident, sizeof(e_ident)) != sizeof(e_ident))
+		return -1;
+
+	if (memcmp(e_ident, ELFMAG, SELFMAG) ||
+	    e_ident[EI_VERSION] != EV_CURRENT)
+		return -1;
+
+	return e_ident[EI_CLASS] == ELFCLASS64;
+}
+
 int dso__load_sym(struct dso *dso, struct map *map __maybe_unused,
 		  struct symsrc *ss,
 		  struct symsrc *runtime_ss __maybe_unused,
@@ -295,6 +312,11 @@ int dso__load_sym(struct dso *dso, struct map *map __maybe_unused,
 		  int kmodule __maybe_unused)
 {
 	unsigned char *build_id[BUILD_ID_SIZE];
+	int ret;
+
+	ret = fd__is_64_bit(ss->fd);
+	if (ret >= 0)
+		dso->is_64_bit = ret;
 
 	if (filename__read_build_id(ss->name, build_id, BUILD_ID_SIZE) > 0) {
 		dso__set_build_id(dso, build_id);
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index 7b9096f..be7b0df 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -1064,6 +1064,7 @@ static int dso__load_kcore(struct dso *dso, struct map *map,
 			      &is_64_bit);
 	if (err)
 		goto out_err;
+	dso->is_64_bit = is_64_bit;
 
 	if (list_empty(&md.maps)) {
 		err = -EINVAL;
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index 615c752..6ba8a22 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -215,6 +215,7 @@ struct symsrc {
 	GElf_Shdr dynshdr;
 
 	bool adjust_symbols;
+	bool is_64_bit;
 #endif
 };
 
-- 
1.8.3.2


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

* [PATCH 18/41] perf tools: Record whether a dso has data
  2014-07-14 10:02 [PATCH 00/41] perf tools: Preparation for call graph from Intel BTS Adrian Hunter
                   ` (16 preceding siblings ...)
  2014-07-14 10:02 ` [PATCH 17/41] perf tools: Record whether a dso is 64-bit Adrian Hunter
@ 2014-07-14 10:02 ` Adrian Hunter
  2014-07-16 14:20   ` Jiri Olsa
  2014-07-14 10:02 ` [PATCH 19/41] perf tools: Do not attempt to read data from kallsyms Adrian Hunter
                   ` (22 subsequent siblings)
  40 siblings, 1 reply; 122+ messages in thread
From: Adrian Hunter @ 2014-07-14 10:02 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Peter Zijlstra, linux-kernel, David Ahern, Frederic Weisbecker,
	Jiri Olsa, Namhyung Kim, Paul Mackerras, Stephane Eranian

Add 'data_status' to record whether a dso has data
(i.e. an object file) as follows:

	dso->data_status	meaning
	----------------------------------
	0			don't know
	-1			no data
	1			has data

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
 tools/perf/util/dso.c | 5 ++++-
 tools/perf/util/dso.h | 1 +
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c
index fc006fe..91a4eb4 100644
--- a/tools/perf/util/dso.c
+++ b/tools/perf/util/dso.c
@@ -556,8 +556,11 @@ static ssize_t data_read_offset(struct dso *dso, u64 offset,
 ssize_t dso__data_read_offset(struct dso *dso, struct machine *machine,
 			      u64 offset, u8 *data, ssize_t size)
 {
-	if (dso__data_fd(dso, machine) < 0)
+	if (dso__data_fd(dso, machine) < 0) {
+		dso->data.data_status = -1;
 		return -1;
+	}
+	dso->data.data_status = 1;
 
 	return data_read_offset(dso, offset, data, size);
 }
diff --git a/tools/perf/util/dso.h b/tools/perf/util/dso.h
index c239e86..c5257aa 100644
--- a/tools/perf/util/dso.h
+++ b/tools/perf/util/dso.h
@@ -104,6 +104,7 @@ struct dso {
 	struct {
 		struct rb_root	 cache;
 		int		 fd;
+		int		 data_status;
 		size_t		 file_size;
 		struct list_head open_entry;
 	} data;
-- 
1.8.3.2


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

* [PATCH 19/41] perf tools: Do not attempt to read data from kallsyms
  2014-07-14 10:02 [PATCH 00/41] perf tools: Preparation for call graph from Intel BTS Adrian Hunter
                   ` (17 preceding siblings ...)
  2014-07-14 10:02 ` [PATCH 18/41] perf tools: Record whether a dso has data Adrian Hunter
@ 2014-07-14 10:02 ` Adrian Hunter
  2014-07-18  4:25   ` [tip:perf/core] perf symbols: " tip-bot for Adrian Hunter
  2014-07-14 10:02 ` [PATCH 20/41] perf tools: Let a user specify a PMU event without any config terms Adrian Hunter
                   ` (21 subsequent siblings)
  40 siblings, 1 reply; 122+ messages in thread
From: Adrian Hunter @ 2014-07-14 10:02 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Peter Zijlstra, linux-kernel, David Ahern, Frederic Weisbecker,
	Jiri Olsa, Namhyung Kim, Paul Mackerras, Stephane Eranian

Record kallsyms binary type so that tools will not
attempt to read binary data from it.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
 tools/perf/util/symbol.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index be7b0df..21b2e45 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -1663,6 +1663,7 @@ do_kallsyms:
 	free(kallsyms_allocated_filename);
 
 	if (err > 0 && !dso__is_kcore(dso)) {
+		dso->binary_type = DSO_BINARY_TYPE__KALLSYMS;
 		dso__set_long_name(dso, "[kernel.kallsyms]", false);
 		map__fixup_start(map);
 		map__fixup_end(map);
@@ -1710,6 +1711,7 @@ static int dso__load_guest_kernel_sym(struct dso *dso, struct map *map,
 	if (err > 0)
 		pr_debug("Using %s for symbols\n", kallsyms_filename);
 	if (err > 0 && !dso__is_kcore(dso)) {
+		dso->binary_type = DSO_BINARY_TYPE__GUEST_KALLSYMS;
 		machine__mmap_name(machine, path, sizeof(path));
 		dso__set_long_name(dso, strdup(path), true);
 		map__fixup_start(map);
-- 
1.8.3.2


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

* [PATCH 20/41] perf tools: Let a user specify a PMU event without any config terms
  2014-07-14 10:02 [PATCH 00/41] perf tools: Preparation for call graph from Intel BTS Adrian Hunter
                   ` (18 preceding siblings ...)
  2014-07-14 10:02 ` [PATCH 19/41] perf tools: Do not attempt to read data from kallsyms Adrian Hunter
@ 2014-07-14 10:02 ` Adrian Hunter
  2014-07-16 14:25   ` Jiri Olsa
  2014-07-14 10:02 ` [PATCH 21/41] perf tools: Let default config be defined for a PMU Adrian Hunter
                   ` (20 subsequent siblings)
  40 siblings, 1 reply; 122+ messages in thread
From: Adrian Hunter @ 2014-07-14 10:02 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Peter Zijlstra, linux-kernel, David Ahern, Frederic Weisbecker,
	Jiri Olsa, Namhyung Kim, Paul Mackerras, Stephane Eranian

This enables a PMU event to be specified in the form:

	pmu//

which is effectively the same as:

	pmu/config=0/

This patch is a precursor to defining
default config for a PMU.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
 tools/perf/util/parse-events.c |  6 ++++++
 tools/perf/util/parse-events.y | 10 ++++++++++
 2 files changed, 16 insertions(+)

diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index 1e15df1..76fd04b 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -644,6 +644,12 @@ int parse_events_add_pmu(struct list_head *list, int *idx,
 
 	memset(&attr, 0, sizeof(attr));
 
+	if (!head_config) {
+		attr.type = pmu->type;
+		evsel = __add_event(list, idx, &attr, NULL, pmu->cpus);
+		return evsel ? 0 : -ENOMEM;
+	}
+
 	if (perf_pmu__check_alias(pmu, head_config, &unit, &scale))
 		return -EINVAL;
 
diff --git a/tools/perf/util/parse-events.y b/tools/perf/util/parse-events.y
index 0bc87ba..55fab6a 100644
--- a/tools/perf/util/parse-events.y
+++ b/tools/perf/util/parse-events.y
@@ -210,6 +210,16 @@ PE_NAME '/' event_config '/'
 	parse_events__free_terms($3);
 	$$ = list;
 }
+|
+PE_NAME '/' '/'
+{
+	struct parse_events_evlist *data = _data;
+	struct list_head *list;
+
+	ALLOC_LIST(list);
+	ABORT_ON(parse_events_add_pmu(list, &data->idx, $1, NULL));
+	$$ = list;
+}
 
 value_sym:
 PE_VALUE_SYM_HW
-- 
1.8.3.2


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

* [PATCH 21/41] perf tools: Let default config be defined for a PMU
  2014-07-14 10:02 [PATCH 00/41] perf tools: Preparation for call graph from Intel BTS Adrian Hunter
                   ` (19 preceding siblings ...)
  2014-07-14 10:02 ` [PATCH 20/41] perf tools: Let a user specify a PMU event without any config terms Adrian Hunter
@ 2014-07-14 10:02 ` Adrian Hunter
  2014-07-14 10:02 ` [PATCH 22/41] perf tools: Add perf_pmu__scan_file() Adrian Hunter
                   ` (19 subsequent siblings)
  40 siblings, 0 replies; 122+ messages in thread
From: Adrian Hunter @ 2014-07-14 10:02 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Peter Zijlstra, linux-kernel, David Ahern, Frederic Weisbecker,
	Jiri Olsa, Namhyung Kim, Paul Mackerras, Stephane Eranian

This allows default config terms to be provided
for a PMU. So, for example, when the Intel PT
PMU is added, it will be possible to specify:

	intel_pt//

which will be the same as:

	intel_pt/tsc=1,noretcomp=0/

meaning that the trace should contain
TSC timestamps and perform 'return
compression'.

An important consideration of this
patch is that it must be possible
to overwrite the default values.
That has meant changing the logic
so that a zero value can replace
a non-zero value.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
 tools/perf/tests/pmu.c         |  2 +-
 tools/perf/util/parse-events.c |  7 ++++++-
 tools/perf/util/pmu.c          | 42 ++++++++++++++++++++++++++----------------
 tools/perf/util/pmu.h          |  9 ++++++++-
 4 files changed, 41 insertions(+), 19 deletions(-)

diff --git a/tools/perf/tests/pmu.c b/tools/perf/tests/pmu.c
index 12b322f..eeb68bb1 100644
--- a/tools/perf/tests/pmu.c
+++ b/tools/perf/tests/pmu.c
@@ -152,7 +152,7 @@ int test__pmu(void)
 		if (ret)
 			break;
 
-		ret = perf_pmu__config_terms(&formats, &attr, terms);
+		ret = perf_pmu__config_terms(&formats, &attr, terms, false);
 		if (ret)
 			break;
 
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index 76fd04b..20d2c1e 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -642,7 +642,12 @@ int parse_events_add_pmu(struct list_head *list, int *idx,
 	if (!pmu)
 		return -EINVAL;
 
-	memset(&attr, 0, sizeof(attr));
+	if (pmu->default_config) {
+		memcpy(&attr, pmu->default_config,
+		       sizeof(struct perf_event_attr));
+	} else {
+		memset(&attr, 0, sizeof(attr));
+	}
 
 	if (!head_config) {
 		attr.type = pmu->type;
diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
index 7a811eb..11ec977 100644
--- a/tools/perf/util/pmu.c
+++ b/tools/perf/util/pmu.c
@@ -2,6 +2,7 @@
 #include <sys/types.h>
 #include <unistd.h>
 #include <stdio.h>
+#include <stdbool.h>
 #include <dirent.h>
 #include <api/fs/fs.h>
 #include <locale.h>
@@ -387,6 +388,12 @@ static struct cpu_map *pmu_cpumask(const char *name)
 	return cpus;
 }
 
+struct perf_event_attr *__attribute__((weak))
+perf_pmu__get_default_config(struct perf_pmu *pmu __maybe_unused)
+{
+	return NULL;
+}
+
 static struct perf_pmu *pmu_lookup(const char *name)
 {
 	struct perf_pmu *pmu;
@@ -421,6 +428,9 @@ static struct perf_pmu *pmu_lookup(const char *name)
 	pmu->name = strdup(name);
 	pmu->type = type;
 	list_add_tail(&pmu->list, &pmus);
+
+	pmu->default_config = perf_pmu__get_default_config(pmu);
+
 	return pmu;
 }
 
@@ -479,28 +489,24 @@ pmu_find_format(struct list_head *formats, char *name)
 }
 
 /*
- * Returns value based on the format definition (format parameter)
+ * Sets value based on the format definition (format parameter)
  * and unformated value (value parameter).
- *
- * TODO maybe optimize a little ;)
  */
-static __u64 pmu_format_value(unsigned long *format, __u64 value)
+static void pmu_format_value(unsigned long *format, __u64 value, __u64 *v,
+			     bool zero)
 {
 	unsigned long fbit, vbit;
-	__u64 v = 0;
 
 	for (fbit = 0, vbit = 0; fbit < PERF_PMU_FORMAT_BITS; fbit++) {
 
 		if (!test_bit(fbit, format))
 			continue;
 
-		if (!(value & (1llu << vbit++)))
-			continue;
-
-		v |= (1llu << fbit);
+		if (value & (1llu << vbit++))
+			*v |= (1llu << fbit);
+		else if (zero)
+			*v &= ~(1llu << fbit);
 	}
-
-	return v;
 }
 
 /*
@@ -509,7 +515,8 @@ static __u64 pmu_format_value(unsigned long *format, __u64 value)
  */
 static int pmu_config_term(struct list_head *formats,
 			   struct perf_event_attr *attr,
-			   struct parse_events_term *term)
+			   struct parse_events_term *term,
+			   bool zero)
 {
 	struct perf_pmu_format *format;
 	__u64 *vp;
@@ -548,18 +555,19 @@ static int pmu_config_term(struct list_head *formats,
 	 * non-hardcoded terms, here's the place to translate
 	 * them into value.
 	 */
-	*vp |= pmu_format_value(format->bits, term->val.num);
+	pmu_format_value(format->bits, term->val.num, vp, zero);
 	return 0;
 }
 
 int perf_pmu__config_terms(struct list_head *formats,
 			   struct perf_event_attr *attr,
-			   struct list_head *head_terms)
+			   struct list_head *head_terms,
+			   bool zero)
 {
 	struct parse_events_term *term;
 
 	list_for_each_entry(term, head_terms, list)
-		if (pmu_config_term(formats, attr, term))
+		if (pmu_config_term(formats, attr, term, zero))
 			return -EINVAL;
 
 	return 0;
@@ -573,8 +581,10 @@ int perf_pmu__config_terms(struct list_head *formats,
 int perf_pmu__config(struct perf_pmu *pmu, struct perf_event_attr *attr,
 		     struct list_head *head_terms)
 {
+	bool zero = !!pmu->default_config;
+
 	attr->type = pmu->type;
-	return perf_pmu__config_terms(&pmu->format, attr, head_terms);
+	return perf_pmu__config_terms(&pmu->format, attr, head_terms, zero);
 }
 
 static struct perf_pmu_alias *pmu_find_alias(struct perf_pmu *pmu,
diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h
index c14a543..281d5b1 100644
--- a/tools/perf/util/pmu.h
+++ b/tools/perf/util/pmu.h
@@ -13,9 +13,12 @@ enum {
 
 #define PERF_PMU_FORMAT_BITS 64
 
+struct perf_event_attr;
+
 struct perf_pmu {
 	char *name;
 	__u32 type;
+	struct perf_event_attr *default_config;
 	struct cpu_map *cpus;
 	struct list_head format;
 	struct list_head aliases;
@@ -27,7 +30,8 @@ int perf_pmu__config(struct perf_pmu *pmu, struct perf_event_attr *attr,
 		     struct list_head *head_terms);
 int perf_pmu__config_terms(struct list_head *formats,
 			   struct perf_event_attr *attr,
-			   struct list_head *head_terms);
+			   struct list_head *head_terms,
+			   bool zero);
 int perf_pmu__check_alias(struct perf_pmu *pmu, struct list_head *head_terms,
 			  const char **unit, double *scale);
 struct list_head *perf_pmu__alias(struct perf_pmu *pmu,
@@ -46,4 +50,7 @@ void print_pmu_events(const char *event_glob, bool name_only);
 bool pmu_have_event(const char *pname, const char *name);
 
 int perf_pmu__test(void);
+
+struct perf_event_attr *perf_pmu__get_default_config(struct perf_pmu *pmu);
+
 #endif /* __PMU_H */
-- 
1.8.3.2


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

* [PATCH 22/41] perf tools: Add perf_pmu__scan_file()
  2014-07-14 10:02 [PATCH 00/41] perf tools: Preparation for call graph from Intel BTS Adrian Hunter
                   ` (20 preceding siblings ...)
  2014-07-14 10:02 ` [PATCH 21/41] perf tools: Let default config be defined for a PMU Adrian Hunter
@ 2014-07-14 10:02 ` Adrian Hunter
  2014-07-14 10:02 ` [PATCH 23/41] perf tools: Add dsos__hit_all() Adrian Hunter
                   ` (18 subsequent siblings)
  40 siblings, 0 replies; 122+ messages in thread
From: Adrian Hunter @ 2014-07-14 10:02 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Peter Zijlstra, linux-kernel, David Ahern, Frederic Weisbecker,
	Jiri Olsa, Namhyung Kim, Paul Mackerras, Stephane Eranian

Add a function to scan a sysfs file within the pmu device
directory.

This will be used to read capability values from the PMU
'caps' subdirectory.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
 tools/perf/util/pmu.c | 37 +++++++++++++++++++++++++++++++++++++
 tools/perf/util/pmu.h |  3 +++
 2 files changed, 40 insertions(+)

diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
index 11ec977..348d1d2 100644
--- a/tools/perf/util/pmu.c
+++ b/tools/perf/util/pmu.c
@@ -3,6 +3,7 @@
 #include <unistd.h>
 #include <stdio.h>
 #include <stdbool.h>
+#include <stdarg.h>
 #include <dirent.h>
 #include <api/fs/fs.h>
 #include <locale.h>
@@ -804,3 +805,39 @@ bool pmu_have_event(const char *pname, const char *name)
 	}
 	return false;
 }
+
+static FILE *perf_pmu__open_file(struct perf_pmu *pmu, const char *name)
+{
+	struct stat st;
+	char path[PATH_MAX];
+	const char *sysfs;
+
+	sysfs = sysfs__mountpoint();
+	if (!sysfs)
+		return NULL;
+
+	snprintf(path, PATH_MAX,
+		 "%s" EVENT_SOURCE_DEVICE_PATH "%s/%s", sysfs, pmu->name, name);
+
+	if (stat(path, &st) < 0)
+		return NULL;
+
+	return fopen(path, "r");
+}
+
+int perf_pmu__scan_file(struct perf_pmu *pmu, const char *name, const char *fmt,
+			...)
+{
+	va_list args;
+	FILE *file;
+	int ret = EOF;
+
+	va_start(args, fmt);
+	file = perf_pmu__open_file(pmu, name);
+	if (file) {
+		ret = vfscanf(file, fmt, args);
+		fclose(file);
+	}
+	va_end(args);
+	return ret;
+}
diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h
index 281d5b1..c35f578 100644
--- a/tools/perf/util/pmu.h
+++ b/tools/perf/util/pmu.h
@@ -49,6 +49,9 @@ struct perf_pmu *perf_pmu__scan(struct perf_pmu *pmu);
 void print_pmu_events(const char *event_glob, bool name_only);
 bool pmu_have_event(const char *pname, const char *name);
 
+int perf_pmu__scan_file(struct perf_pmu *pmu, const char *name, const char *fmt,
+			...) __attribute__((format(scanf, 3, 4)));
+
 int perf_pmu__test(void);
 
 struct perf_event_attr *perf_pmu__get_default_config(struct perf_pmu *pmu);
-- 
1.8.3.2


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

* [PATCH 23/41] perf tools: Add dsos__hit_all()
  2014-07-14 10:02 [PATCH 00/41] perf tools: Preparation for call graph from Intel BTS Adrian Hunter
                   ` (21 preceding siblings ...)
  2014-07-14 10:02 ` [PATCH 22/41] perf tools: Add perf_pmu__scan_file() Adrian Hunter
@ 2014-07-14 10:02 ` Adrian Hunter
  2014-07-14 10:02 ` [PATCH 24/41] perf tools: Add cpu to struct thread Adrian Hunter
                   ` (17 subsequent siblings)
  40 siblings, 0 replies; 122+ messages in thread
From: Adrian Hunter @ 2014-07-14 10:02 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Peter Zijlstra, linux-kernel, David Ahern, Frederic Weisbecker,
	Jiri Olsa, Namhyung Kim, Paul Mackerras, Stephane Eranian

Add ability to mark all dsos as hit.

This is needed in the case of Instruction
Tracing.  It takes so long to decode an
Instruction Trace that it is not worth
doing just to determine which dsos are
hit.  A later patch takes this into use.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
 tools/perf/util/header.c | 41 +++++++++++++++++++++++++++++++++++++++++
 tools/perf/util/header.h |  2 ++
 2 files changed, 43 insertions(+)

diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index 893f8e2..a588a3e 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -200,6 +200,47 @@ static int write_buildid(const char *name, size_t name_len, u8 *build_id,
 	return write_padded(fd, name, name_len + 1, len);
 }
 
+static int __dsos__hit_all(struct list_head *head)
+{
+	struct dso *pos;
+
+	list_for_each_entry(pos, head, node)
+		pos->hit = true;
+
+	return 0;
+}
+
+static int machine__hit_all_dsos(struct machine *machine)
+{
+	int err;
+
+	err = __dsos__hit_all(&machine->kernel_dsos);
+	if (err)
+		return err;
+
+	return __dsos__hit_all(&machine->user_dsos);
+}
+
+int dsos__hit_all(struct perf_session *session)
+{
+	struct rb_node *nd;
+	int err;
+
+	err = machine__hit_all_dsos(&session->machines.host);
+	if (err)
+		return err;
+
+	for (nd = rb_first(&session->machines.guests); nd; nd = rb_next(nd)) {
+		struct machine *pos = rb_entry(nd, struct machine, rb_node);
+
+		err = machine__hit_all_dsos(pos);
+		if (err)
+			return err;
+	}
+
+	return 0;
+}
+
 static int __dsos__write_buildid_table(struct list_head *head,
 				       struct machine *machine,
 				       pid_t pid, u16 misc, int fd)
diff --git a/tools/perf/util/header.h b/tools/perf/util/header.h
index d08cfe4..8f5cbae 100644
--- a/tools/perf/util/header.h
+++ b/tools/perf/util/header.h
@@ -151,6 +151,8 @@ int perf_event__process_build_id(struct perf_tool *tool,
 				 struct perf_session *session);
 bool is_perf_magic(u64 magic);
 
+int dsos__hit_all(struct perf_session *session);
+
 /*
  * arch specific callback
  */
-- 
1.8.3.2


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

* [PATCH 24/41] perf tools: Add cpu to struct thread
  2014-07-14 10:02 [PATCH 00/41] perf tools: Preparation for call graph from Intel BTS Adrian Hunter
                   ` (22 preceding siblings ...)
  2014-07-14 10:02 ` [PATCH 23/41] perf tools: Add dsos__hit_all() Adrian Hunter
@ 2014-07-14 10:02 ` Adrian Hunter
  2014-07-15 14:24   ` Arnaldo Carvalho de Melo
  2014-07-14 10:02 ` [PATCH 25/41] perf tools: Add ability to record the current tid for each cpu Adrian Hunter
                   ` (16 subsequent siblings)
  40 siblings, 1 reply; 122+ messages in thread
From: Adrian Hunter @ 2014-07-14 10:02 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Peter Zijlstra, linux-kernel, David Ahern, Frederic Weisbecker,
	Jiri Olsa, Namhyung Kim, Paul Mackerras, Stephane Eranian

Tools may wish to track on which cpu a thread
is running.  Add 'cpu' to struct thread for
that purpose.

This will be used to determine the cpu when
decoding a per-thread Instruction Trace.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
 tools/perf/util/thread.c | 1 +
 tools/perf/util/thread.h | 1 +
 2 files changed, 2 insertions(+)

diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c
index b9a3ee4..2f8c0c1 100644
--- a/tools/perf/util/thread.c
+++ b/tools/perf/util/thread.c
@@ -69,6 +69,7 @@ struct thread *thread__new(pid_t pid, pid_t tid)
 		thread->pid_ = pid;
 		thread->tid = tid;
 		thread->ppid = -1;
+		thread->cpu = -1;
 		INIT_LIST_HEAD(&thread->comm_list);
 
 		comm_str = malloc(32);
diff --git a/tools/perf/util/thread.h b/tools/perf/util/thread.h
index b4269af..e4920ff 100644
--- a/tools/perf/util/thread.h
+++ b/tools/perf/util/thread.h
@@ -17,6 +17,7 @@ struct thread {
 	pid_t			pid_; /* Not all tools update this */
 	pid_t			tid;
 	pid_t			ppid;
+	int			cpu;
 	char			shortname[3];
 	bool			comm_set;
 	bool			dead; /* if set thread has exited */
-- 
1.8.3.2


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

* [PATCH 25/41] perf tools: Add ability to record the current tid for each cpu
  2014-07-14 10:02 [PATCH 00/41] perf tools: Preparation for call graph from Intel BTS Adrian Hunter
                   ` (23 preceding siblings ...)
  2014-07-14 10:02 ` [PATCH 24/41] perf tools: Add cpu to struct thread Adrian Hunter
@ 2014-07-14 10:02 ` Adrian Hunter
  2014-07-14 10:02 ` [PATCH 26/41] perf tools: Add ability to iterate over a dso's symbols Adrian Hunter
                   ` (15 subsequent siblings)
  40 siblings, 0 replies; 122+ messages in thread
From: Adrian Hunter @ 2014-07-14 10:02 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Peter Zijlstra, linux-kernel, David Ahern, Frederic Weisbecker,
	Jiri Olsa, Namhyung Kim, Paul Mackerras, Stephane Eranian

Add an array to struct machine to store
the current tid running on each cpu.
Add machine functions to get / set
the tid for a cpu.

This will be used to determine the tid
when decoding a per-cpu Instruction Trace.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
 tools/perf/util/machine.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
 tools/perf/util/machine.h |  5 +++++
 2 files changed, 51 insertions(+)

diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index 347ac65..8d9e4a7 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -47,6 +47,8 @@ int machine__init(struct machine *machine, const char *root_dir, pid_t pid)
 		thread__set_comm(thread, comm, 0);
 	}
 
+	machine->current_tid = NULL;
+
 	return 0;
 }
 
@@ -106,6 +108,7 @@ void machine__exit(struct machine *machine)
 	dsos__delete(&machine->user_dsos);
 	dsos__delete(&machine->kernel_dsos);
 	zfree(&machine->root_dir);
+	zfree(&machine->current_tid);
 }
 
 void machine__delete(struct machine *machine)
@@ -1497,3 +1500,46 @@ int machine__get_kernel_start(struct machine *machine)
 	}
 	return err;
 }
+
+pid_t machine__get_current_tid(struct machine *machine, int cpu)
+{
+	if (cpu < 0 || cpu >= MAX_NR_CPUS || !machine->current_tid)
+		return -1;
+
+	return machine->current_tid[cpu];
+}
+
+int machine__set_current_tid(struct machine *machine, int cpu, pid_t pid,
+			     pid_t tid)
+{
+	struct thread *thread;
+
+	if (cpu < 0)
+		return -EINVAL;
+
+	if (!machine->current_tid) {
+		int i;
+
+		machine->current_tid = calloc(MAX_NR_CPUS, sizeof(pid_t));
+		if (!machine->current_tid)
+			return -ENOMEM;
+		for (i = 0; i < MAX_NR_CPUS; i++)
+			machine->current_tid[i] = -1;
+	}
+
+	if (cpu >= MAX_NR_CPUS) {
+		pr_err("Requested CPU %d too large. ", cpu);
+		pr_err("Consider raising MAX_NR_CPUS\n");
+		return -EINVAL;
+	}
+
+	machine->current_tid[cpu] = tid;
+
+	thread = machine__findnew_thread(machine, pid, tid);
+	if (!thread)
+		return -ENOMEM;
+
+	thread->cpu = cpu;
+
+	return 0;
+}
diff --git a/tools/perf/util/machine.h b/tools/perf/util/machine.h
index be97021..6442d65 100644
--- a/tools/perf/util/machine.h
+++ b/tools/perf/util/machine.h
@@ -35,6 +35,7 @@ struct machine {
 	struct map	  *vmlinux_maps[MAP__NR_TYPES];
 	u64		  kernel_start;
 	symbol_filter_t	  symbol_filter;
+	pid_t		  *current_tid;
 };
 
 static inline
@@ -212,4 +213,8 @@ int machine__synthesize_threads(struct machine *machine, struct target *target,
 					     perf_event__process, data_mmap);
 }
 
+pid_t machine__get_current_tid(struct machine *machine, int cpu);
+int machine__set_current_tid(struct machine *machine, int cpu, pid_t pid,
+			     pid_t tid);
+
 #endif /* __PERF_MACHINE_H */
-- 
1.8.3.2


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

* [PATCH 26/41] perf tools: Add ability to iterate over a dso's symbols
  2014-07-14 10:02 [PATCH 00/41] perf tools: Preparation for call graph from Intel BTS Adrian Hunter
                   ` (24 preceding siblings ...)
  2014-07-14 10:02 ` [PATCH 25/41] perf tools: Add ability to record the current tid for each cpu Adrian Hunter
@ 2014-07-14 10:02 ` Adrian Hunter
  2014-07-18  4:25   ` [tip:perf/core] perf symbols: Add ability to iterate over a dso' s symbols tip-bot for Adrian Hunter
  2014-07-14 10:02 ` [PATCH 27/41] perf session: Flag if the event stream is entirely in memory Adrian Hunter
                   ` (14 subsequent siblings)
  40 siblings, 1 reply; 122+ messages in thread
From: Adrian Hunter @ 2014-07-14 10:02 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Peter Zijlstra, linux-kernel, David Ahern, Frederic Weisbecker,
	Jiri Olsa, Namhyung Kim, Paul Mackerras, Stephane Eranian

Expose dso__first_symbol() and dso__next_symbol() to make
it possible to iterate over a dso's symbols.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
 tools/perf/util/symbol.c | 17 ++++++++++++++++-
 tools/perf/util/symbol.h |  3 +++
 2 files changed, 19 insertions(+), 1 deletion(-)

diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index 21b2e45..d5dc547 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -341,6 +341,16 @@ static struct symbol *symbols__first(struct rb_root *symbols)
 	return NULL;
 }
 
+static struct symbol *symbols__next(struct symbol *sym)
+{
+	struct rb_node *n = rb_next(&sym->rb_node);
+
+	if (n)
+		return rb_entry(n, struct symbol, rb_node);
+
+	return NULL;
+}
+
 struct symbol_name_rb_node {
 	struct rb_node	rb_node;
 	struct symbol	sym;
@@ -411,11 +421,16 @@ struct symbol *dso__find_symbol(struct dso *dso,
 	return symbols__find(&dso->symbols[type], addr);
 }
 
-static struct symbol *dso__first_symbol(struct dso *dso, enum map_type type)
+struct symbol *dso__first_symbol(struct dso *dso, enum map_type type)
 {
 	return symbols__first(&dso->symbols[type]);
 }
 
+struct symbol *dso__next_symbol(struct symbol *sym)
+{
+	return symbols__next(sym);
+}
+
 struct symbol *dso__find_symbol_by_name(struct dso *dso, enum map_type type,
 					const char *name)
 {
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index 6ba8a22..e1350bc 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -239,6 +239,9 @@ struct symbol *dso__find_symbol(struct dso *dso, enum map_type type,
 struct symbol *dso__find_symbol_by_name(struct dso *dso, enum map_type type,
 					const char *name);
 
+struct symbol *dso__first_symbol(struct dso *dso, enum map_type type);
+struct symbol *dso__next_symbol(struct symbol *sym);
+
 int filename__read_build_id(const char *filename, void *bf, size_t size);
 int sysfs__read_build_id(const char *filename, void *bf, size_t size);
 int modules__parse(const char *filename, void *arg,
-- 
1.8.3.2


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

* [PATCH 27/41] perf session: Flag if the event stream is entirely in memory
  2014-07-14 10:02 [PATCH 00/41] perf tools: Preparation for call graph from Intel BTS Adrian Hunter
                   ` (25 preceding siblings ...)
  2014-07-14 10:02 ` [PATCH 26/41] perf tools: Add ability to iterate over a dso's symbols Adrian Hunter
@ 2014-07-14 10:02 ` Adrian Hunter
  2014-07-18  4:25   ` [tip:perf/core] " tip-bot for Adrian Hunter
  2014-07-14 10:02 ` [PATCH 28/41] perf evlist: Pass mmap parameters in a struct Adrian Hunter
                   ` (13 subsequent siblings)
  40 siblings, 1 reply; 122+ messages in thread
From: Adrian Hunter @ 2014-07-14 10:02 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Peter Zijlstra, linux-kernel, David Ahern, Frederic Weisbecker,
	Jiri Olsa, Namhyung Kim, Paul Mackerras, Stephane Eranian

Flag if the event stream is a file that has been mmapped
in one go.

This is useful, for example, if a tool needs to keep an
event for later reference.  If the new flag is set, a
pointer to the event can be retained, otherwise the
event must be copied.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
 tools/perf/util/session.c | 9 ++++++++-
 tools/perf/util/session.h | 3 +++
 2 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index c1abe6b..7b0fb03 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -1319,8 +1319,10 @@ int __perf_session__process_events(struct perf_session *session,
 	ui_progress__init(&prog, file_size, "Processing events...");
 
 	mmap_size = MMAP_SIZE;
-	if (mmap_size > file_size)
+	if (mmap_size > file_size) {
 		mmap_size = file_size;
+		session->one_mmap = true;
+	}
 
 	memset(mmaps, 0, sizeof(mmaps));
 
@@ -1342,6 +1344,10 @@ remap:
 	mmaps[map_idx] = buf;
 	map_idx = (map_idx + 1) & (ARRAY_SIZE(mmaps) - 1);
 	file_pos = file_offset + head;
+	if (session->one_mmap) {
+		session->one_mmap_addr = buf;
+		session->one_mmap_offset = file_offset;
+	}
 
 more:
 	event = fetch_mmaped_event(session, head, mmap_size, buf);
@@ -1387,6 +1393,7 @@ out_err:
 	ui_progress__finish();
 	perf_session__warn_about_errors(session, tool);
 	perf_session_free_sample_buffers(session);
+	session->one_mmap = false;
 	return err;
 }
 
diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h
index 3140f8a..0321013 100644
--- a/tools/perf/util/session.h
+++ b/tools/perf/util/session.h
@@ -36,6 +36,9 @@ struct perf_session {
 	struct trace_event	tevent;
 	struct events_stats	stats;
 	bool			repipe;
+	bool			one_mmap;
+	void			*one_mmap_addr;
+	u64			one_mmap_offset;
 	struct ordered_samples	ordered_samples;
 	struct perf_data_file	*file;
 };
-- 
1.8.3.2


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

* [PATCH 28/41] perf evlist: Pass mmap parameters in a struct
  2014-07-14 10:02 [PATCH 00/41] perf tools: Preparation for call graph from Intel BTS Adrian Hunter
                   ` (26 preceding siblings ...)
  2014-07-14 10:02 ` [PATCH 27/41] perf session: Flag if the event stream is entirely in memory Adrian Hunter
@ 2014-07-14 10:02 ` Adrian Hunter
  2014-07-18  4:25   ` [tip:perf/core] " tip-bot for Adrian Hunter
  2014-07-14 10:02 ` [PATCH 29/41] perf tools: Add feature test for __sync_val_compare_and_swap Adrian Hunter
                   ` (12 subsequent siblings)
  40 siblings, 1 reply; 122+ messages in thread
From: Adrian Hunter @ 2014-07-14 10:02 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Peter Zijlstra, linux-kernel, David Ahern, Frederic Weisbecker,
	Jiri Olsa, Namhyung Kim, Paul Mackerras, Stephane Eranian

In preparation for adding more mmap parameters, pass
existing parameters in a struct.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
 tools/perf/util/evlist.c | 46 ++++++++++++++++++++++++++--------------------
 1 file changed, 26 insertions(+), 20 deletions(-)

diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index c51223a..814e954 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -606,12 +606,17 @@ static int perf_evlist__alloc_mmap(struct perf_evlist *evlist)
 	return evlist->mmap != NULL ? 0 : -ENOMEM;
 }
 
-static int __perf_evlist__mmap(struct perf_evlist *evlist,
-			       int idx, int prot, int mask, int fd)
+struct mmap_params {
+	int prot;
+	int mask;
+};
+
+static int __perf_evlist__mmap(struct perf_evlist *evlist, int idx,
+			       struct mmap_params *mp, int fd)
 {
 	evlist->mmap[idx].prev = 0;
-	evlist->mmap[idx].mask = mask;
-	evlist->mmap[idx].base = mmap(NULL, evlist->mmap_len, prot,
+	evlist->mmap[idx].mask = mp->mask;
+	evlist->mmap[idx].base = mmap(NULL, evlist->mmap_len, mp->prot,
 				      MAP_SHARED, fd, 0);
 	if (evlist->mmap[idx].base == MAP_FAILED) {
 		pr_debug2("failed to mmap perf event ring buffer, error %d\n",
@@ -625,8 +630,8 @@ static int __perf_evlist__mmap(struct perf_evlist *evlist,
 }
 
 static int perf_evlist__mmap_per_evsel(struct perf_evlist *evlist, int idx,
-				       int prot, int mask, int cpu, int thread,
-				       int *output)
+				       struct mmap_params *mp, int cpu,
+				       int thread, int *output)
 {
 	struct perf_evsel *evsel;
 
@@ -635,8 +640,7 @@ static int perf_evlist__mmap_per_evsel(struct perf_evlist *evlist, int idx,
 
 		if (*output == -1) {
 			*output = fd;
-			if (__perf_evlist__mmap(evlist, idx, prot, mask,
-						*output) < 0)
+			if (__perf_evlist__mmap(evlist, idx, mp, *output) < 0)
 				return -1;
 		} else {
 			if (ioctl(fd, PERF_EVENT_IOC_SET_OUTPUT, *output) != 0)
@@ -651,8 +655,8 @@ static int perf_evlist__mmap_per_evsel(struct perf_evlist *evlist, int idx,
 	return 0;
 }
 
-static int perf_evlist__mmap_per_cpu(struct perf_evlist *evlist, int prot,
-				     int mask)
+static int perf_evlist__mmap_per_cpu(struct perf_evlist *evlist,
+				     struct mmap_params *mp)
 {
 	int cpu, thread;
 	int nr_cpus = cpu_map__nr(evlist->cpus);
@@ -663,8 +667,8 @@ static int perf_evlist__mmap_per_cpu(struct perf_evlist *evlist, int prot,
 		int output = -1;
 
 		for (thread = 0; thread < nr_threads; thread++) {
-			if (perf_evlist__mmap_per_evsel(evlist, cpu, prot, mask,
-							cpu, thread, &output))
+			if (perf_evlist__mmap_per_evsel(evlist, cpu, mp, cpu,
+							thread, &output))
 				goto out_unmap;
 		}
 	}
@@ -677,8 +681,8 @@ out_unmap:
 	return -1;
 }
 
-static int perf_evlist__mmap_per_thread(struct perf_evlist *evlist, int prot,
-					int mask)
+static int perf_evlist__mmap_per_thread(struct perf_evlist *evlist,
+					struct mmap_params *mp)
 {
 	int thread;
 	int nr_threads = thread_map__nr(evlist->threads);
@@ -687,8 +691,8 @@ static int perf_evlist__mmap_per_thread(struct perf_evlist *evlist, int prot,
 	for (thread = 0; thread < nr_threads; thread++) {
 		int output = -1;
 
-		if (perf_evlist__mmap_per_evsel(evlist, thread, prot, mask, 0,
-						thread, &output))
+		if (perf_evlist__mmap_per_evsel(evlist, thread, mp, 0, thread,
+						&output))
 			goto out_unmap;
 	}
 
@@ -793,7 +797,9 @@ int perf_evlist__mmap(struct perf_evlist *evlist, unsigned int pages,
 	struct perf_evsel *evsel;
 	const struct cpu_map *cpus = evlist->cpus;
 	const struct thread_map *threads = evlist->threads;
-	int prot = PROT_READ | (overwrite ? 0 : PROT_WRITE), mask;
+	struct mmap_params mp = {
+		.prot = PROT_READ | (overwrite ? 0 : PROT_WRITE),
+	};
 
 	if (evlist->mmap == NULL && perf_evlist__alloc_mmap(evlist) < 0)
 		return -ENOMEM;
@@ -804,7 +810,7 @@ int perf_evlist__mmap(struct perf_evlist *evlist, unsigned int pages,
 	evlist->overwrite = overwrite;
 	evlist->mmap_len = perf_evlist__mmap_size(pages);
 	pr_debug("mmap size %zuB\n", evlist->mmap_len);
-	mask = evlist->mmap_len - page_size - 1;
+	mp.mask = evlist->mmap_len - page_size - 1;
 
 	evlist__for_each(evlist, evsel) {
 		if ((evsel->attr.read_format & PERF_FORMAT_ID) &&
@@ -814,9 +820,9 @@ int perf_evlist__mmap(struct perf_evlist *evlist, unsigned int pages,
 	}
 
 	if (cpu_map__empty(cpus))
-		return perf_evlist__mmap_per_thread(evlist, prot, mask);
+		return perf_evlist__mmap_per_thread(evlist, &mp);
 
-	return perf_evlist__mmap_per_cpu(evlist, prot, mask);
+	return perf_evlist__mmap_per_cpu(evlist, &mp);
 }
 
 int perf_evlist__create_maps(struct perf_evlist *evlist, struct target *target)
-- 
1.8.3.2


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

* [PATCH 29/41] perf tools: Add feature test for __sync_val_compare_and_swap
  2014-07-14 10:02 [PATCH 00/41] perf tools: Preparation for call graph from Intel BTS Adrian Hunter
                   ` (27 preceding siblings ...)
  2014-07-14 10:02 ` [PATCH 28/41] perf evlist: Pass mmap parameters in a struct Adrian Hunter
@ 2014-07-14 10:02 ` Adrian Hunter
  2014-07-18  4:26   ` [tip:perf/core] " tip-bot for Adrian Hunter
  2014-07-14 10:02 ` [PATCH 30/41] perf tools: Add option macro OPT_CALLBACK_OPTARG Adrian Hunter
                   ` (11 subsequent siblings)
  40 siblings, 1 reply; 122+ messages in thread
From: Adrian Hunter @ 2014-07-14 10:02 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Peter Zijlstra, linux-kernel, David Ahern, Frederic Weisbecker,
	Jiri Olsa, Namhyung Kim, Paul Mackerras, Stephane Eranian

Add a feature test for __sync_val_compare_and_swap()
and __sync_bool_compare_and_swap()

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
 tools/perf/config/Makefile                                 |  6 ++++++
 tools/perf/config/feature-checks/Makefile                  |  4 ++++
 tools/perf/config/feature-checks/test-all.c                |  5 +++++
 .../config/feature-checks/test-sync-compare-and-swap.c     | 14 ++++++++++++++
 4 files changed, 29 insertions(+)
 create mode 100644 tools/perf/config/feature-checks/test-sync-compare-and-swap.c

diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile
index 346bdb6..a0e1329 100644
--- a/tools/perf/config/Makefile
+++ b/tools/perf/config/Makefile
@@ -164,6 +164,7 @@ CORE_FEATURE_TESTS =			\
 	backtrace			\
 	dwarf				\
 	fortify-source			\
+	sync-compare-and-swap		\
 	glibc				\
 	gtk2				\
 	gtk2-infobar			\
@@ -199,6 +200,7 @@ LIB_FEATURE_TESTS =			\
 VF_FEATURE_TESTS =			\
 	backtrace			\
 	fortify-source			\
+	sync-compare-and-swap		\
 	gtk2-infobar			\
 	libelf-getphdrnum		\
 	libelf-mmap			\
@@ -272,6 +274,10 @@ CFLAGS += -I$(LIB_INCLUDE)
 
 CFLAGS += -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE
 
+ifeq ($(feature-sync-compare-and-swap), 1)
+  CFLAGS += -DHAVE_SYNC_COMPARE_AND_SWAP_SUPPORT
+endif
+
 ifndef NO_BIONIC
   $(call feature_check,bionic)
   ifeq ($(feature-bionic), 1)
diff --git a/tools/perf/config/feature-checks/Makefile b/tools/perf/config/feature-checks/Makefile
index 64c84e5..6088f8d 100644
--- a/tools/perf/config/feature-checks/Makefile
+++ b/tools/perf/config/feature-checks/Makefile
@@ -5,6 +5,7 @@ FILES=					\
 	test-bionic.bin			\
 	test-dwarf.bin			\
 	test-fortify-source.bin		\
+	test-sync-compare-and-swap.bin	\
 	test-glibc.bin			\
 	test-gtk2.bin			\
 	test-gtk2-infobar.bin		\
@@ -141,6 +142,9 @@ test-timerfd.bin:
 test-libdw-dwarf-unwind.bin:
 	$(BUILD)
 
+test-sync-compare-and-swap.bin:
+	$(BUILD) -Werror
+
 -include *.d
 
 ###############################
diff --git a/tools/perf/config/feature-checks/test-all.c b/tools/perf/config/feature-checks/test-all.c
index fe5c1e5..a7d022e 100644
--- a/tools/perf/config/feature-checks/test-all.c
+++ b/tools/perf/config/feature-checks/test-all.c
@@ -89,6 +89,10 @@
 # include "test-libdw-dwarf-unwind.c"
 #undef main
 
+#define main main_test_sync_compare_and_swap
+# include "test-sync-compare-and-swap.c"
+#undef main
+
 int main(int argc, char *argv[])
 {
 	main_test_libpython();
@@ -111,6 +115,7 @@ int main(int argc, char *argv[])
 	main_test_timerfd();
 	main_test_stackprotector_all();
 	main_test_libdw_dwarf_unwind();
+	main_test_sync_compare_and_swap(argc, argv);
 
 	return 0;
 }
diff --git a/tools/perf/config/feature-checks/test-sync-compare-and-swap.c b/tools/perf/config/feature-checks/test-sync-compare-and-swap.c
new file mode 100644
index 0000000..c34d4ca
--- /dev/null
+++ b/tools/perf/config/feature-checks/test-sync-compare-and-swap.c
@@ -0,0 +1,14 @@
+#include <stdint.h>
+
+volatile uint64_t x;
+
+int main(int argc, char *argv[])
+{
+	uint64_t old, new = argc;
+
+	argv = argv;
+	do {
+		old = __sync_val_compare_and_swap(&x, 0, 0);
+	} while (!__sync_bool_compare_and_swap(&x, old, new));
+	return old == new;
+}
-- 
1.8.3.2


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

* [PATCH 30/41] perf tools: Add option macro OPT_CALLBACK_OPTARG
  2014-07-14 10:02 [PATCH 00/41] perf tools: Preparation for call graph from Intel BTS Adrian Hunter
                   ` (28 preceding siblings ...)
  2014-07-14 10:02 ` [PATCH 29/41] perf tools: Add feature test for __sync_val_compare_and_swap Adrian Hunter
@ 2014-07-14 10:02 ` Adrian Hunter
  2014-07-18  4:26   ` [tip:perf/core] " tip-bot for Adrian Hunter
  2014-07-14 10:02 ` [PATCH 31/41] perf evlist: Add perf_evlist__set_tracking_event() Adrian Hunter
                   ` (10 subsequent siblings)
  40 siblings, 1 reply; 122+ messages in thread
From: Adrian Hunter @ 2014-07-14 10:02 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Peter Zijlstra, linux-kernel, David Ahern, Frederic Weisbecker,
	Jiri Olsa, Namhyung Kim, Paul Mackerras, Stephane Eranian

Add an option macro that is the same as
OPT_CALLBACK except that the argument is
optional and it is possible to associate
additional data with it.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
 tools/perf/util/parse-options.h | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/tools/perf/util/parse-options.h b/tools/perf/util/parse-options.h
index d8dac8a..b59ba85 100644
--- a/tools/perf/util/parse-options.h
+++ b/tools/perf/util/parse-options.h
@@ -98,6 +98,7 @@ struct option {
 	parse_opt_cb *callback;
 	intptr_t defval;
 	bool *set;
+	void *data;
 };
 
 #define check_vtype(v, type) ( BUILD_BUG_ON_ZERO(!__builtin_types_compatible_p(typeof(v), type)) + v )
@@ -131,6 +132,10 @@ struct option {
 	{ .type = OPTION_CALLBACK, .short_name = (s), .long_name = (l),\
 	.value = (v), (a), .help = (h), .callback = (f), .defval = (intptr_t)d,\
 	.flags = PARSE_OPT_LASTARG_DEFAULT | PARSE_OPT_NOARG}
+#define OPT_CALLBACK_OPTARG(s, l, v, d, a, h, f) \
+	{ .type = OPTION_CALLBACK, .short_name = (s), .long_name = (l), \
+	  .value = (v), (a), .help = (h), .callback = (f), \
+	  .flags = PARSE_OPT_OPTARG, .data = (d) }
 
 /* parse_options() will filter out the processed options and leave the
  * non-option argments in argv[].
-- 
1.8.3.2


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

* [PATCH 31/41] perf evlist: Add perf_evlist__set_tracking_event()
  2014-07-14 10:02 [PATCH 00/41] perf tools: Preparation for call graph from Intel BTS Adrian Hunter
                   ` (29 preceding siblings ...)
  2014-07-14 10:02 ` [PATCH 30/41] perf tools: Add option macro OPT_CALLBACK_OPTARG Adrian Hunter
@ 2014-07-14 10:02 ` Adrian Hunter
  2014-07-14 10:02 ` [PATCH 32/41] perf evsel: Add 'no_aux_samples' option Adrian Hunter
                   ` (9 subsequent siblings)
  40 siblings, 0 replies; 122+ messages in thread
From: Adrian Hunter @ 2014-07-14 10:02 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Peter Zijlstra, linux-kernel, David Ahern, Frederic Weisbecker,
	Jiri Olsa, Namhyung Kim, Paul Mackerras, Stephane Eranian

Add a function to change which event is used
to track mmap, comm and task events.

This is needed with Instruction Tracing
because the Instruction Tracing event
must come first but cannot be used for
tracking because it will be disabled
under some circumstances.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
 tools/perf/util/evlist.c | 20 ++++++++++++++++++++
 tools/perf/util/evlist.h |  3 +++
 2 files changed, 23 insertions(+)

diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index 814e954..282e83e 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -1250,3 +1250,23 @@ void perf_evlist__to_front(struct perf_evlist *evlist,
 
 	list_splice(&move, &evlist->entries);
 }
+
+int perf_evlist__set_tracking_event(struct perf_evlist *evlist,
+				    struct perf_evsel *tracking_evsel)
+{
+	struct perf_evsel *evsel;
+
+	if (tracking_evsel->idx == 0)
+		return 0;
+
+	if (tracking_evsel->leader->nr_members > 1)
+		return -EINVAL;
+
+	list_for_each_entry(evsel, &evlist->entries, node) {
+		if (evsel->idx < tracking_evsel->idx)
+			evsel->idx += 1;
+	}
+	tracking_evsel->idx = 0;
+
+	return 0;
+}
diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h
index f5173cd..657a36c 100644
--- a/tools/perf/util/evlist.h
+++ b/tools/perf/util/evlist.h
@@ -262,4 +262,7 @@ void perf_evlist__to_front(struct perf_evlist *evlist,
 #define evlist__for_each_safe(evlist, tmp, evsel) \
 	__evlist__for_each_safe(&(evlist)->entries, tmp, evsel)
 
+int perf_evlist__set_tracking_event(struct perf_evlist *evlist,
+				    struct perf_evsel *tracking_evsel);
+
 #endif /* __PERF_EVLIST_H */
-- 
1.8.3.2


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

* [PATCH 32/41] perf evsel: Add 'no_aux_samples' option
  2014-07-14 10:02 [PATCH 00/41] perf tools: Preparation for call graph from Intel BTS Adrian Hunter
                   ` (30 preceding siblings ...)
  2014-07-14 10:02 ` [PATCH 31/41] perf evlist: Add perf_evlist__set_tracking_event() Adrian Hunter
@ 2014-07-14 10:02 ` Adrian Hunter
  2014-07-18  4:26   ` [tip:perf/core] " tip-bot for Adrian Hunter
  2014-07-14 10:02 ` [PATCH 33/41] perf evsel: Add 'immediate' option Adrian Hunter
                   ` (8 subsequent siblings)
  40 siblings, 1 reply; 122+ messages in thread
From: Adrian Hunter @ 2014-07-14 10:02 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Peter Zijlstra, linux-kernel, David Ahern, Frederic Weisbecker,
	Jiri Olsa, Namhyung Kim, Paul Mackerras, Stephane Eranian

Add an option to prevent additional
samples being added to a selected
event by perf_evsel__config().

This is needed when using the sched_switch
tracepoint to follow object code execution.
Since sched_switch will be used only for
switch information, additional sampling is
wasteful.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
 tools/perf/util/evsel.c | 6 +++---
 tools/perf/util/evsel.h | 1 +
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index b760d32..40626e5 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -623,7 +623,7 @@ void perf_evsel__config(struct perf_evsel *evsel, struct record_opts *opts)
 		attr->mmap_data = track;
 	}
 
-	if (opts->call_graph_enabled)
+	if (opts->call_graph_enabled && !evsel->no_aux_samples)
 		perf_evsel__config_callgraph(evsel, opts);
 
 	if (target__has_cpu(&opts->target))
@@ -637,7 +637,7 @@ void perf_evsel__config(struct perf_evsel *evsel, struct record_opts *opts)
 	     target__has_cpu(&opts->target) || per_cpu))
 		perf_evsel__set_sample_bit(evsel, TIME);
 
-	if (opts->raw_samples) {
+	if (opts->raw_samples && !evsel->no_aux_samples) {
 		perf_evsel__set_sample_bit(evsel, TIME);
 		perf_evsel__set_sample_bit(evsel, RAW);
 		perf_evsel__set_sample_bit(evsel, CPU);
@@ -650,7 +650,7 @@ void perf_evsel__config(struct perf_evsel *evsel, struct record_opts *opts)
 		attr->watermark = 0;
 		attr->wakeup_events = 1;
 	}
-	if (opts->branch_stack) {
+	if (opts->branch_stack && !evsel->no_aux_samples) {
 		perf_evsel__set_sample_bit(evsel, BRANCH_STACK);
 		attr->branch_sample_type = opts->branch_stack;
 	}
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index a52e9a5..8dfec05 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -83,6 +83,7 @@ struct perf_evsel {
 	int			is_pos;
 	bool 			supported;
 	bool 			needs_swap;
+	bool			no_aux_samples;
 	/* parse modifier helper */
 	int			exclude_GH;
 	int			nr_members;
-- 
1.8.3.2


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

* [PATCH 33/41] perf evsel: Add 'immediate' option
  2014-07-14 10:02 [PATCH 00/41] perf tools: Preparation for call graph from Intel BTS Adrian Hunter
                   ` (31 preceding siblings ...)
  2014-07-14 10:02 ` [PATCH 32/41] perf evsel: Add 'no_aux_samples' option Adrian Hunter
@ 2014-07-14 10:02 ` Adrian Hunter
  2014-07-18  4:26   ` [tip:perf/core] " tip-bot for Adrian Hunter
  2014-07-14 10:02 ` [PATCH 34/41] perf evlist: Add 'system_wide' option Adrian Hunter
                   ` (7 subsequent siblings)
  40 siblings, 1 reply; 122+ messages in thread
From: Adrian Hunter @ 2014-07-14 10:02 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Peter Zijlstra, linux-kernel, David Ahern, Frederic Weisbecker,
	Jiri Olsa, Namhyung Kim, Paul Mackerras, Stephane Eranian

Add an option to cause a selected event
to be enabled immediately when configured
by perf_evsel__config().

This is needed when using the sched_switch
tracepoint to follow object code execution.
By having sched_switch enabled immediately
the first sched_switch event precedes
the start of other tracing.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
 tools/perf/util/evsel.c | 5 +++++
 tools/perf/util/evsel.h | 1 +
 2 files changed, 6 insertions(+)

diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 40626e5..90f58cd 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -681,6 +681,11 @@ void perf_evsel__config(struct perf_evsel *evsel, struct record_opts *opts)
 	if (target__none(&opts->target) && perf_evsel__is_group_leader(evsel) &&
 		!opts->initial_delay)
 		attr->enable_on_exec = 1;
+
+	if (evsel->immediate) {
+		attr->disabled = 0;
+		attr->enable_on_exec = 0;
+	}
 }
 
 int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthreads)
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index 8dfec05..d7f93ce 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -84,6 +84,7 @@ struct perf_evsel {
 	bool 			supported;
 	bool 			needs_swap;
 	bool			no_aux_samples;
+	bool			immediate;
 	/* parse modifier helper */
 	int			exclude_GH;
 	int			nr_members;
-- 
1.8.3.2


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

* [PATCH 34/41] perf evlist: Add 'system_wide' option
  2014-07-14 10:02 [PATCH 00/41] perf tools: Preparation for call graph from Intel BTS Adrian Hunter
                   ` (32 preceding siblings ...)
  2014-07-14 10:02 ` [PATCH 33/41] perf evsel: Add 'immediate' option Adrian Hunter
@ 2014-07-14 10:02 ` Adrian Hunter
  2014-07-15 15:03   ` Arnaldo Carvalho de Melo
  2014-08-11 13:12   ` Jiri Olsa
  2014-07-14 10:02 ` [PATCH 35/41] perf tools: Add id index Adrian Hunter
                   ` (6 subsequent siblings)
  40 siblings, 2 replies; 122+ messages in thread
From: Adrian Hunter @ 2014-07-14 10:02 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Peter Zijlstra, linux-kernel, David Ahern, Frederic Weisbecker,
	Jiri Olsa, Namhyung Kim, Paul Mackerras, Stephane Eranian

Add an option to cause a selected event
to be opened always without a pid when
configured by perf_evsel__config().

This is needed when using the sched_switch
tracepoint to follow object code execution.
sched_switch occurs before the task
switch and so it cannot record it in a
context limited to that task.  Note
that also means that sched_switch is
useless when capturing data per-thread,
as is the 'context-switches' software
event for the same reason.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
 tools/perf/util/evlist.c | 45 +++++++++++++++++++++++++++++++++++++--------
 tools/perf/util/evsel.c  | 31 ++++++++++++++++++++++++++-----
 tools/perf/util/evsel.h  |  1 +
 3 files changed, 64 insertions(+), 13 deletions(-)

diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index 282e83e..c295b7b 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -265,17 +265,27 @@ int perf_evlist__add_newtp(struct perf_evlist *evlist,
 	return 0;
 }
 
+static int perf_evlist__nr_threads(struct perf_evlist *evlist,
+				   struct perf_evsel *evsel)
+{
+	if (evsel->system_wide)
+		return 1;
+	else
+		return thread_map__nr(evlist->threads);
+}
+
 void perf_evlist__disable(struct perf_evlist *evlist)
 {
 	int cpu, thread;
 	struct perf_evsel *pos;
 	int nr_cpus = cpu_map__nr(evlist->cpus);
-	int nr_threads = thread_map__nr(evlist->threads);
+	int nr_threads;
 
 	for (cpu = 0; cpu < nr_cpus; cpu++) {
 		evlist__for_each(evlist, pos) {
 			if (!perf_evsel__is_group_leader(pos) || !pos->fd)
 				continue;
+			nr_threads = perf_evlist__nr_threads(evlist, pos);
 			for (thread = 0; thread < nr_threads; thread++)
 				ioctl(FD(pos, cpu, thread),
 				      PERF_EVENT_IOC_DISABLE, 0);
@@ -288,12 +298,13 @@ void perf_evlist__enable(struct perf_evlist *evlist)
 	int cpu, thread;
 	struct perf_evsel *pos;
 	int nr_cpus = cpu_map__nr(evlist->cpus);
-	int nr_threads = thread_map__nr(evlist->threads);
+	int nr_threads;
 
 	for (cpu = 0; cpu < nr_cpus; cpu++) {
 		evlist__for_each(evlist, pos) {
 			if (!perf_evsel__is_group_leader(pos) || !pos->fd)
 				continue;
+			nr_threads = perf_evlist__nr_threads(evlist, pos);
 			for (thread = 0; thread < nr_threads; thread++)
 				ioctl(FD(pos, cpu, thread),
 				      PERF_EVENT_IOC_ENABLE, 0);
@@ -305,12 +316,14 @@ int perf_evlist__disable_event(struct perf_evlist *evlist,
 			       struct perf_evsel *evsel)
 {
 	int cpu, thread, err;
+	int nr_cpus = cpu_map__nr(evlist->cpus);
+	int nr_threads = perf_evlist__nr_threads(evlist, evsel);
 
 	if (!evsel->fd)
 		return 0;
 
-	for (cpu = 0; cpu < evlist->cpus->nr; cpu++) {
-		for (thread = 0; thread < evlist->threads->nr; thread++) {
+	for (cpu = 0; cpu < nr_cpus; cpu++) {
+		for (thread = 0; thread < nr_threads; thread++) {
 			err = ioctl(FD(evsel, cpu, thread),
 				    PERF_EVENT_IOC_DISABLE, 0);
 			if (err)
@@ -324,12 +337,14 @@ int perf_evlist__enable_event(struct perf_evlist *evlist,
 			      struct perf_evsel *evsel)
 {
 	int cpu, thread, err;
+	int nr_cpus = cpu_map__nr(evlist->cpus);
+	int nr_threads = perf_evlist__nr_threads(evlist, evsel);
 
 	if (!evsel->fd)
 		return -EINVAL;
 
-	for (cpu = 0; cpu < evlist->cpus->nr; cpu++) {
-		for (thread = 0; thread < evlist->threads->nr; thread++) {
+	for (cpu = 0; cpu < nr_cpus; cpu++) {
+		for (thread = 0; thread < nr_threads; thread++) {
 			err = ioctl(FD(evsel, cpu, thread),
 				    PERF_EVENT_IOC_ENABLE, 0);
 			if (err)
@@ -343,7 +358,16 @@ static int perf_evlist__alloc_pollfd(struct perf_evlist *evlist)
 {
 	int nr_cpus = cpu_map__nr(evlist->cpus);
 	int nr_threads = thread_map__nr(evlist->threads);
-	int nfds = nr_cpus * nr_threads * evlist->nr_entries;
+	int nfds = 0;
+	struct perf_evsel *evsel;
+
+	list_for_each_entry(evsel, &evlist->entries, node) {
+		if (evsel->system_wide)
+			nfds += nr_cpus;
+		else
+			nfds += nr_cpus * nr_threads;
+	}
+
 	evlist->pollfd = malloc(sizeof(struct pollfd) * nfds);
 	return evlist->pollfd != NULL ? 0 : -ENOMEM;
 }
@@ -636,7 +660,12 @@ static int perf_evlist__mmap_per_evsel(struct perf_evlist *evlist, int idx,
 	struct perf_evsel *evsel;
 
 	evlist__for_each(evlist, evsel) {
-		int fd = FD(evsel, cpu, thread);
+		int fd;
+
+		if (evsel->system_wide && thread)
+			continue;
+
+		fd = FD(evsel, cpu, thread);
 
 		if (*output == -1) {
 			*output = fd;
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 90f58cd..7540b5f 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -691,6 +691,10 @@ void perf_evsel__config(struct perf_evsel *evsel, struct record_opts *opts)
 int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthreads)
 {
 	int cpu, thread;
+
+	if (evsel->system_wide)
+		nthreads = 1;
+
 	evsel->fd = xyarray__new(ncpus, nthreads, sizeof(int));
 
 	if (evsel->fd) {
@@ -709,6 +713,9 @@ static int perf_evsel__run_ioctl(struct perf_evsel *evsel, int ncpus, int nthrea
 {
 	int cpu, thread;
 
+	if (evsel->system_wide)
+		nthreads = 1;
+
 	for (cpu = 0; cpu < ncpus; cpu++) {
 		for (thread = 0; thread < nthreads; thread++) {
 			int fd = FD(evsel, cpu, thread),
@@ -739,6 +746,9 @@ int perf_evsel__enable(struct perf_evsel *evsel, int ncpus, int nthreads)
 
 int perf_evsel__alloc_id(struct perf_evsel *evsel, int ncpus, int nthreads)
 {
+	if (evsel->system_wide)
+		nthreads = 1;
+
 	evsel->sample_id = xyarray__new(ncpus, nthreads, sizeof(struct perf_sample_id));
 	if (evsel->sample_id == NULL)
 		return -ENOMEM;
@@ -783,6 +793,9 @@ void perf_evsel__close_fd(struct perf_evsel *evsel, int ncpus, int nthreads)
 {
 	int cpu, thread;
 
+	if (evsel->system_wide)
+		nthreads = 1;
+
 	for (cpu = 0; cpu < ncpus; cpu++)
 		for (thread = 0; thread < nthreads; ++thread) {
 			close(FD(evsel, cpu, thread));
@@ -871,6 +884,9 @@ int __perf_evsel__read(struct perf_evsel *evsel,
 	int cpu, thread;
 	struct perf_counts_values *aggr = &evsel->counts->aggr, count;
 
+	if (evsel->system_wide)
+		nthreads = 1;
+
 	aggr->val = aggr->ena = aggr->run = 0;
 
 	for (cpu = 0; cpu < ncpus; cpu++) {
@@ -993,13 +1009,18 @@ static size_t perf_event_attr__fprintf(struct perf_event_attr *attr, FILE *fp)
 static int __perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus,
 			      struct thread_map *threads)
 {
-	int cpu, thread;
+	int cpu, thread, nthreads;
 	unsigned long flags = 0;
 	int pid = -1, err;
 	enum { NO_CHANGE, SET_TO_MAX, INCREASED_MAX } set_rlimit = NO_CHANGE;
 
+	if (evsel->system_wide)
+		nthreads = 1;
+	else
+		nthreads = threads->nr;
+
 	if (evsel->fd == NULL &&
-	    perf_evsel__alloc_fd(evsel, cpus->nr, threads->nr) < 0)
+	    perf_evsel__alloc_fd(evsel, cpus->nr, nthreads) < 0)
 		return -ENOMEM;
 
 	if (evsel->cgrp) {
@@ -1021,10 +1042,10 @@ retry_sample_id:
 
 	for (cpu = 0; cpu < cpus->nr; cpu++) {
 
-		for (thread = 0; thread < threads->nr; thread++) {
+		for (thread = 0; thread < nthreads; thread++) {
 			int group_fd;
 
-			if (!evsel->cgrp)
+			if (!evsel->cgrp && !evsel->system_wide)
 				pid = threads->map[thread];
 
 			group_fd = get_group_fd(evsel, cpu, thread);
@@ -1094,7 +1115,7 @@ out_close:
 			close(FD(evsel, cpu, thread));
 			FD(evsel, cpu, thread) = -1;
 		}
-		thread = threads->nr;
+		thread = nthreads;
 	} while (--cpu >= 0);
 	return err;
 }
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index d7f93ce..dbb2a0d 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -85,6 +85,7 @@ struct perf_evsel {
 	bool 			needs_swap;
 	bool			no_aux_samples;
 	bool			immediate;
+	bool			system_wide;
 	/* parse modifier helper */
 	int			exclude_GH;
 	int			nr_members;
-- 
1.8.3.2


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

* [PATCH 35/41] perf tools: Add id index
  2014-07-14 10:02 [PATCH 00/41] perf tools: Preparation for call graph from Intel BTS Adrian Hunter
                   ` (33 preceding siblings ...)
  2014-07-14 10:02 ` [PATCH 34/41] perf evlist: Add 'system_wide' option Adrian Hunter
@ 2014-07-14 10:02 ` Adrian Hunter
  2014-07-14 10:03 ` [PATCH 36/41] perf pmu: Let pmu's with no events show up on perf list Adrian Hunter
                   ` (5 subsequent siblings)
  40 siblings, 0 replies; 122+ messages in thread
From: Adrian Hunter @ 2014-07-14 10:02 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Peter Zijlstra, linux-kernel, David Ahern, Frederic Weisbecker,
	Jiri Olsa, Namhyung Kim, Paul Mackerras, Stephane Eranian

Add an index of the event identifiers.

This is needed to queue Instruction
Trace samples according to the mmap
buffer from which they were recorded.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
 tools/perf/builtin-inject.c |   1 +
 tools/perf/util/event.c     |   1 +
 tools/perf/util/event.h     |  15 ++++++
 tools/perf/util/evlist.c    |  26 ++++++++--
 tools/perf/util/evsel.h     |   3 ++
 tools/perf/util/session.c   | 122 ++++++++++++++++++++++++++++++++++++++++++++
 tools/perf/util/session.h   |  10 ++++
 tools/perf/util/tool.h      |   3 +-
 8 files changed, 177 insertions(+), 4 deletions(-)

diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c
index cf6a605..ce691c4 100644
--- a/tools/perf/builtin-inject.c
+++ b/tools/perf/builtin-inject.c
@@ -419,6 +419,7 @@ int cmd_inject(int argc, const char **argv, const char *prefix __maybe_unused)
 			.tracing_data	= perf_event__repipe_op2_synth,
 			.finished_round	= perf_event__repipe_op2_synth,
 			.build_id	= perf_event__repipe_op2_synth,
+			.id_index	= perf_event__repipe_op2_synth,
 		},
 		.input_name  = "-",
 		.samples = LIST_HEAD_INIT(inject.samples),
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index d1283cc..dc32de0 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -28,6 +28,7 @@ static const char *perf_event__names[] = {
 	[PERF_RECORD_HEADER_TRACING_DATA]	= "TRACING_DATA",
 	[PERF_RECORD_HEADER_BUILD_ID]		= "BUILD_ID",
 	[PERF_RECORD_FINISHED_ROUND]		= "FINISHED_ROUND",
+	[PERF_RECORD_ID_INDEX]			= "ID_INDEX",
 };
 
 const char *perf_event__name(unsigned int id)
diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h
index e5dd40a..3fa9ab1 100644
--- a/tools/perf/util/event.h
+++ b/tools/perf/util/event.h
@@ -185,6 +185,7 @@ enum perf_user_event_type { /* above any possible kernel type */
 	PERF_RECORD_HEADER_TRACING_DATA		= 66,
 	PERF_RECORD_HEADER_BUILD_ID		= 67,
 	PERF_RECORD_FINISHED_ROUND		= 68,
+	PERF_RECORD_ID_INDEX			= 69,
 	PERF_RECORD_HEADER_MAX
 };
 
@@ -211,6 +212,19 @@ struct tracing_data_event {
 	u32 size;
 };
 
+struct id_index_entry {
+	u64 id;
+	u64 idx;
+	u64 cpu;
+	u64 tid;
+};
+
+struct id_index_event {
+	struct perf_event_header header;
+	u64 nr;
+	struct id_index_entry entries[0];
+};
+
 union perf_event {
 	struct perf_event_header	header;
 	struct mmap_event		mmap;
@@ -225,6 +239,7 @@ union perf_event {
 	struct event_type_event		event_type;
 	struct tracing_data_event	tracing_data;
 	struct build_id_event		build_id;
+	struct id_index_event		id_index;
 };
 
 void perf_event__print_totals(void);
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index c295b7b..10514f3 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -441,6 +441,22 @@ static int perf_evlist__id_add_fd(struct perf_evlist *evlist,
 	return 0;
 }
 
+static void perf_evlist__set_sid_idx(struct perf_evlist *evlist,
+				     struct perf_evsel *evsel, int idx, int cpu,
+				     int thread)
+{
+	struct perf_sample_id *sid = SID(evsel, cpu, thread);
+	sid->idx = idx;
+	if (evlist->cpus && cpu >= 0)
+		sid->cpu = evlist->cpus->map[cpu];
+	else
+		sid->cpu = -1;
+	if (!evsel->system_wide && evlist->threads && thread >= 0)
+		sid->tid = evlist->threads->map[thread];
+	else
+		sid->tid = -1;
+}
+
 struct perf_sample_id *perf_evlist__id2sid(struct perf_evlist *evlist, u64 id)
 {
 	struct hlist_head *head;
@@ -676,9 +692,13 @@ static int perf_evlist__mmap_per_evsel(struct perf_evlist *evlist, int idx,
 				return -1;
 		}
 
-		if ((evsel->attr.read_format & PERF_FORMAT_ID) &&
-		    perf_evlist__id_add_fd(evlist, evsel, cpu, thread, fd) < 0)
-			return -1;
+		if (evsel->attr.read_format & PERF_FORMAT_ID) {
+			if (perf_evlist__id_add_fd(evlist, evsel, cpu, thread,
+						   fd) < 0)
+				return -1;
+			perf_evlist__set_sid_idx(evlist, evsel, idx, cpu,
+						 thread);
+		}
 	}
 
 	return 0;
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index dbb2a0d..330218a 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -38,6 +38,9 @@ struct perf_sample_id {
 	struct hlist_node 	node;
 	u64		 	id;
 	struct perf_evsel	*evsel;
+	int			idx;
+	int			cpu;
+	pid_t			tid;
 
 	/* Holds total ID period value for PERF_SAMPLE_READ processing. */
 	u64			period;
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 7b0fb03..8aa1be1 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -231,6 +231,15 @@ static int process_finished_round(struct perf_tool *tool,
 				  union perf_event *event,
 				  struct perf_session *session);
 
+static int process_id_index_stub(struct perf_tool *tool __maybe_unused,
+				 union perf_event *event __maybe_unused,
+				 struct perf_session *perf_session
+				 __maybe_unused)
+{
+	dump_printf(": unhandled!\n");
+	return 0;
+}
+
 void perf_tool__fill_defaults(struct perf_tool *tool)
 {
 	if (tool->sample == NULL)
@@ -265,6 +274,8 @@ void perf_tool__fill_defaults(struct perf_tool *tool)
 		else
 			tool->finished_round = process_finished_round_stub;
 	}
+	if (tool->id_index == NULL)
+		tool->id_index = process_id_index_stub;
 }
  
 static void swap_sample_id_all(union perf_event *event, void *data)
@@ -463,6 +474,7 @@ static perf_event__swap_op perf_event__swap_ops[] = {
 	[PERF_RECORD_HEADER_EVENT_TYPE]	  = perf_event__event_type_swap,
 	[PERF_RECORD_HEADER_TRACING_DATA] = perf_event__tracing_data_swap,
 	[PERF_RECORD_HEADER_BUILD_ID]	  = NULL,
+	[PERF_RECORD_ID_INDEX]		  = perf_event__all64_swap,
 	[PERF_RECORD_HEADER_MAX]	  = NULL,
 };
 
@@ -1045,6 +1057,8 @@ static int perf_session__process_user_event(struct perf_session *session, union
 		return tool->build_id(tool, event, session);
 	case PERF_RECORD_FINISHED_ROUND:
 		return tool->finished_round(tool, event, session);
+	case PERF_RECORD_ID_INDEX:
+		return tool->id_index(tool, event, session);
 	default:
 		return -EINVAL;
 	}
@@ -1701,3 +1715,111 @@ int __perf_session__set_tracepoints_handlers(struct perf_session *session,
 out:
 	return err;
 }
+
+int perf_event__process_id_index(struct perf_tool *tool __maybe_unused,
+				 union perf_event *event,
+				 struct perf_session *session)
+{
+	struct perf_evlist *evlist = session->evlist;
+	struct id_index_event *ie = &event->id_index;
+	size_t i, nr, max_nr;
+
+	max_nr = (ie->header.size - sizeof(struct id_index_event)) /
+		 sizeof(struct id_index_entry);
+	nr = ie->nr;
+	if (nr > max_nr)
+		return -EINVAL;
+
+	if (dump_trace)
+		fprintf(stdout, " nr: %zu\n", nr);
+
+	for (i = 0; i < nr; i++) {
+		struct id_index_entry *e = &ie->entries[i];
+		struct perf_sample_id *sid;
+
+		if (dump_trace) {
+			fprintf(stdout,	" ... id: %"PRIu64, e->id);
+			fprintf(stdout,	"  idx: %"PRIu64, e->idx);
+			fprintf(stdout,	"  cpu: %"PRId64, e->cpu);
+			fprintf(stdout,	"  tid: %"PRId64"\n", e->tid);
+		}
+
+		sid = perf_evlist__id2sid(evlist, e->id);
+		if (!sid)
+			return -ENOENT;
+		sid->idx = e->idx;
+		sid->cpu = e->cpu;
+		sid->tid = e->tid;
+	}
+	return 0;
+}
+
+int perf_event__synthesize_id_index(struct perf_tool *tool,
+				    perf_event__handler_t process,
+				    struct perf_evlist *evlist,
+				    struct machine *machine)
+{
+	union perf_event *ev;
+	struct perf_evsel *evsel;
+	size_t nr = 0, i = 0, sz, max_nr, n;
+	int err;
+
+	pr_debug2("Synthesizing id index\n");
+
+	max_nr = (UINT16_MAX - sizeof(struct id_index_event)) /
+		 sizeof(struct id_index_entry);
+
+	list_for_each_entry(evsel, &evlist->entries, node)
+		nr += evsel->ids;
+
+	n = nr > max_nr ? max_nr : nr;
+	sz = sizeof(struct id_index_event) + n * sizeof(struct id_index_entry);
+	ev = zalloc(sz);
+	if (!ev)
+		return -ENOMEM;
+
+	ev->id_index.header.type = PERF_RECORD_ID_INDEX;
+	ev->id_index.header.size = sz;
+	ev->id_index.nr = n;
+
+	list_for_each_entry(evsel, &evlist->entries, node) {
+		u32 j;
+
+		for (j = 0; j < evsel->ids; j++) {
+			struct id_index_entry *e;
+			struct perf_sample_id *sid;
+
+			if (i >= n) {
+				err = process(tool, ev, NULL, machine);
+				if (err)
+					goto out_err;
+				nr -= n;
+				i = 0;
+			}
+
+			e = &ev->id_index.entries[i++];
+
+			e->id = evsel->id[j];
+
+			sid = perf_evlist__id2sid(evlist, e->id);
+			if (!sid) {
+				free(ev);
+				return -ENOENT;
+			}
+
+			e->idx = sid->idx;
+			e->cpu = sid->cpu;
+			e->tid = sid->tid;
+		}
+	}
+
+	sz = sizeof(struct id_index_event) + nr * sizeof(struct id_index_entry);
+	ev->id_index.header.size = sz;
+	ev->id_index.nr = nr;
+
+	err = process(tool, ev, NULL, machine);
+out_err:
+	free(ev);
+
+	return err;
+}
diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h
index 0321013..39327ca 100644
--- a/tools/perf/util/session.h
+++ b/tools/perf/util/session.h
@@ -129,4 +129,14 @@ int __perf_session__set_tracepoints_handlers(struct perf_session *session,
 extern volatile int session_done;
 
 #define session_done()	(*(volatile int *)(&session_done))
+
+int perf_event__process_id_index(struct perf_tool *tool,
+				 union perf_event *event,
+				 struct perf_session *session);
+
+int perf_event__synthesize_id_index(struct perf_tool *tool,
+				    perf_event__handler_t process,
+				    struct perf_evlist *evlist,
+				    struct machine *machine);
+
 #endif /* __PERF_SESSION_H */
diff --git a/tools/perf/util/tool.h b/tools/perf/util/tool.h
index 4385816..f07d6fe 100644
--- a/tools/perf/util/tool.h
+++ b/tools/perf/util/tool.h
@@ -39,7 +39,8 @@ struct perf_tool {
 	event_attr_op	attr;
 	event_op2	tracing_data;
 	event_op2	finished_round,
-			build_id;
+			build_id,
+			id_index;
 	bool		ordered_samples;
 	bool		ordering_requires_timestamps;
 };
-- 
1.8.3.2


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

* [PATCH 36/41] perf pmu: Let pmu's with no events show up on perf list
  2014-07-14 10:02 [PATCH 00/41] perf tools: Preparation for call graph from Intel BTS Adrian Hunter
                   ` (34 preceding siblings ...)
  2014-07-14 10:02 ` [PATCH 35/41] perf tools: Add id index Adrian Hunter
@ 2014-07-14 10:03 ` Adrian Hunter
  2014-07-14 10:03 ` [PATCH 37/41] perf session: Add ability to skip 4GiB or more Adrian Hunter
                   ` (4 subsequent siblings)
  40 siblings, 0 replies; 122+ messages in thread
From: Adrian Hunter @ 2014-07-14 10:03 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Peter Zijlstra, linux-kernel, David Ahern, Frederic Weisbecker,
	Jiri Olsa, Namhyung Kim, Paul Mackerras, Stephane Eranian

perf list only lists PMUs with events.  Add a
flag to cause a PMU to be also listed separately.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
 tools/perf/util/pmu.c | 13 +++++++++++--
 tools/perf/util/pmu.h |  1 +
 2 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
index 348d1d2..ba300d9 100644
--- a/tools/perf/util/pmu.c
+++ b/tools/perf/util/pmu.c
@@ -749,15 +749,18 @@ void print_pmu_events(const char *event_glob, bool name_only)
 
 	pmu = NULL;
 	len = 0;
-	while ((pmu = perf_pmu__scan(pmu)) != NULL)
+	while ((pmu = perf_pmu__scan(pmu)) != NULL) {
 		list_for_each_entry(alias, &pmu->aliases, list)
 			len++;
+		if (pmu->selectable)
+			len++;
+	}
 	aliases = malloc(sizeof(char *) * len);
 	if (!aliases)
 		return;
 	pmu = NULL;
 	j = 0;
-	while ((pmu = perf_pmu__scan(pmu)) != NULL)
+	while ((pmu = perf_pmu__scan(pmu)) != NULL) {
 		list_for_each_entry(alias, &pmu->aliases, list) {
 			char *name = format_alias(buf, sizeof(buf), pmu, alias);
 			bool is_cpu = !strcmp(pmu->name, "cpu");
@@ -774,6 +777,12 @@ void print_pmu_events(const char *event_glob, bool name_only)
 			aliases[j] = strdup(aliases[j]);
 			j++;
 		}
+		if (pmu->selectable) {
+			scnprintf(buf, sizeof(buf), "%s//", pmu->name);
+			aliases[j] = strdup(buf);
+			j++;
+		}
+	}
 	len = j;
 	qsort(aliases, len, sizeof(char *), cmp_string);
 	for (j = 0; j < len; j++) {
diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h
index c35f578..8c999b3 100644
--- a/tools/perf/util/pmu.h
+++ b/tools/perf/util/pmu.h
@@ -18,6 +18,7 @@ struct perf_event_attr;
 struct perf_pmu {
 	char *name;
 	__u32 type;
+	bool selectable;
 	struct perf_event_attr *default_config;
 	struct cpu_map *cpus;
 	struct list_head format;
-- 
1.8.3.2


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

* [PATCH 37/41] perf session: Add ability to skip 4GiB or more
  2014-07-14 10:02 [PATCH 00/41] perf tools: Preparation for call graph from Intel BTS Adrian Hunter
                   ` (35 preceding siblings ...)
  2014-07-14 10:03 ` [PATCH 36/41] perf pmu: Let pmu's with no events show up on perf list Adrian Hunter
@ 2014-07-14 10:03 ` Adrian Hunter
  2014-07-14 10:03 ` [PATCH 38/41] perf session: Add perf_session__deliver_synth_event() Adrian Hunter
                   ` (3 subsequent siblings)
  40 siblings, 0 replies; 122+ messages in thread
From: Adrian Hunter @ 2014-07-14 10:03 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Peter Zijlstra, linux-kernel, David Ahern, Frederic Weisbecker,
	Jiri Olsa, Namhyung Kim, Paul Mackerras, Stephane Eranian

A session can be made to skip portions of the input
file.  Do not limit that size to 32-bits.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
 tools/perf/util/session.c | 20 +++++++++++++-------
 1 file changed, 13 insertions(+), 7 deletions(-)

diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 8aa1be1..708e1c1 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -1026,8 +1026,10 @@ static int perf_session_deliver_event(struct perf_session *session,
 	}
 }
 
-static int perf_session__process_user_event(struct perf_session *session, union perf_event *event,
-					    struct perf_tool *tool, u64 file_offset)
+static s64 perf_session__process_user_event(struct perf_session *session,
+					    union perf_event *event,
+					    struct perf_tool *tool,
+					    u64 file_offset)
 {
 	int fd = perf_data_file__fd(session->file);
 	int err;
@@ -1073,7 +1075,7 @@ static void event_swap(union perf_event *event, bool sample_id_all)
 		swap(event, sample_id_all);
 }
 
-static int perf_session__process_event(struct perf_session *session,
+static s64 perf_session__process_event(struct perf_session *session,
 				       union perf_event *event,
 				       struct perf_tool *tool,
 				       u64 file_offset)
@@ -1184,7 +1186,7 @@ static int __perf_session__process_pipe_events(struct perf_session *session,
 	union perf_event *event;
 	uint32_t size, cur_size = 0;
 	void *buf = NULL;
-	int skip = 0;
+	s64 skip = 0;
 	u64 head;
 	ssize_t err;
 	void *p;
@@ -1313,13 +1315,13 @@ int __perf_session__process_events(struct perf_session *session,
 				   u64 file_size, struct perf_tool *tool)
 {
 	int fd = perf_data_file__fd(session->file);
-	u64 head, page_offset, file_offset, file_pos;
+	u64 head, page_offset, file_offset, file_pos, size;
 	int err, mmap_prot, mmap_flags, map_idx = 0;
 	size_t	mmap_size;
 	char *buf, *mmaps[NUM_MMAPS];
 	union perf_event *event;
-	uint32_t size;
 	struct ui_progress prog;
+	s64 skip;
 
 	perf_tool__fill_defaults(tool);
 
@@ -1380,7 +1382,8 @@ more:
 	size = event->header.size;
 
 	if (size < sizeof(struct perf_event_header) ||
-	    perf_session__process_event(session, event, tool, file_pos) < 0) {
+	    (skip = perf_session__process_event(session, event, tool, file_pos))
+									< 0) {
 		pr_err("%#" PRIx64 " [%#x]: failed to process type: %d\n",
 		       file_offset + head, event->header.size,
 		       event->header.type);
@@ -1388,6 +1391,9 @@ more:
 		goto out_err;
 	}
 
+	if (skip)
+		size += skip;
+
 	head += size;
 	file_pos += size;
 
-- 
1.8.3.2


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

* [PATCH 38/41] perf session: Add perf_session__deliver_synth_event()
  2014-07-14 10:02 [PATCH 00/41] perf tools: Preparation for call graph from Intel BTS Adrian Hunter
                   ` (36 preceding siblings ...)
  2014-07-14 10:03 ` [PATCH 37/41] perf session: Add ability to skip 4GiB or more Adrian Hunter
@ 2014-07-14 10:03 ` Adrian Hunter
  2014-07-15 15:17   ` Arnaldo Carvalho de Melo
  2014-07-14 10:03 ` [PATCH 39/41] perf tools: Allow TSC conversion on any arch Adrian Hunter
                   ` (2 subsequent siblings)
  40 siblings, 1 reply; 122+ messages in thread
From: Adrian Hunter @ 2014-07-14 10:03 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Peter Zijlstra, linux-kernel, David Ahern, Frederic Weisbecker,
	Jiri Olsa, Namhyung Kim, Paul Mackerras, Stephane Eranian

Add a function to deliver synthesized events from
within a session.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
 tools/perf/util/session.c | 14 ++++++++++++++
 tools/perf/util/session.h |  5 +++++
 2 files changed, 19 insertions(+)

diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 708e1c1..433884c 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -1066,6 +1066,20 @@ static s64 perf_session__process_user_event(struct perf_session *session,
 	}
 }
 
+int perf_session__deliver_synth_event(struct perf_session *session,
+				      union perf_event *event,
+				      struct perf_sample *sample,
+				      struct perf_tool *tool)
+{
+	events_stats__inc(&session->stats, event->header.type);
+
+	if (event->header.type >= PERF_RECORD_USER_TYPE_START)
+		return perf_session__process_user_event(session, event, tool,
+							0);
+
+	return perf_session_deliver_event(session, event, sample, tool, 0);
+}
+
 static void event_swap(union perf_event *event, bool sample_id_all)
 {
 	perf_event__swap_op swap;
diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h
index 39327ca..86f1bb4 100644
--- a/tools/perf/util/session.h
+++ b/tools/perf/util/session.h
@@ -130,6 +130,11 @@ extern volatile int session_done;
 
 #define session_done()	(*(volatile int *)(&session_done))
 
+int perf_session__deliver_synth_event(struct perf_session *session,
+				      union perf_event *event,
+				      struct perf_sample *sample,
+				      struct perf_tool *tool);
+
 int perf_event__process_id_index(struct perf_tool *tool,
 				 union perf_event *event,
 				 struct perf_session *session);
-- 
1.8.3.2


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

* [PATCH 39/41] perf tools: Allow TSC conversion on any arch
  2014-07-14 10:02 [PATCH 00/41] perf tools: Preparation for call graph from Intel BTS Adrian Hunter
                   ` (37 preceding siblings ...)
  2014-07-14 10:03 ` [PATCH 38/41] perf session: Add perf_session__deliver_synth_event() Adrian Hunter
@ 2014-07-14 10:03 ` Adrian Hunter
  2014-07-15 15:20   ` Arnaldo Carvalho de Melo
  2014-07-18  4:28   ` [tip:perf/core] " tip-bot for Adrian Hunter
  2014-07-14 10:03 ` [PATCH 40/41] perf tools: Move rdtsc() function Adrian Hunter
  2014-07-14 10:03 ` [PATCH 41/41] perf evlist: Add perf_evlist__enable_event_idx() Adrian Hunter
  40 siblings, 2 replies; 122+ messages in thread
From: Adrian Hunter @ 2014-07-14 10:03 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Peter Zijlstra, linux-kernel, David Ahern, Frederic Weisbecker,
	Jiri Olsa, Namhyung Kim, Paul Mackerras, Stephane Eranian

It is possible to record a perf.data file on
one architecture and process it on another.
Consequently, TSC conversion functions need
to be moved out of the arch directory.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
 tools/perf/Makefile.perf            |  2 ++
 tools/perf/arch/x86/util/tsc.c      | 22 +---------------------
 tools/perf/arch/x86/util/tsc.h      |  3 ---
 tools/perf/tests/perf-time-to-tsc.c |  3 +--
 tools/perf/util/tsc.c               | 25 +++++++++++++++++++++++++
 tools/perf/util/tsc.h               | 11 +++++++++++
 6 files changed, 40 insertions(+), 26 deletions(-)
 create mode 100644 tools/perf/util/tsc.c
 create mode 100644 tools/perf/util/tsc.h

diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index 9670a16..abca577 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -295,6 +295,7 @@ LIB_H += util/intlist.h
 LIB_H += util/perf_regs.h
 LIB_H += util/unwind.h
 LIB_H += util/vdso.h
+LIB_H += util/tsc.h
 LIB_H += ui/helpline.h
 LIB_H += ui/progress.h
 LIB_H += ui/util.h
@@ -373,6 +374,7 @@ LIB_OBJS += $(OUTPUT)util/stat.o
 LIB_OBJS += $(OUTPUT)util/record.o
 LIB_OBJS += $(OUTPUT)util/srcline.o
 LIB_OBJS += $(OUTPUT)util/data.o
+LIB_OBJS += $(OUTPUT)util/tsc.o
 
 LIB_OBJS += $(OUTPUT)ui/setup.o
 LIB_OBJS += $(OUTPUT)ui/helpline.o
diff --git a/tools/perf/arch/x86/util/tsc.c b/tools/perf/arch/x86/util/tsc.c
index 40021fa..3655f24 100644
--- a/tools/perf/arch/x86/util/tsc.c
+++ b/tools/perf/arch/x86/util/tsc.c
@@ -6,29 +6,9 @@
 #include "../../perf.h"
 #include <linux/types.h>
 #include "../../util/debug.h"
+#include "../../util/tsc.h"
 #include "tsc.h"
 
-u64 perf_time_to_tsc(u64 ns, struct perf_tsc_conversion *tc)
-{
-	u64 t, quot, rem;
-
-	t = ns - tc->time_zero;
-	quot = t / tc->time_mult;
-	rem  = t % tc->time_mult;
-	return (quot << tc->time_shift) +
-	       (rem << tc->time_shift) / tc->time_mult;
-}
-
-u64 tsc_to_perf_time(u64 cyc, struct perf_tsc_conversion *tc)
-{
-	u64 quot, rem;
-
-	quot = cyc >> tc->time_shift;
-	rem  = cyc & ((1 << tc->time_shift) - 1);
-	return tc->time_zero + quot * tc->time_mult +
-	       ((rem * tc->time_mult) >> tc->time_shift);
-}
-
 int perf_read_tsc_conversion(const struct perf_event_mmap_page *pc,
 			     struct perf_tsc_conversion *tc)
 {
diff --git a/tools/perf/arch/x86/util/tsc.h b/tools/perf/arch/x86/util/tsc.h
index 2affe03..2edc4d3 100644
--- a/tools/perf/arch/x86/util/tsc.h
+++ b/tools/perf/arch/x86/util/tsc.h
@@ -14,7 +14,4 @@ struct perf_event_mmap_page;
 int perf_read_tsc_conversion(const struct perf_event_mmap_page *pc,
 			     struct perf_tsc_conversion *tc);
 
-u64 perf_time_to_tsc(u64 ns, struct perf_tsc_conversion *tc);
-u64 tsc_to_perf_time(u64 cyc, struct perf_tsc_conversion *tc);
-
 #endif /* TOOLS_PERF_ARCH_X86_UTIL_TSC_H__ */
diff --git a/tools/perf/tests/perf-time-to-tsc.c b/tools/perf/tests/perf-time-to-tsc.c
index 3b7cd4d..0372f6e 100644
--- a/tools/perf/tests/perf-time-to-tsc.c
+++ b/tools/perf/tests/perf-time-to-tsc.c
@@ -8,10 +8,9 @@
 #include "evsel.h"
 #include "thread_map.h"
 #include "cpumap.h"
+#include "tsc.h"
 #include "tests.h"
 
-#include "../arch/x86/util/tsc.h"
-
 #define CHECK__(x) {				\
 	while ((x) < 0) {			\
 		pr_debug(#x " failed!\n");	\
diff --git a/tools/perf/util/tsc.c b/tools/perf/util/tsc.c
new file mode 100644
index 0000000..ef4749836
--- /dev/null
+++ b/tools/perf/util/tsc.c
@@ -0,0 +1,25 @@
+#include <linux/compiler.h>
+#include <linux/types.h>
+
+#include "tsc.h"
+
+u64 perf_time_to_tsc(u64 ns, struct perf_tsc_conversion *tc)
+{
+	u64 t, quot, rem;
+
+	t = ns - tc->time_zero;
+	quot = t / tc->time_mult;
+	rem  = t % tc->time_mult;
+	return (quot << tc->time_shift) +
+	       (rem << tc->time_shift) / tc->time_mult;
+}
+
+u64 tsc_to_perf_time(u64 cyc, struct perf_tsc_conversion *tc)
+{
+	u64 quot, rem;
+
+	quot = cyc >> tc->time_shift;
+	rem  = cyc & ((1 << tc->time_shift) - 1);
+	return tc->time_zero + quot * tc->time_mult +
+	       ((rem * tc->time_mult) >> tc->time_shift);
+}
diff --git a/tools/perf/util/tsc.h b/tools/perf/util/tsc.h
new file mode 100644
index 0000000..4eca848
--- /dev/null
+++ b/tools/perf/util/tsc.h
@@ -0,0 +1,11 @@
+#ifndef __PERF_TSC_H
+#define __PERF_TSC_H
+
+#include <linux/types.h>
+
+#include "../arch/x86/util/tsc.h"
+
+u64 perf_time_to_tsc(u64 ns, struct perf_tsc_conversion *tc);
+u64 tsc_to_perf_time(u64 cyc, struct perf_tsc_conversion *tc);
+
+#endif
-- 
1.8.3.2


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

* [PATCH 40/41] perf tools: Move rdtsc() function
  2014-07-14 10:02 [PATCH 00/41] perf tools: Preparation for call graph from Intel BTS Adrian Hunter
                   ` (38 preceding siblings ...)
  2014-07-14 10:03 ` [PATCH 39/41] perf tools: Allow TSC conversion on any arch Adrian Hunter
@ 2014-07-14 10:03 ` Adrian Hunter
  2014-07-14 10:03 ` [PATCH 41/41] perf evlist: Add perf_evlist__enable_event_idx() Adrian Hunter
  40 siblings, 0 replies; 122+ messages in thread
From: Adrian Hunter @ 2014-07-14 10:03 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Peter Zijlstra, linux-kernel, David Ahern, Frederic Weisbecker,
	Jiri Olsa, Namhyung Kim, Paul Mackerras, Stephane Eranian

Move the rdtsc() function so it can
be reusued.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
 tools/perf/arch/x86/util/tsc.c      | 9 +++++++++
 tools/perf/tests/perf-time-to-tsc.c | 9 ---------
 tools/perf/util/tsc.c               | 5 +++++
 tools/perf/util/tsc.h               | 1 +
 4 files changed, 15 insertions(+), 9 deletions(-)

diff --git a/tools/perf/arch/x86/util/tsc.c b/tools/perf/arch/x86/util/tsc.c
index 3655f24..fd28684 100644
--- a/tools/perf/arch/x86/util/tsc.c
+++ b/tools/perf/arch/x86/util/tsc.c
@@ -37,3 +37,12 @@ int perf_read_tsc_conversion(const struct perf_event_mmap_page *pc,
 
 	return 0;
 }
+
+u64 rdtsc(void)
+{
+	unsigned int low, high;
+
+	asm volatile("rdtsc" : "=a" (low), "=d" (high));
+
+	return low | ((u64)high) << 32;
+}
diff --git a/tools/perf/tests/perf-time-to-tsc.c b/tools/perf/tests/perf-time-to-tsc.c
index 0372f6e..f238442 100644
--- a/tools/perf/tests/perf-time-to-tsc.c
+++ b/tools/perf/tests/perf-time-to-tsc.c
@@ -25,15 +25,6 @@
 	}					\
 }
 
-static u64 rdtsc(void)
-{
-	unsigned int low, high;
-
-	asm volatile("rdtsc" : "=a" (low), "=d" (high));
-
-	return low | ((u64)high) << 32;
-}
-
 /**
  * test__perf_time_to_tsc - test converting perf time to TSC.
  *
diff --git a/tools/perf/util/tsc.c b/tools/perf/util/tsc.c
index ef4749836..4d4210d 100644
--- a/tools/perf/util/tsc.c
+++ b/tools/perf/util/tsc.c
@@ -23,3 +23,8 @@ u64 tsc_to_perf_time(u64 cyc, struct perf_tsc_conversion *tc)
 	return tc->time_zero + quot * tc->time_mult +
 	       ((rem * tc->time_mult) >> tc->time_shift);
 }
+
+u64 __weak rdtsc(void)
+{
+	return 0;
+}
diff --git a/tools/perf/util/tsc.h b/tools/perf/util/tsc.h
index 4eca848..a8b78f1 100644
--- a/tools/perf/util/tsc.h
+++ b/tools/perf/util/tsc.h
@@ -7,5 +7,6 @@
 
 u64 perf_time_to_tsc(u64 ns, struct perf_tsc_conversion *tc);
 u64 tsc_to_perf_time(u64 cyc, struct perf_tsc_conversion *tc);
+u64 rdtsc(void);
 
 #endif
-- 
1.8.3.2


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

* [PATCH 41/41] perf evlist: Add perf_evlist__enable_event_idx()
  2014-07-14 10:02 [PATCH 00/41] perf tools: Preparation for call graph from Intel BTS Adrian Hunter
                   ` (39 preceding siblings ...)
  2014-07-14 10:03 ` [PATCH 40/41] perf tools: Move rdtsc() function Adrian Hunter
@ 2014-07-14 10:03 ` Adrian Hunter
  40 siblings, 0 replies; 122+ messages in thread
From: Adrian Hunter @ 2014-07-14 10:03 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Peter Zijlstra, linux-kernel, David Ahern, Frederic Weisbecker,
	Jiri Olsa, Namhyung Kim, Paul Mackerras, Stephane Eranian

Add a function to enable a specific event
within a specific perf event buffer.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
 tools/perf/util/evlist.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++
 tools/perf/util/evlist.h |  2 ++
 2 files changed, 49 insertions(+)

diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index 10514f3..8eb6e72 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -354,6 +354,53 @@ int perf_evlist__enable_event(struct perf_evlist *evlist,
 	return 0;
 }
 
+static int perf_evlist__enable_event_cpu(struct perf_evlist *evlist,
+					 struct perf_evsel *evsel, int cpu)
+{
+	int thread, err;
+	int nr_threads = perf_evlist__nr_threads(evlist, evsel);
+
+	if (!evsel->fd)
+		return -EINVAL;
+
+	for (thread = 0; thread < nr_threads; thread++) {
+		err = ioctl(FD(evsel, cpu, thread),
+			    PERF_EVENT_IOC_ENABLE, 0);
+		if (err)
+			return err;
+	}
+	return 0;
+}
+
+static int perf_evlist__enable_event_thread(struct perf_evlist *evlist,
+					    struct perf_evsel *evsel,
+					    int thread)
+{
+	int cpu, err;
+	int nr_cpus = cpu_map__nr(evlist->cpus);
+
+	if (!evsel->fd)
+		return -EINVAL;
+
+	for (cpu = 0; cpu < nr_cpus; cpu++) {
+		err = ioctl(FD(evsel, cpu, thread), PERF_EVENT_IOC_ENABLE, 0);
+		if (err)
+			return err;
+	}
+	return 0;
+}
+
+int perf_evlist__enable_event_idx(struct perf_evlist *evlist,
+				  struct perf_evsel *evsel, int idx)
+{
+	bool per_cpu_mmaps = !cpu_map__empty(evlist->cpus);
+
+	if (per_cpu_mmaps)
+		return perf_evlist__enable_event_cpu(evlist, evsel, idx);
+	else
+		return perf_evlist__enable_event_thread(evlist, evsel, idx);
+}
+
 static int perf_evlist__alloc_pollfd(struct perf_evlist *evlist)
 {
 	int nr_cpus = cpu_map__nr(evlist->cpus);
diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h
index 657a36c..70f2676 100644
--- a/tools/perf/util/evlist.h
+++ b/tools/perf/util/evlist.h
@@ -122,6 +122,8 @@ int perf_evlist__disable_event(struct perf_evlist *evlist,
 			       struct perf_evsel *evsel);
 int perf_evlist__enable_event(struct perf_evlist *evlist,
 			      struct perf_evsel *evsel);
+int perf_evlist__enable_event_idx(struct perf_evlist *evlist,
+				  struct perf_evsel *evsel, int idx);
 
 void perf_evlist__set_selected(struct perf_evlist *evlist,
 			       struct perf_evsel *evsel);
-- 
1.8.3.2


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

* Re: [PATCH 02/41] perf tools: Fix map groups of threads with unknown pids
  2014-07-14 10:02 ` [PATCH 02/41] perf tools: Fix map groups of threads with " Adrian Hunter
@ 2014-07-14 20:18   ` Arnaldo Carvalho de Melo
  2014-07-15 11:33     ` Adrian Hunter
  0 siblings, 1 reply; 122+ messages in thread
From: Arnaldo Carvalho de Melo @ 2014-07-14 20:18 UTC (permalink / raw)
  To: Adrian Hunter
  Cc: Peter Zijlstra, linux-kernel, David Ahern, Frederic Weisbecker,
	Jiri Olsa, Namhyung Kim, Paul Mackerras, Stephane Eranian

Em Mon, Jul 14, 2014 at 01:02:26PM +0300, Adrian Hunter escreveu:
> Events like sched_switch do not provide a pid (tgid)
> which can result in threads with an unknown pid.  If
> the pid is later discovered, join the map groups.
> Note the thread's map groups should be empty because
> they are populated by MMAP events which do provide the
> pid and tid.
> 
> Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
> ---
>  tools/perf/util/machine.c | 22 ++++++++++++++++------
>  tools/perf/util/map.c     | 14 ++++++++++++++
>  tools/perf/util/map.h     |  1 +
>  tools/perf/util/thread.c  | 35 +++++++++++++++++++++++++++++++++++
>  tools/perf/util/thread.h  |  1 +
>  5 files changed, 67 insertions(+), 6 deletions(-)
> 
> diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
> index 5b80877..0fa93c1 100644
> --- a/tools/perf/util/machine.c
> +++ b/tools/perf/util/machine.c
> @@ -272,6 +272,17 @@ void machines__set_id_hdr_size(struct machines *machines, u16 id_hdr_size)
>  	return;
>  }
>  
> +static void machine__update_thread_pid(struct machine *machine,
> +				       struct thread *th, pid_t pid)
> +{
> +	if (pid != th->pid_ && pid != -1 && th->pid_ == -1) {
> +		th->pid_ = pid;
> +		if (thread__join_map_groups(th, machine))
> +			pr_err("Failed to join map groups for %d:%d\n",
> +			       th->pid_, th->tid);
> +	}
> +}
> +

I think you should combine the above function with
thread__join_map_groups, and I think that the method belongs to the
'machine' class, see below for further comments on this...

>  static struct thread *__machine__findnew_thread(struct machine *machine,
>  						pid_t pid, pid_t tid,
>  						bool create)
> @@ -285,10 +296,10 @@ static struct thread *__machine__findnew_thread(struct machine *machine,
>  	 * so most of the time we dont have to look up
>  	 * the full rbtree:
>  	 */
> -	if (machine->last_match && machine->last_match->tid == tid) {
> -		if (pid != -1 && pid != machine->last_match->pid_)
> -			machine->last_match->pid_ = pid;
> -		return machine->last_match;
> +	th = machine->last_match;
> +	if (th && th->tid == tid) {
> +		machine__update_thread_pid(machine, th, pid);
> +		return th;
>  	}
>  
>  	while (*p != NULL) {
> @@ -297,8 +308,7 @@ static struct thread *__machine__findnew_thread(struct machine *machine,
>  
>  		if (th->tid == tid) {
>  			machine->last_match = th;
> -			if (pid != -1 && pid != th->pid_)
> -				th->pid_ = pid;
> +			machine__update_thread_pid(machine, th, pid);
>  			return th;
>  		}
>  
> diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c
> index 25c571f..7af1480 100644
> --- a/tools/perf/util/map.c
> +++ b/tools/perf/util/map.c
> @@ -454,6 +454,20 @@ void map_groups__exit(struct map_groups *mg)
>  	}
>  }
>  
> +bool map_groups__empty(struct map_groups *mg)
> +{
> +	int i;
> +
> +	for (i = 0; i < MAP__NR_TYPES; ++i) {
> +		if (maps__first(&mg->maps[i]))
> +			return false;
> +		if (!list_empty(&mg->removed_maps[i]))
> +			return false;
> +	}
> +
> +	return true;
> +}
> +
>  struct map_groups *map_groups__new(void)
>  {
>  	struct map_groups *mg = malloc(sizeof(*mg));
> diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h
> index 7758c72..5806a90 100644
> --- a/tools/perf/util/map.h
> +++ b/tools/perf/util/map.h
> @@ -66,6 +66,7 @@ struct map_groups {
>  
>  struct map_groups *map_groups__new(void);
>  void map_groups__delete(struct map_groups *mg);
> +bool map_groups__empty(struct map_groups *mg);
>  
>  static inline struct map_groups *map_groups__get(struct map_groups *mg)
>  {
> diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c
> index 7a32f44..ca94295 100644
> --- a/tools/perf/util/thread.c
> +++ b/tools/perf/util/thread.c
> @@ -24,6 +24,41 @@ int thread__init_map_groups(struct thread *thread, struct machine *machine)
>  	return thread->mg ? 0 : -1;
>  }
>  
> +int thread__join_map_groups(struct thread *thread, struct machine *machine)
> +{
> +	struct thread *leader;
> +	pid_t pid = thread->pid_;
> +
> +	if (pid == thread->tid)
> +		return 0;
> +
> +	leader = machine__findnew_thread(machine, pid, pid);
> +	if (!leader)
> +		return -ENOMEM;
> +
> +	if (!leader->mg)
> +		leader->mg = map_groups__new();
> +
> +	if (!leader->mg)
> +		return -ENOMEM;
> +
> +	if (thread->mg) {
> +		/*
> +		 * Maps are created from MMAP events which provide the pid and
> +		 * tid.  Consequently there never should be any maps on a thread
> +		 * with an unknown pid.  Just print an error if there are.
> +		 */
> +		if (!map_groups__empty(thread->mg))
> +			pr_err("Discarding thread maps for %d:%d\n",
> +			       thread->pid_, thread->tid);

Because there is nothing in this function (thread__join_map_groups),
checking if it is operating on a thread that has an unknown pid.

So, please consider merging this and its sole caller,
machine__update_thread_pid, so that the test is in the same function as
the assumption that it is operating on a thread with an unknown pid.

Continuing to look at the other patches...

> +		map_groups__delete(thread->mg);
> +	}
> +
> +	thread->mg = map_groups__get(leader->mg);
> +
> +	return 0;
> +}
> +
>  struct thread *thread__new(pid_t pid, pid_t tid)
>  {
>  	char *comm_str;
> diff --git a/tools/perf/util/thread.h b/tools/perf/util/thread.h
> index 3c0c272..9de0629 100644
> --- a/tools/perf/util/thread.h
> +++ b/tools/perf/util/thread.h
> @@ -31,6 +31,7 @@ struct comm;
>  
>  struct thread *thread__new(pid_t pid, pid_t tid);
>  int thread__init_map_groups(struct thread *thread, struct machine *machine);
> +int thread__join_map_groups(struct thread *thread, struct machine *machine);
>  void thread__delete(struct thread *thread);
>  static inline void thread__exited(struct thread *thread)
>  {
> -- 
> 1.8.3.2

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

* Re: [PATCH 05/41] perf tools: Identify which comms are from exec
  2014-07-14 10:02 ` [PATCH 05/41] perf tools: Identify which comms are from exec Adrian Hunter
@ 2014-07-14 20:32   ` Arnaldo Carvalho de Melo
  2014-07-15 11:43     ` Adrian Hunter
  0 siblings, 1 reply; 122+ messages in thread
From: Arnaldo Carvalho de Melo @ 2014-07-14 20:32 UTC (permalink / raw)
  To: Adrian Hunter
  Cc: Peter Zijlstra, linux-kernel, David Ahern, Frederic Weisbecker,
	Jiri Olsa, Namhyung Kim, Paul Mackerras, Stephane Eranian

Em Mon, Jul 14, 2014 at 01:02:29PM +0300, Adrian Hunter escreveu:
> Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
> ---
>  tools/perf/util/comm.c    |  7 +++++--
>  tools/perf/util/comm.h    |  6 ++++--
>  tools/perf/util/machine.c |  4 +++-
>  tools/perf/util/thread.c  | 24 +++++++++++++++++++-----
>  tools/perf/util/thread.h  | 10 +++++++++-
>  5 files changed, 40 insertions(+), 11 deletions(-)
> 
> diff --git a/tools/perf/util/comm.c b/tools/perf/util/comm.c
> index f9e7776..5e1e80e 100644
> --- a/tools/perf/util/comm.c
> +++ b/tools/perf/util/comm.c
> @@ -74,7 +74,7 @@ static struct comm_str *comm_str__findnew(const char *str, struct rb_root *root)
>  	return new;
>  }
>  
> -struct comm *comm__new(const char *str, u64 timestamp)
> +struct comm *comm__new(const char *str, u64 timestamp, bool exec)
>  {
>  	struct comm *comm = zalloc(sizeof(*comm));
>  
> @@ -82,6 +82,7 @@ struct comm *comm__new(const char *str, u64 timestamp)
>  		return NULL;
>  
>  	comm->start = timestamp;
> +	comm->exec = exec;
>  
>  	comm->comm_str = comm_str__findnew(str, &comm_str_root);
>  	if (!comm->comm_str) {
> @@ -94,7 +95,7 @@ struct comm *comm__new(const char *str, u64 timestamp)
>  	return comm;
>  }
>  
> -int comm__override(struct comm *comm, const char *str, u64 timestamp)
> +int comm__override(struct comm *comm, const char *str, u64 timestamp, bool exec)
>  {
>  	struct comm_str *new, *old = comm->comm_str;
>  
> @@ -106,6 +107,8 @@ int comm__override(struct comm *comm, const char *str, u64 timestamp)
>  	comm_str__put(old);
>  	comm->comm_str = new;
>  	comm->start = timestamp;
> +	if (exec && !comm->exec)
> +		comm->exec = true;

Why do you need the !comm->exec test?

>  	return 0;
>  }
> diff --git a/tools/perf/util/comm.h b/tools/perf/util/comm.h
> index fac5bd5..51c10ab 100644
> --- a/tools/perf/util/comm.h
> +++ b/tools/perf/util/comm.h
> @@ -11,11 +11,13 @@ struct comm {
>  	struct comm_str *comm_str;
>  	u64 start;
>  	struct list_head list;
> +	bool exec;
>  };
>  
>  void comm__free(struct comm *comm);
> -struct comm *comm__new(const char *str, u64 timestamp);
> +struct comm *comm__new(const char *str, u64 timestamp, bool exec);
>  const char *comm__str(const struct comm *comm);
> -int comm__override(struct comm *comm, const char *str, u64 timestamp);
> +int comm__override(struct comm *comm, const char *str, u64 timestamp,
> +		   bool exec);
>  
>  #endif  /* __PERF_COMM_H */
> diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
> index 0fa93c1..2513204 100644
> --- a/tools/perf/util/machine.c
> +++ b/tools/perf/util/machine.c
> @@ -360,11 +360,13 @@ int machine__process_comm_event(struct machine *machine, union perf_event *event
>  	struct thread *thread = machine__findnew_thread(machine,
>  							event->comm.pid,
>  							event->comm.tid);
> +	bool exec = event->header.misc & PERF_RECORD_MISC_COMM_EXEC;
>  
>  	if (dump_trace)
>  		perf_event__fprintf_comm(event, stdout);
>  
> -	if (thread == NULL || thread__set_comm(thread, event->comm.comm, sample->time)) {
> +	if (thread == NULL ||
> +	    __thread__set_comm(thread, event->comm.comm, sample->time, exec)) {
>  		dump_printf("problem processing PERF_RECORD_COMM, skipping event.\n");
>  		return -1;
>  	}
> diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c
> index ca94295..149e417 100644
> --- a/tools/perf/util/thread.c
> +++ b/tools/perf/util/thread.c
> @@ -76,7 +76,7 @@ struct thread *thread__new(pid_t pid, pid_t tid)
>  			goto err_thread;
>  
>  		snprintf(comm_str, 32, ":%d", tid);
> -		comm = comm__new(comm_str, 0);
> +		comm = comm__new(comm_str, 0, false);
>  		free(comm_str);
>  		if (!comm)
>  			goto err_thread;
> @@ -113,19 +113,33 @@ struct comm *thread__comm(const struct thread *thread)
>  	return list_first_entry(&thread->comm_list, struct comm, list);
>  }
>  
> +struct comm *thread__exec_comm(const struct thread *thread)
> +{
> +	struct comm *comm, *last = NULL;
> +
> +	list_for_each_entry(comm, &thread->comm_list, list) {
> +		if (comm->exec)
> +			return comm;
> +		last = comm;
> +	}
> +
> +	return last;
> +}
> +
>  /* CHECKME: time should always be 0 if event aren't ordered */
> -int thread__set_comm(struct thread *thread, const char *str, u64 timestamp)
> +int __thread__set_comm(struct thread *thread, const char *str, u64 timestamp,
> +		       bool exec)
>  {
>  	struct comm *new, *curr = thread__comm(thread);
>  	int err;
>  
>  	/* Override latest entry if it had no specific time coverage */
> -	if (!curr->start) {
> -		err = comm__override(curr, str, timestamp);
> +	if (!curr->start && !curr->exec) {
> +		err = comm__override(curr, str, timestamp, exec);
>  		if (err)
>  			return err;
>  	} else {
> -		new = comm__new(str, timestamp);
> +		new = comm__new(str, timestamp, exec);
>  		if (!new)
>  			return -ENOMEM;
>  		list_add(&new->list, &thread->comm_list);
> diff --git a/tools/perf/util/thread.h b/tools/perf/util/thread.h
> index 9de0629..b4269af 100644
> --- a/tools/perf/util/thread.h
> +++ b/tools/perf/util/thread.h
> @@ -38,9 +38,17 @@ static inline void thread__exited(struct thread *thread)
>  	thread->dead = true;
>  }
>  
> -int thread__set_comm(struct thread *thread, const char *comm, u64 timestamp);
> +int __thread__set_comm(struct thread *thread, const char *comm, u64 timestamp,
> +		       bool exec);
> +static inline int thread__set_comm(struct thread *thread, const char *comm,
> +				   u64 timestamp)
> +{
> +	return __thread__set_comm(thread, comm, timestamp, false);
> +}
> +

So this is nice, you leave the existing function, setting exec to false,
so that you don't have to change the existing codepaths where it is not
from 'exec', and provide a __ prefixed variant where 'exec' can be set.

Why not to do the same thing for comm__new() ? No uses, i.e. in all
cases you will need to pass 'exec' as a variable?

I thought about doing the same thing for that machine__findnew_thread,
i.e. provide a variant where tid and pid is passed and one where just
the tid is passed, because the pid is unknown.

BTW, I'll update my perf/core branch with the set of patches that I
merged, so that you can have where to look for a consolidated tree with
the things already processed.

- Arnaldo

>  int thread__comm_len(struct thread *thread);
>  struct comm *thread__comm(const struct thread *thread);
> +struct comm *thread__exec_comm(const struct thread *thread);
>  const char *thread__comm_str(const struct thread *thread);
>  void thread__insert_map(struct thread *thread, struct map *map);
>  int thread__fork(struct thread *thread, struct thread *parent, u64 timestamp);
> -- 
> 1.8.3.2

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

* Re: [PATCH 08/41] perf tools: Fix missing label symbols
  2014-07-14 10:02 ` [PATCH 08/41] perf tools: Fix missing label symbols Adrian Hunter
@ 2014-07-14 20:38   ` Arnaldo Carvalho de Melo
  2014-07-15 12:11     ` Adrian Hunter
  0 siblings, 1 reply; 122+ messages in thread
From: Arnaldo Carvalho de Melo @ 2014-07-14 20:38 UTC (permalink / raw)
  To: Adrian Hunter
  Cc: Peter Zijlstra, linux-kernel, David Ahern, Frederic Weisbecker,
	Jiri Olsa, Namhyung Kim, Paul Mackerras, Stephane Eranian

Em Mon, Jul 14, 2014 at 01:02:32PM +0300, Adrian Hunter escreveu:
> label symbols are missing because elf_sec__is_a() fails
> to find the section because the section strings do not
> match the section headers because the sections headers
> are from the 'runtime' object and the sections strings
> are from the 'symbol source' object.
> 
> Fix by getting the section strings from the 'runtime'
> object so that they match the section headers.

Would be great to have a 'perf test' entry that fail when looking for
those 'label symbols', i.e. looking for one such symbol in vmlinux that
we know is always there, in some written in stone area of the kernel,
where this label vanishing is unlikely to happen.

Can you elaborate on the case that fails? So that I can test it here,
and then after the fix, check that it indeed fixes the problem? I may
well write that test myself and insert it in my branch just before this
one.

- Arnaldo
 
> Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
> ---
>  tools/perf/util/symbol-elf.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c
> index 6864661..8c96817 100644
> --- a/tools/perf/util/symbol-elf.c
> +++ b/tools/perf/util/symbol-elf.c
> @@ -732,7 +732,7 @@ int dso__load_sym(struct dso *dso, struct map *map,
>  	if (symstrs == NULL)
>  		goto out_elf_end;
>  
> -	sec_strndx = elf_getscn(elf, ehdr.e_shstrndx);
> +	sec_strndx = elf_getscn(runtime_ss->elf, runtime_ss->ehdr.e_shstrndx);
>  	if (sec_strndx == NULL)
>  		goto out_elf_end;
>  
> -- 
> 1.8.3.2

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

* Re: [PATCH 12/41] perf tools: Fix leak of 'struct thread' on error path
  2014-07-14 10:02 ` [PATCH 12/41] perf tools: Fix leak of 'struct thread' on error path Adrian Hunter
@ 2014-07-14 20:43   ` Arnaldo Carvalho de Melo
  2014-07-16  7:19     ` [PATCH V2 0/2] perf tools: Allow deletion of a thread with no map groups Adrian Hunter
  2014-07-16 14:02   ` [PATCH 12/41] perf tools: " Jiri Olsa
  1 sibling, 1 reply; 122+ messages in thread
From: Arnaldo Carvalho de Melo @ 2014-07-14 20:43 UTC (permalink / raw)
  To: Adrian Hunter
  Cc: Peter Zijlstra, linux-kernel, David Ahern, Frederic Weisbecker,
	Jiri Olsa, Namhyung Kim, Paul Mackerras, Stephane Eranian

Em Mon, Jul 14, 2014 at 01:02:36PM +0300, Adrian Hunter escreveu:
> __machine__findnew_thread() creates a 'struct thread'
> but does not free it on the error path.

Ok, but that second one is a separate bug, i.e. its not fixing the
described leak, please break this into two patches with separate commit
messages.

- Arnaldo
 
> Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
> ---
>  tools/perf/util/machine.c | 4 +++-
>  tools/perf/util/thread.c  | 6 ++++--
>  2 files changed, 7 insertions(+), 3 deletions(-)
> 
> diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
> index c1c5ca3..18eaf31 100644
> --- a/tools/perf/util/machine.c
> +++ b/tools/perf/util/machine.c
> @@ -349,8 +349,10 @@ static struct thread *__machine__findnew_thread(struct machine *machine,
>  		 * within thread__init_map_groups to find the thread
>  		 * leader and that would screwed the rb tree.
>  		 */
> -		if (thread__init_map_groups(th, machine))
> +		if (thread__init_map_groups(th, machine)) {
> +			thread__delete(th);
>  			return NULL;
> +		}
>  	}
>  
>  	return th;
> diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c
> index 149e417..b9a3ee4 100644
> --- a/tools/perf/util/thread.c
> +++ b/tools/perf/util/thread.c
> @@ -95,8 +95,10 @@ void thread__delete(struct thread *thread)
>  {
>  	struct comm *comm, *tmp;
>  
> -	map_groups__put(thread->mg);
> -	thread->mg = NULL;
> +	if (thread->mg) {
> +		map_groups__put(thread->mg);
> +		thread->mg = NULL;
> +	}
>  	list_for_each_entry_safe(comm, tmp, &thread->comm_list, list) {
>  		list_del(&comm->list);
>  		comm__free(comm);
> -- 
> 1.8.3.2

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

* Re: [PATCH 02/41] perf tools: Fix map groups of threads with unknown pids
  2014-07-14 20:18   ` Arnaldo Carvalho de Melo
@ 2014-07-15 11:33     ` Adrian Hunter
  2014-07-15 19:33       ` Arnaldo Carvalho de Melo
  0 siblings, 1 reply; 122+ messages in thread
From: Adrian Hunter @ 2014-07-15 11:33 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Peter Zijlstra, linux-kernel, David Ahern, Frederic Weisbecker,
	Jiri Olsa, Namhyung Kim, Paul Mackerras, Stephane Eranian

On 07/14/2014 11:18 PM, Arnaldo Carvalho de Melo wrote:
> Em Mon, Jul 14, 2014 at 01:02:26PM +0300, Adrian Hunter escreveu:
>> Events like sched_switch do not provide a pid (tgid)
>> which can result in threads with an unknown pid.  If
>> the pid is later discovered, join the map groups.
>> Note the thread's map groups should be empty because
>> they are populated by MMAP events which do provide the
>> pid and tid.
>>
>> Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
>> ---
>>  tools/perf/util/machine.c | 22 ++++++++++++++++------
>>  tools/perf/util/map.c     | 14 ++++++++++++++
>>  tools/perf/util/map.h     |  1 +
>>  tools/perf/util/thread.c  | 35 +++++++++++++++++++++++++++++++++++
>>  tools/perf/util/thread.h  |  1 +
>>  5 files changed, 67 insertions(+), 6 deletions(-)
>>
>> diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
>> index 5b80877..0fa93c1 100644
>> --- a/tools/perf/util/machine.c
>> +++ b/tools/perf/util/machine.c
>> @@ -272,6 +272,17 @@ void machines__set_id_hdr_size(struct machines *machines, u16 id_hdr_size)
>>  	return;
>>  }
>>  
>> +static void machine__update_thread_pid(struct machine *machine,
>> +				       struct thread *th, pid_t pid)
>> +{
>> +	if (pid != th->pid_ && pid != -1 && th->pid_ == -1) {
>> +		th->pid_ = pid;
>> +		if (thread__join_map_groups(th, machine))
>> +			pr_err("Failed to join map groups for %d:%d\n",
>> +			       th->pid_, th->tid);
>> +	}
>> +}
>> +
> 
> I think you should combine the above function with
> thread__join_map_groups, and I think that the method belongs to the
> 'machine' class, see below for further comments on this...
> 
>> diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c
>> index 7a32f44..ca94295 100644
>> --- a/tools/perf/util/thread.c
>> +++ b/tools/perf/util/thread.c
>> @@ -24,6 +24,41 @@ int thread__init_map_groups(struct thread *thread, struct machine *machine)
>>  	return thread->mg ? 0 : -1;
>>  }
>>  
>> +int thread__join_map_groups(struct thread *thread, struct machine *machine)
>> +{
>> +	struct thread *leader;
>> +	pid_t pid = thread->pid_;
>> +
>> +	if (pid == thread->tid)
>> +		return 0;
>> +
>> +	leader = machine__findnew_thread(machine, pid, pid);
>> +	if (!leader)
>> +		return -ENOMEM;
>> +
>> +	if (!leader->mg)
>> +		leader->mg = map_groups__new();
>> +
>> +	if (!leader->mg)
>> +		return -ENOMEM;
>> +
>> +	if (thread->mg) {
>> +		/*
>> +		 * Maps are created from MMAP events which provide the pid and
>> +		 * tid.  Consequently there never should be any maps on a thread
>> +		 * with an unknown pid.  Just print an error if there are.
>> +		 */
>> +		if (!map_groups__empty(thread->mg))
>> +			pr_err("Discarding thread maps for %d:%d\n",
>> +			       thread->pid_, thread->tid);
> 
> Because there is nothing in this function (thread__join_map_groups),
> checking if it is operating on a thread that has an unknown pid.
> 
> So, please consider merging this and its sole caller,
> machine__update_thread_pid, so that the test is in the same function as
> the assumption that it is operating on a thread with an unknown pid.

You have it in your tree now.  Do you want another patch
to do that?


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

* Re: [PATCH 05/41] perf tools: Identify which comms are from exec
  2014-07-14 20:32   ` Arnaldo Carvalho de Melo
@ 2014-07-15 11:43     ` Adrian Hunter
  2014-07-23 14:07       ` Arnaldo Carvalho de Melo
  0 siblings, 1 reply; 122+ messages in thread
From: Adrian Hunter @ 2014-07-15 11:43 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Peter Zijlstra, linux-kernel, David Ahern, Frederic Weisbecker,
	Jiri Olsa, Namhyung Kim, Paul Mackerras, Stephane Eranian

On 07/14/2014 11:32 PM, Arnaldo Carvalho de Melo wrote:
> Em Mon, Jul 14, 2014 at 01:02:29PM +0300, Adrian Hunter escreveu:
>> Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
>> ---
>>  tools/perf/util/comm.c    |  7 +++++--
>>  tools/perf/util/comm.h    |  6 ++++--
>>  tools/perf/util/machine.c |  4 +++-
>>  tools/perf/util/thread.c  | 24 +++++++++++++++++++-----
>>  tools/perf/util/thread.h  | 10 +++++++++-
>>  5 files changed, 40 insertions(+), 11 deletions(-)
>>
>> diff --git a/tools/perf/util/comm.c b/tools/perf/util/comm.c
>> index f9e7776..5e1e80e 100644
>> --- a/tools/perf/util/comm.c
>> +++ b/tools/perf/util/comm.c
>> @@ -74,7 +74,7 @@ static struct comm_str *comm_str__findnew(const char *str, struct rb_root *root)
>>  	return new;
>>  }
>>  
>> -struct comm *comm__new(const char *str, u64 timestamp)
>> +struct comm *comm__new(const char *str, u64 timestamp, bool exec)
>>  {
>>  	struct comm *comm = zalloc(sizeof(*comm));
>>  
>> @@ -82,6 +82,7 @@ struct comm *comm__new(const char *str, u64 timestamp)
>>  		return NULL;
>>  
>>  	comm->start = timestamp;
>> +	comm->exec = exec;
>>  
>>  	comm->comm_str = comm_str__findnew(str, &comm_str_root);
>>  	if (!comm->comm_str) {
>> @@ -94,7 +95,7 @@ struct comm *comm__new(const char *str, u64 timestamp)
>>  	return comm;
>>  }
>>  
>> -int comm__override(struct comm *comm, const char *str, u64 timestamp)
>> +int comm__override(struct comm *comm, const char *str, u64 timestamp, bool exec)
>>  {
>>  	struct comm_str *new, *old = comm->comm_str;
>>  
>> @@ -106,6 +107,8 @@ int comm__override(struct comm *comm, const char *str, u64 timestamp)
>>  	comm_str__put(old);
>>  	comm->comm_str = new;
>>  	comm->start = timestamp;
>> +	if (exec && !comm->exec)
>> +		comm->exec = true;
> 
> Why do you need the !comm->exec test?

Dunno

> 
>>  	return 0;
>>  }
>> diff --git a/tools/perf/util/comm.h b/tools/perf/util/comm.h
>> index fac5bd5..51c10ab 100644
>> --- a/tools/perf/util/comm.h
>> +++ b/tools/perf/util/comm.h
>> @@ -11,11 +11,13 @@ struct comm {
>>  	struct comm_str *comm_str;
>>  	u64 start;
>>  	struct list_head list;
>> +	bool exec;
>>  };
>>  
>>  void comm__free(struct comm *comm);
>> -struct comm *comm__new(const char *str, u64 timestamp);
>> +struct comm *comm__new(const char *str, u64 timestamp, bool exec);
>>  const char *comm__str(const struct comm *comm);
>> -int comm__override(struct comm *comm, const char *str, u64 timestamp);
>> +int comm__override(struct comm *comm, const char *str, u64 timestamp,
>> +		   bool exec);
>>  
>>  #endif  /* __PERF_COMM_H */
>> diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
>> index 0fa93c1..2513204 100644
>> --- a/tools/perf/util/machine.c
>> +++ b/tools/perf/util/machine.c
>> @@ -360,11 +360,13 @@ int machine__process_comm_event(struct machine *machine, union perf_event *event
>>  	struct thread *thread = machine__findnew_thread(machine,
>>  							event->comm.pid,
>>  							event->comm.tid);
>> +	bool exec = event->header.misc & PERF_RECORD_MISC_COMM_EXEC;
>>  
>>  	if (dump_trace)
>>  		perf_event__fprintf_comm(event, stdout);
>>  
>> -	if (thread == NULL || thread__set_comm(thread, event->comm.comm, sample->time)) {
>> +	if (thread == NULL ||
>> +	    __thread__set_comm(thread, event->comm.comm, sample->time, exec)) {
>>  		dump_printf("problem processing PERF_RECORD_COMM, skipping event.\n");
>>  		return -1;
>>  	}
>> diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c
>> index ca94295..149e417 100644
>> --- a/tools/perf/util/thread.c
>> +++ b/tools/perf/util/thread.c
>> @@ -76,7 +76,7 @@ struct thread *thread__new(pid_t pid, pid_t tid)
>>  			goto err_thread;
>>  
>>  		snprintf(comm_str, 32, ":%d", tid);
>> -		comm = comm__new(comm_str, 0);
>> +		comm = comm__new(comm_str, 0, false);
>>  		free(comm_str);
>>  		if (!comm)
>>  			goto err_thread;
>> @@ -113,19 +113,33 @@ struct comm *thread__comm(const struct thread *thread)
>>  	return list_first_entry(&thread->comm_list, struct comm, list);
>>  }
>>  
>> +struct comm *thread__exec_comm(const struct thread *thread)
>> +{
>> +	struct comm *comm, *last = NULL;
>> +
>> +	list_for_each_entry(comm, &thread->comm_list, list) {
>> +		if (comm->exec)
>> +			return comm;
>> +		last = comm;
>> +	}
>> +
>> +	return last;
>> +}
>> +
>>  /* CHECKME: time should always be 0 if event aren't ordered */
>> -int thread__set_comm(struct thread *thread, const char *str, u64 timestamp)
>> +int __thread__set_comm(struct thread *thread, const char *str, u64 timestamp,
>> +		       bool exec)
>>  {
>>  	struct comm *new, *curr = thread__comm(thread);
>>  	int err;
>>  
>>  	/* Override latest entry if it had no specific time coverage */
>> -	if (!curr->start) {
>> -		err = comm__override(curr, str, timestamp);
>> +	if (!curr->start && !curr->exec) {
>> +		err = comm__override(curr, str, timestamp, exec);
>>  		if (err)
>>  			return err;
>>  	} else {
>> -		new = comm__new(str, timestamp);
>> +		new = comm__new(str, timestamp, exec);
>>  		if (!new)
>>  			return -ENOMEM;
>>  		list_add(&new->list, &thread->comm_list);
>> diff --git a/tools/perf/util/thread.h b/tools/perf/util/thread.h
>> index 9de0629..b4269af 100644
>> --- a/tools/perf/util/thread.h
>> +++ b/tools/perf/util/thread.h
>> @@ -38,9 +38,17 @@ static inline void thread__exited(struct thread *thread)
>>  	thread->dead = true;
>>  }
>>  
>> -int thread__set_comm(struct thread *thread, const char *comm, u64 timestamp);
>> +int __thread__set_comm(struct thread *thread, const char *comm, u64 timestamp,
>> +		       bool exec);
>> +static inline int thread__set_comm(struct thread *thread, const char *comm,
>> +				   u64 timestamp)
>> +{
>> +	return __thread__set_comm(thread, comm, timestamp, false);
>> +}
>> +
> 
> So this is nice, you leave the existing function, setting exec to false,
> so that you don't have to change the existing codepaths where it is not
> from 'exec', and provide a __ prefixed variant where 'exec' can be set.
> 
> Why not to do the same thing for comm__new() ? No uses, i.e. in all
> cases you will need to pass 'exec' as a variable?

There are only 2 comm__new() callers, and they are in files I am changing
anyway.

> 
> I thought about doing the same thing for that machine__findnew_thread,
> i.e. provide a variant where tid and pid is passed and one where just
> the tid is passed, because the pid is unknown.

But you don't want people using the "unknown" variant if they do know
the pid, so forcing them to pass something maybe better.

> 
> BTW, I'll update my perf/core branch with the set of patches that I
> merged, so that you can have where to look for a consolidated tree with
> the things already processed.

Thanks!


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

* Re: [PATCH 08/41] perf tools: Fix missing label symbols
  2014-07-14 20:38   ` Arnaldo Carvalho de Melo
@ 2014-07-15 12:11     ` Adrian Hunter
  0 siblings, 0 replies; 122+ messages in thread
From: Adrian Hunter @ 2014-07-15 12:11 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Peter Zijlstra, linux-kernel, David Ahern, Frederic Weisbecker,
	Jiri Olsa, Namhyung Kim, Paul Mackerras, Stephane Eranian

On 07/14/2014 11:38 PM, Arnaldo Carvalho de Melo wrote:
> Em Mon, Jul 14, 2014 at 01:02:32PM +0300, Adrian Hunter escreveu:
>> label symbols are missing because elf_sec__is_a() fails
>> to find the section because the section strings do not
>> match the section headers because the sections headers
>> are from the 'runtime' object and the sections strings
>> are from the 'symbol source' object.
>>
>> Fix by getting the section strings from the 'runtime'
>> object so that they match the section headers.
> 
> Would be great to have a 'perf test' entry that fail when looking for
> those 'label symbols', i.e. looking for one such symbol in vmlinux that
> we know is always there, in some written in stone area of the kernel,
> where this label vanishing is unlikely to happen.
> 
> Can you elaborate on the case that fails? So that I can test it here,
> and then after the fix, check that it indeed fixes the problem? I may
> well write that test myself and insert it in my branch just before this
> one.

It fails with "_start" which is a label in /lib/x86_64-linux-gnu/ld-2.17.so.
It is where the program starts so it is not a function, and it is the first
user space address of an exec'ed process.

If you do:

	perf record --per-thread -T -e branches:u -c1 -d -- uname

Then, assuming the old BTS driver doesn't lose the data, it should be
pretty much the first branch.

	pref script | head

> 
> - Arnaldo
>  
>> Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
>> ---
>>  tools/perf/util/symbol-elf.c | 2 +-
>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c
>> index 6864661..8c96817 100644
>> --- a/tools/perf/util/symbol-elf.c
>> +++ b/tools/perf/util/symbol-elf.c
>> @@ -732,7 +732,7 @@ int dso__load_sym(struct dso *dso, struct map *map,
>>  	if (symstrs == NULL)
>>  		goto out_elf_end;
>>  
>> -	sec_strndx = elf_getscn(elf, ehdr.e_shstrndx);
>> +	sec_strndx = elf_getscn(runtime_ss->elf, runtime_ss->ehdr.e_shstrndx);
>>  	if (sec_strndx == NULL)
>>  		goto out_elf_end;
>>  
>> -- 
>> 1.8.3.2
> 
> 


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

* Re: [PATCH 15/41] perf script: Improve srcline display for BTS
  2014-07-14 10:02 ` [PATCH 15/41] perf script: Improve srcline display for BTS Adrian Hunter
@ 2014-07-15 14:16   ` Arnaldo Carvalho de Melo
  2014-07-15 17:51     ` Adrian Hunter
  2014-07-16  2:08     ` David Ahern
  0 siblings, 2 replies; 122+ messages in thread
From: Arnaldo Carvalho de Melo @ 2014-07-15 14:16 UTC (permalink / raw)
  To: Adrian Hunter
  Cc: Peter Zijlstra, linux-kernel, David Ahern, Frederic Weisbecker,
	Jiri Olsa, Namhyung Kim, Paul Mackerras, Stephane Eranian

Em Mon, Jul 14, 2014 at 01:02:39PM +0300, Adrian Hunter escreveu:
> Change the order of the output to put the srcline last.
> e.g. old format:
> 
>           4028fc main+0x2c (/bin/ls)
>   /build/buildd/coreutils-8.20/src/ls.c:1269 =>           40d8a0 set_program_name+0x0 (/bin/ls)
> 
> new format:
> 
>           4028fc main+0x2c (/bin/ls) =>           40d8a0 set_program_name+0x0 (/bin/ls)
>   /build/buildd/coreutils-8.20/src/ls.c:1269

David,

	Can I have your acked-by?

Adrian,

	Can you elaborate on why this is an improvement?

- Arnaldo
 
> Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
> ---
>  tools/perf/builtin-script.c | 20 +++++++++++++++-----
>  1 file changed, 15 insertions(+), 5 deletions(-)
> 
> diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
> index 9e9c91f..333b15e 100644
> --- a/tools/perf/builtin-script.c
> +++ b/tools/perf/builtin-script.c
> @@ -427,15 +427,22 @@ static void print_sample_bts(union perf_event *event,
>  			     struct addr_location *al)
>  {
>  	struct perf_event_attr *attr = &evsel->attr;
> +	bool print_srcline_last = false;
>  
>  	/* print branch_from information */
>  	if (PRINT_FIELD(IP)) {
> -		if (!symbol_conf.use_callchain)
> -			printf(" ");
> -		else
> +		unsigned int print_opts = output[attr->type].print_ip_opts;
> +
> +		if (symbol_conf.use_callchain && sample->callchain) {
>  			printf("\n");
> -		perf_evsel__print_ip(evsel, sample, al,
> -				     output[attr->type].print_ip_opts,
> +		} else {
> +			printf(" ");
> +			if (print_opts & PRINT_IP_OPT_SRCLINE) {
> +				print_srcline_last = true;
> +				print_opts &= ~PRINT_IP_OPT_SRCLINE;
> +			}
> +		}
> +		perf_evsel__print_ip(evsel, sample, al, print_opts,
>  				     PERF_MAX_STACK_DEPTH);
>  	}
>  
> @@ -447,6 +454,9 @@ static void print_sample_bts(union perf_event *event,
>  	     !output[attr->type].user_set))
>  		print_sample_addr(event, sample, al->machine, thread, attr);
>  
> +	if (print_srcline_last)
> +		map__fprintf_srcline(al->map, al->addr, "\n  ", stdout);
> +
>  	printf("\n");
>  }
>  
> -- 
> 1.8.3.2

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

* Re: [PATCH 24/41] perf tools: Add cpu to struct thread
  2014-07-14 10:02 ` [PATCH 24/41] perf tools: Add cpu to struct thread Adrian Hunter
@ 2014-07-15 14:24   ` Arnaldo Carvalho de Melo
  2014-07-15 17:58     ` Adrian Hunter
  0 siblings, 1 reply; 122+ messages in thread
From: Arnaldo Carvalho de Melo @ 2014-07-15 14:24 UTC (permalink / raw)
  To: Adrian Hunter
  Cc: Peter Zijlstra, linux-kernel, David Ahern, Frederic Weisbecker,
	Jiri Olsa, Namhyung Kim, Paul Mackerras, Stephane Eranian

Em Mon, Jul 14, 2014 at 01:02:48PM +0300, Adrian Hunter escreveu:
> Tools may wish to track on which cpu a thread
> is running.  Add 'cpu' to struct thread for
> that purpose.
> 
> This will be used to determine the cpu when
> decoding a per-thread Instruction Trace.

Humm, is this the last cpu we got some event telling the cpu was running
on? Continuing looking at the patches...

- Arnaldo
 
> Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
> ---
>  tools/perf/util/thread.c | 1 +
>  tools/perf/util/thread.h | 1 +
>  2 files changed, 2 insertions(+)
> 
> diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c
> index b9a3ee4..2f8c0c1 100644
> --- a/tools/perf/util/thread.c
> +++ b/tools/perf/util/thread.c
> @@ -69,6 +69,7 @@ struct thread *thread__new(pid_t pid, pid_t tid)
>  		thread->pid_ = pid;
>  		thread->tid = tid;
>  		thread->ppid = -1;
> +		thread->cpu = -1;
>  		INIT_LIST_HEAD(&thread->comm_list);
>  
>  		comm_str = malloc(32);
> diff --git a/tools/perf/util/thread.h b/tools/perf/util/thread.h
> index b4269af..e4920ff 100644
> --- a/tools/perf/util/thread.h
> +++ b/tools/perf/util/thread.h
> @@ -17,6 +17,7 @@ struct thread {
>  	pid_t			pid_; /* Not all tools update this */
>  	pid_t			tid;
>  	pid_t			ppid;
> +	int			cpu;
>  	char			shortname[3];
>  	bool			comm_set;
>  	bool			dead; /* if set thread has exited */
> -- 
> 1.8.3.2

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

* Re: [PATCH 34/41] perf evlist: Add 'system_wide' option
  2014-07-14 10:02 ` [PATCH 34/41] perf evlist: Add 'system_wide' option Adrian Hunter
@ 2014-07-15 15:03   ` Arnaldo Carvalho de Melo
  2014-07-15 18:05     ` Adrian Hunter
  2014-08-11 13:12   ` Jiri Olsa
  1 sibling, 1 reply; 122+ messages in thread
From: Arnaldo Carvalho de Melo @ 2014-07-15 15:03 UTC (permalink / raw)
  To: Adrian Hunter
  Cc: Peter Zijlstra, linux-kernel, David Ahern, Frederic Weisbecker,
	Jiri Olsa, Namhyung Kim, Paul Mackerras, Stephane Eranian

Em Mon, Jul 14, 2014 at 01:02:58PM +0300, Adrian Hunter escreveu:
> Add an option to cause a selected event
> to be opened always without a pid when
> configured by perf_evsel__config().
> 
> This is needed when using the sched_switch
> tracepoint to follow object code execution.
> sched_switch occurs before the task
> switch and so it cannot record it in a
> context limited to that task.  Note
> that also means that sched_switch is
> useless when capturing data per-thread,
> as is the 'context-switches' software
> event for the same reason.

clever, but humm, need to be judicious when allocating things like the
pollfd, I think, more below...

... after going thru the whole patch, its not clear how pollfd usage
takes into account the fact that some of the evsels don't have
thread_map->nr entries, but just one, will continue reading...
 
> Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
> ---
>  tools/perf/util/evlist.c | 45 +++++++++++++++++++++++++++++++++++++--------
>  tools/perf/util/evsel.c  | 31 ++++++++++++++++++++++++++-----
>  tools/perf/util/evsel.h  |  1 +
>  3 files changed, 64 insertions(+), 13 deletions(-)
> 
> diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
> index 282e83e..c295b7b 100644
> --- a/tools/perf/util/evlist.c
> +++ b/tools/perf/util/evlist.c
> @@ -265,17 +265,27 @@ int perf_evlist__add_newtp(struct perf_evlist *evlist,
>  	return 0;
>  }
>  
> +static int perf_evlist__nr_threads(struct perf_evlist *evlist,
> +				   struct perf_evsel *evsel)
> +{
> +	if (evsel->system_wide)
> +		return 1;
> +	else
> +		return thread_map__nr(evlist->threads);
> +}
> +
>  void perf_evlist__disable(struct perf_evlist *evlist)
>  {
>  	int cpu, thread;
>  	struct perf_evsel *pos;
>  	int nr_cpus = cpu_map__nr(evlist->cpus);
> -	int nr_threads = thread_map__nr(evlist->threads);
> +	int nr_threads;
>  
>  	for (cpu = 0; cpu < nr_cpus; cpu++) {
>  		evlist__for_each(evlist, pos) {
>  			if (!perf_evsel__is_group_leader(pos) || !pos->fd)
>  				continue;
> +			nr_threads = perf_evlist__nr_threads(evlist, pos);
>  			for (thread = 0; thread < nr_threads; thread++)
>  				ioctl(FD(pos, cpu, thread),
>  				      PERF_EVENT_IOC_DISABLE, 0);
> @@ -288,12 +298,13 @@ void perf_evlist__enable(struct perf_evlist *evlist)
>  	int cpu, thread;
>  	struct perf_evsel *pos;
>  	int nr_cpus = cpu_map__nr(evlist->cpus);
> -	int nr_threads = thread_map__nr(evlist->threads);
> +	int nr_threads;
>  
>  	for (cpu = 0; cpu < nr_cpus; cpu++) {
>  		evlist__for_each(evlist, pos) {
>  			if (!perf_evsel__is_group_leader(pos) || !pos->fd)
>  				continue;
> +			nr_threads = perf_evlist__nr_threads(evlist, pos);
>  			for (thread = 0; thread < nr_threads; thread++)
>  				ioctl(FD(pos, cpu, thread),
>  				      PERF_EVENT_IOC_ENABLE, 0);
> @@ -305,12 +316,14 @@ int perf_evlist__disable_event(struct perf_evlist *evlist,
>  			       struct perf_evsel *evsel)
>  {
>  	int cpu, thread, err;
> +	int nr_cpus = cpu_map__nr(evlist->cpus);
> +	int nr_threads = perf_evlist__nr_threads(evlist, evsel);
>  
>  	if (!evsel->fd)
>  		return 0;
>  
> -	for (cpu = 0; cpu < evlist->cpus->nr; cpu++) {
> -		for (thread = 0; thread < evlist->threads->nr; thread++) {
> +	for (cpu = 0; cpu < nr_cpus; cpu++) {
> +		for (thread = 0; thread < nr_threads; thread++) {
>  			err = ioctl(FD(evsel, cpu, thread),
>  				    PERF_EVENT_IOC_DISABLE, 0);
>  			if (err)
> @@ -324,12 +337,14 @@ int perf_evlist__enable_event(struct perf_evlist *evlist,
>  			      struct perf_evsel *evsel)
>  {
>  	int cpu, thread, err;
> +	int nr_cpus = cpu_map__nr(evlist->cpus);
> +	int nr_threads = perf_evlist__nr_threads(evlist, evsel);
>  
>  	if (!evsel->fd)
>  		return -EINVAL;
>  
> -	for (cpu = 0; cpu < evlist->cpus->nr; cpu++) {
> -		for (thread = 0; thread < evlist->threads->nr; thread++) {
> +	for (cpu = 0; cpu < nr_cpus; cpu++) {
> +		for (thread = 0; thread < nr_threads; thread++) {
>  			err = ioctl(FD(evsel, cpu, thread),
>  				    PERF_EVENT_IOC_ENABLE, 0);
>  			if (err)

All the above seems ok, the threads (x axis) array is flat when syswide, ok.

> @@ -343,7 +358,16 @@ static int perf_evlist__alloc_pollfd(struct perf_evlist *evlist)
>  {
>  	int nr_cpus = cpu_map__nr(evlist->cpus);
>  	int nr_threads = thread_map__nr(evlist->threads);
> -	int nfds = nr_cpus * nr_threads * evlist->nr_entries;
> +	int nfds = 0;
> +	struct perf_evsel *evsel;
> +
> +	list_for_each_entry(evsel, &evlist->entries, node) {
> +		if (evsel->system_wide)
> +			nfds += nr_cpus;
> +		else
> +			nfds += nr_cpus * nr_threads;
> +	}

But here looks tricky, will look how the evlist->pollfd is used...

> +
>  	evlist->pollfd = malloc(sizeof(struct pollfd) * nfds);
>  	return evlist->pollfd != NULL ? 0 : -ENOMEM;
>  }
> @@ -636,7 +660,12 @@ static int perf_evlist__mmap_per_evsel(struct perf_evlist *evlist, int idx,
>  	struct perf_evsel *evsel;
>  
>  	evlist__for_each(evlist, evsel) {
> -		int fd = FD(evsel, cpu, thread);
> +		int fd;
> +
> +		if (evsel->system_wide && thread)
> +			continue;

Discard after thread 0, i.e. the first, ok.

> +
> +		fd = FD(evsel, cpu, thread);
>  
>  		if (*output == -1) {
>  			*output = fd;
> diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
> index 90f58cd..7540b5f 100644
> --- a/tools/perf/util/evsel.c
> +++ b/tools/perf/util/evsel.c
> @@ -691,6 +691,10 @@ void perf_evsel__config(struct perf_evsel *evsel, struct record_opts *opts)
>  int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthreads)
>  {
>  	int cpu, thread;
> +
> +	if (evsel->system_wide)
> +		nthreads = 1;

flatten it, ok

> +
>  	evsel->fd = xyarray__new(ncpus, nthreads, sizeof(int));
>  
>  	if (evsel->fd) {
> @@ -709,6 +713,9 @@ static int perf_evsel__run_ioctl(struct perf_evsel *evsel, int ncpus, int nthrea
>  {
>  	int cpu, thread;
>  
> +	if (evsel->system_wide)
> +		nthreads = 1;
> +

Ditto.

>  	for (cpu = 0; cpu < ncpus; cpu++) {
>  		for (thread = 0; thread < nthreads; thread++) {
>  			int fd = FD(evsel, cpu, thread),
> @@ -739,6 +746,9 @@ int perf_evsel__enable(struct perf_evsel *evsel, int ncpus, int nthreads)
>  
>  int perf_evsel__alloc_id(struct perf_evsel *evsel, int ncpus, int nthreads)
>  {
> +	if (evsel->system_wide)
> +		nthreads = 1;
> +
>  	evsel->sample_id = xyarray__new(ncpus, nthreads, sizeof(struct perf_sample_id));

These are per evsel, so can be flattened when we get to it,
evlist->pollfd is per evlist, so mixes syswide with !syswide,  that is why I'm scratching my head at this
point...

>  	if (evsel->sample_id == NULL)
>  		return -ENOMEM;
> @@ -783,6 +793,9 @@ void perf_evsel__close_fd(struct perf_evsel *evsel, int ncpus, int nthreads)
>  {
>  	int cpu, thread;
>  
> +	if (evsel->system_wide)
> +		nthreads = 1;
> +
>  	for (cpu = 0; cpu < ncpus; cpu++)
>  		for (thread = 0; thread < nthreads; ++thread) {
>  			close(FD(evsel, cpu, thread));
> @@ -871,6 +884,9 @@ int __perf_evsel__read(struct perf_evsel *evsel,
>  	int cpu, thread;
>  	struct perf_counts_values *aggr = &evsel->counts->aggr, count;
>  
> +	if (evsel->system_wide)
> +		nthreads = 1;
> +
>  	aggr->val = aggr->ena = aggr->run = 0;
>  
>  	for (cpu = 0; cpu < ncpus; cpu++) {
> @@ -993,13 +1009,18 @@ static size_t perf_event_attr__fprintf(struct perf_event_attr *attr, FILE *fp)
>  static int __perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus,
>  			      struct thread_map *threads)
>  {
> -	int cpu, thread;
> +	int cpu, thread, nthreads;
>  	unsigned long flags = 0;
>  	int pid = -1, err;
>  	enum { NO_CHANGE, SET_TO_MAX, INCREASED_MAX } set_rlimit = NO_CHANGE;
>  
> +	if (evsel->system_wide)
> +		nthreads = 1;
> +	else
> +		nthreads = threads->nr;
> +
>  	if (evsel->fd == NULL &&
> -	    perf_evsel__alloc_fd(evsel, cpus->nr, threads->nr) < 0)
> +	    perf_evsel__alloc_fd(evsel, cpus->nr, nthreads) < 0)
>  		return -ENOMEM;
>  
>  	if (evsel->cgrp) {
> @@ -1021,10 +1042,10 @@ retry_sample_id:
>  
>  	for (cpu = 0; cpu < cpus->nr; cpu++) {
>  
> -		for (thread = 0; thread < threads->nr; thread++) {
> +		for (thread = 0; thread < nthreads; thread++) {
>  			int group_fd;
>  
> -			if (!evsel->cgrp)
> +			if (!evsel->cgrp && !evsel->system_wide)
>  				pid = threads->map[thread];
>  
>  			group_fd = get_group_fd(evsel, cpu, thread);
> @@ -1094,7 +1115,7 @@ out_close:
>  			close(FD(evsel, cpu, thread));
>  			FD(evsel, cpu, thread) = -1;
>  		}
> -		thread = threads->nr;
> +		thread = nthreads;
>  	} while (--cpu >= 0);
>  	return err;
>  }
> diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
> index d7f93ce..dbb2a0d 100644
> --- a/tools/perf/util/evsel.h
> +++ b/tools/perf/util/evsel.h
> @@ -85,6 +85,7 @@ struct perf_evsel {
>  	bool 			needs_swap;
>  	bool			no_aux_samples;
>  	bool			immediate;
> +	bool			system_wide;
>  	/* parse modifier helper */
>  	int			exclude_GH;
>  	int			nr_members;
> -- 
> 1.8.3.2

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

* Re: [PATCH 38/41] perf session: Add perf_session__deliver_synth_event()
  2014-07-14 10:03 ` [PATCH 38/41] perf session: Add perf_session__deliver_synth_event() Adrian Hunter
@ 2014-07-15 15:17   ` Arnaldo Carvalho de Melo
  2014-07-15 18:32     ` Adrian Hunter
  0 siblings, 1 reply; 122+ messages in thread
From: Arnaldo Carvalho de Melo @ 2014-07-15 15:17 UTC (permalink / raw)
  To: Adrian Hunter
  Cc: Peter Zijlstra, linux-kernel, David Ahern, Frederic Weisbecker,
	Jiri Olsa, Namhyung Kim, Paul Mackerras, Stephane Eranian

Em Mon, Jul 14, 2014 at 01:03:02PM +0300, Adrian Hunter escreveu:
> Add a function to deliver synthesized events from
> within a session.

Why not put this in perf_session_deliver_event (and fix its naming,
renaming it to perf_session__deliver_event)?

The way you did makes me wonder why you want to fallback to
perf_session_deliver_event, i.e. would a normal event come thru a
function which name implies it should be used only for synth events?

Also that events_stats__inc() looks suspicious there :-\

- Arnaldo
 
> Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
> ---
>  tools/perf/util/session.c | 14 ++++++++++++++
>  tools/perf/util/session.h |  5 +++++
>  2 files changed, 19 insertions(+)
> 
> diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
> index 708e1c1..433884c 100644
> --- a/tools/perf/util/session.c
> +++ b/tools/perf/util/session.c
> @@ -1066,6 +1066,20 @@ static s64 perf_session__process_user_event(struct perf_session *session,
>  	}
>  }
>  
> +int perf_session__deliver_synth_event(struct perf_session *session,
> +				      union perf_event *event,
> +				      struct perf_sample *sample,
> +				      struct perf_tool *tool)
> +{
> +	events_stats__inc(&session->stats, event->header.type);
> +
> +	if (event->header.type >= PERF_RECORD_USER_TYPE_START)
> +		return perf_session__process_user_event(session, event, tool,
> +							0);
> +
> +	return perf_session_deliver_event(session, event, sample, tool, 0);
> +}
> +
>  static void event_swap(union perf_event *event, bool sample_id_all)
>  {
>  	perf_event__swap_op swap;
> diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h
> index 39327ca..86f1bb4 100644
> --- a/tools/perf/util/session.h
> +++ b/tools/perf/util/session.h
> @@ -130,6 +130,11 @@ extern volatile int session_done;
>  
>  #define session_done()	(*(volatile int *)(&session_done))
>  
> +int perf_session__deliver_synth_event(struct perf_session *session,
> +				      union perf_event *event,
> +				      struct perf_sample *sample,
> +				      struct perf_tool *tool);
> +
>  int perf_event__process_id_index(struct perf_tool *tool,
>  				 union perf_event *event,
>  				 struct perf_session *session);
> -- 
> 1.8.3.2

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

* Re: [PATCH 39/41] perf tools: Allow TSC conversion on any arch
  2014-07-14 10:03 ` [PATCH 39/41] perf tools: Allow TSC conversion on any arch Adrian Hunter
@ 2014-07-15 15:20   ` Arnaldo Carvalho de Melo
  2014-07-15 16:17     ` Peter Zijlstra
  2014-07-15 17:48     ` Adrian Hunter
  2014-07-18  4:28   ` [tip:perf/core] " tip-bot for Adrian Hunter
  1 sibling, 2 replies; 122+ messages in thread
From: Arnaldo Carvalho de Melo @ 2014-07-15 15:20 UTC (permalink / raw)
  To: Adrian Hunter
  Cc: Peter Zijlstra, linux-kernel, David Ahern, Frederic Weisbecker,
	Jiri Olsa, Namhyung Kim, Paul Mackerras, Stephane Eranian

Em Mon, Jul 14, 2014 at 01:03:03PM +0300, Adrian Hunter escreveu:
> It is possible to record a perf.data file on
> one architecture and process it on another.
> Consequently, TSC conversion functions need
> to be moved out of the arch directory.

Can you state where a TSC is stored in perf.data, and how in the !x86
arch this will be detected so that those functions will be used?

- Arnaldo
 
> Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
> ---
>  tools/perf/Makefile.perf            |  2 ++
>  tools/perf/arch/x86/util/tsc.c      | 22 +---------------------
>  tools/perf/arch/x86/util/tsc.h      |  3 ---
>  tools/perf/tests/perf-time-to-tsc.c |  3 +--
>  tools/perf/util/tsc.c               | 25 +++++++++++++++++++++++++
>  tools/perf/util/tsc.h               | 11 +++++++++++
>  6 files changed, 40 insertions(+), 26 deletions(-)
>  create mode 100644 tools/perf/util/tsc.c
>  create mode 100644 tools/perf/util/tsc.h
> 
> diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
> index 9670a16..abca577 100644
> --- a/tools/perf/Makefile.perf
> +++ b/tools/perf/Makefile.perf
> @@ -295,6 +295,7 @@ LIB_H += util/intlist.h
>  LIB_H += util/perf_regs.h
>  LIB_H += util/unwind.h
>  LIB_H += util/vdso.h
> +LIB_H += util/tsc.h
>  LIB_H += ui/helpline.h
>  LIB_H += ui/progress.h
>  LIB_H += ui/util.h
> @@ -373,6 +374,7 @@ LIB_OBJS += $(OUTPUT)util/stat.o
>  LIB_OBJS += $(OUTPUT)util/record.o
>  LIB_OBJS += $(OUTPUT)util/srcline.o
>  LIB_OBJS += $(OUTPUT)util/data.o
> +LIB_OBJS += $(OUTPUT)util/tsc.o
>  
>  LIB_OBJS += $(OUTPUT)ui/setup.o
>  LIB_OBJS += $(OUTPUT)ui/helpline.o
> diff --git a/tools/perf/arch/x86/util/tsc.c b/tools/perf/arch/x86/util/tsc.c
> index 40021fa..3655f24 100644
> --- a/tools/perf/arch/x86/util/tsc.c
> +++ b/tools/perf/arch/x86/util/tsc.c
> @@ -6,29 +6,9 @@
>  #include "../../perf.h"
>  #include <linux/types.h>
>  #include "../../util/debug.h"
> +#include "../../util/tsc.h"
>  #include "tsc.h"
>  
> -u64 perf_time_to_tsc(u64 ns, struct perf_tsc_conversion *tc)
> -{
> -	u64 t, quot, rem;
> -
> -	t = ns - tc->time_zero;
> -	quot = t / tc->time_mult;
> -	rem  = t % tc->time_mult;
> -	return (quot << tc->time_shift) +
> -	       (rem << tc->time_shift) / tc->time_mult;
> -}
> -
> -u64 tsc_to_perf_time(u64 cyc, struct perf_tsc_conversion *tc)
> -{
> -	u64 quot, rem;
> -
> -	quot = cyc >> tc->time_shift;
> -	rem  = cyc & ((1 << tc->time_shift) - 1);
> -	return tc->time_zero + quot * tc->time_mult +
> -	       ((rem * tc->time_mult) >> tc->time_shift);
> -}
> -
>  int perf_read_tsc_conversion(const struct perf_event_mmap_page *pc,
>  			     struct perf_tsc_conversion *tc)
>  {
> diff --git a/tools/perf/arch/x86/util/tsc.h b/tools/perf/arch/x86/util/tsc.h
> index 2affe03..2edc4d3 100644
> --- a/tools/perf/arch/x86/util/tsc.h
> +++ b/tools/perf/arch/x86/util/tsc.h
> @@ -14,7 +14,4 @@ struct perf_event_mmap_page;
>  int perf_read_tsc_conversion(const struct perf_event_mmap_page *pc,
>  			     struct perf_tsc_conversion *tc);
>  
> -u64 perf_time_to_tsc(u64 ns, struct perf_tsc_conversion *tc);
> -u64 tsc_to_perf_time(u64 cyc, struct perf_tsc_conversion *tc);
> -
>  #endif /* TOOLS_PERF_ARCH_X86_UTIL_TSC_H__ */
> diff --git a/tools/perf/tests/perf-time-to-tsc.c b/tools/perf/tests/perf-time-to-tsc.c
> index 3b7cd4d..0372f6e 100644
> --- a/tools/perf/tests/perf-time-to-tsc.c
> +++ b/tools/perf/tests/perf-time-to-tsc.c
> @@ -8,10 +8,9 @@
>  #include "evsel.h"
>  #include "thread_map.h"
>  #include "cpumap.h"
> +#include "tsc.h"
>  #include "tests.h"
>  
> -#include "../arch/x86/util/tsc.h"
> -
>  #define CHECK__(x) {				\
>  	while ((x) < 0) {			\
>  		pr_debug(#x " failed!\n");	\
> diff --git a/tools/perf/util/tsc.c b/tools/perf/util/tsc.c
> new file mode 100644
> index 0000000..ef4749836
> --- /dev/null
> +++ b/tools/perf/util/tsc.c
> @@ -0,0 +1,25 @@
> +#include <linux/compiler.h>
> +#include <linux/types.h>
> +
> +#include "tsc.h"
> +
> +u64 perf_time_to_tsc(u64 ns, struct perf_tsc_conversion *tc)
> +{
> +	u64 t, quot, rem;
> +
> +	t = ns - tc->time_zero;
> +	quot = t / tc->time_mult;
> +	rem  = t % tc->time_mult;
> +	return (quot << tc->time_shift) +
> +	       (rem << tc->time_shift) / tc->time_mult;
> +}
> +
> +u64 tsc_to_perf_time(u64 cyc, struct perf_tsc_conversion *tc)
> +{
> +	u64 quot, rem;
> +
> +	quot = cyc >> tc->time_shift;
> +	rem  = cyc & ((1 << tc->time_shift) - 1);
> +	return tc->time_zero + quot * tc->time_mult +
> +	       ((rem * tc->time_mult) >> tc->time_shift);
> +}
> diff --git a/tools/perf/util/tsc.h b/tools/perf/util/tsc.h
> new file mode 100644
> index 0000000..4eca848
> --- /dev/null
> +++ b/tools/perf/util/tsc.h
> @@ -0,0 +1,11 @@
> +#ifndef __PERF_TSC_H
> +#define __PERF_TSC_H
> +
> +#include <linux/types.h>
> +
> +#include "../arch/x86/util/tsc.h"
> +
> +u64 perf_time_to_tsc(u64 ns, struct perf_tsc_conversion *tc);
> +u64 tsc_to_perf_time(u64 cyc, struct perf_tsc_conversion *tc);
> +
> +#endif
> -- 
> 1.8.3.2

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

* Re: [PATCH 39/41] perf tools: Allow TSC conversion on any arch
  2014-07-15 15:20   ` Arnaldo Carvalho de Melo
@ 2014-07-15 16:17     ` Peter Zijlstra
  2014-07-15 17:48     ` Adrian Hunter
  1 sibling, 0 replies; 122+ messages in thread
From: Peter Zijlstra @ 2014-07-15 16:17 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Adrian Hunter, linux-kernel, David Ahern, Frederic Weisbecker,
	Jiri Olsa, Namhyung Kim, Paul Mackerras, Stephane Eranian

[-- Attachment #1: Type: text/plain, Size: 685 bytes --]

On Tue, Jul 15, 2014 at 12:20:03PM -0300, Arnaldo Carvalho de Melo wrote:
> Em Mon, Jul 14, 2014 at 01:03:03PM +0300, Adrian Hunter escreveu:
> > It is possible to record a perf.data file on
> > one architecture and process it on another.
> > Consequently, TSC conversion functions need
> > to be moved out of the arch directory.
> 
> Can you state where a TSC is stored in perf.data, and how in the !x86
> arch this will be detected so that those functions will be used?

So there's nothing intrinsically x86/tsc about the perf interface here,
although that's currently the only one implementing this thing.

Other archs could equally expose their 'cycle' counter etc..

[-- Attachment #2: Type: application/pgp-signature, Size: 836 bytes --]

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

* Re: [PATCH 39/41] perf tools: Allow TSC conversion on any arch
  2014-07-15 15:20   ` Arnaldo Carvalho de Melo
  2014-07-15 16:17     ` Peter Zijlstra
@ 2014-07-15 17:48     ` Adrian Hunter
  1 sibling, 0 replies; 122+ messages in thread
From: Adrian Hunter @ 2014-07-15 17:48 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Peter Zijlstra, linux-kernel, David Ahern, Frederic Weisbecker,
	Jiri Olsa, Namhyung Kim, Paul Mackerras, Stephane Eranian

On 15/07/2014 6:20 p.m., Arnaldo Carvalho de Melo wrote:
> Em Mon, Jul 14, 2014 at 01:03:03PM +0300, Adrian Hunter escreveu:
>> It is possible to record a perf.data file on
>> one architecture and process it on another.
>> Consequently, TSC conversion functions need
>> to be moved out of the arch directory.
>
> Can you state where a TSC is stored in perf.data, and how in the !x86
> arch this will be detected so that those functions will be used?

Intel PT has packets that contain 7-bytes of TSC.  'perf record' adds a
reference TSC to the ITRACE event so that the full TSC is known.

So this is the possibility that you record a perf.data file on x86
recording Intel PT and then take that file to another machine with a
different architecture.  It should still be possible to read the file there.

>
> - Arnaldo
>
>> Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
>> ---
>>   tools/perf/Makefile.perf            |  2 ++
>>   tools/perf/arch/x86/util/tsc.c      | 22 +---------------------
>>   tools/perf/arch/x86/util/tsc.h      |  3 ---
>>   tools/perf/tests/perf-time-to-tsc.c |  3 +--
>>   tools/perf/util/tsc.c               | 25 +++++++++++++++++++++++++
>>   tools/perf/util/tsc.h               | 11 +++++++++++
>>   6 files changed, 40 insertions(+), 26 deletions(-)
>>   create mode 100644 tools/perf/util/tsc.c
>>   create mode 100644 tools/perf/util/tsc.h
>>
>> diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
>> index 9670a16..abca577 100644
>> --- a/tools/perf/Makefile.perf
>> +++ b/tools/perf/Makefile.perf
>> @@ -295,6 +295,7 @@ LIB_H += util/intlist.h
>>   LIB_H += util/perf_regs.h
>>   LIB_H += util/unwind.h
>>   LIB_H += util/vdso.h
>> +LIB_H += util/tsc.h
>>   LIB_H += ui/helpline.h
>>   LIB_H += ui/progress.h
>>   LIB_H += ui/util.h
>> @@ -373,6 +374,7 @@ LIB_OBJS += $(OUTPUT)util/stat.o
>>   LIB_OBJS += $(OUTPUT)util/record.o
>>   LIB_OBJS += $(OUTPUT)util/srcline.o
>>   LIB_OBJS += $(OUTPUT)util/data.o
>> +LIB_OBJS += $(OUTPUT)util/tsc.o
>>
>>   LIB_OBJS += $(OUTPUT)ui/setup.o
>>   LIB_OBJS += $(OUTPUT)ui/helpline.o
>> diff --git a/tools/perf/arch/x86/util/tsc.c b/tools/perf/arch/x86/util/tsc.c
>> index 40021fa..3655f24 100644
>> --- a/tools/perf/arch/x86/util/tsc.c
>> +++ b/tools/perf/arch/x86/util/tsc.c
>> @@ -6,29 +6,9 @@
>>   #include "../../perf.h"
>>   #include <linux/types.h>
>>   #include "../../util/debug.h"
>> +#include "../../util/tsc.h"
>>   #include "tsc.h"
>>
>> -u64 perf_time_to_tsc(u64 ns, struct perf_tsc_conversion *tc)
>> -{
>> -	u64 t, quot, rem;
>> -
>> -	t = ns - tc->time_zero;
>> -	quot = t / tc->time_mult;
>> -	rem  = t % tc->time_mult;
>> -	return (quot << tc->time_shift) +
>> -	       (rem << tc->time_shift) / tc->time_mult;
>> -}
>> -
>> -u64 tsc_to_perf_time(u64 cyc, struct perf_tsc_conversion *tc)
>> -{
>> -	u64 quot, rem;
>> -
>> -	quot = cyc >> tc->time_shift;
>> -	rem  = cyc & ((1 << tc->time_shift) - 1);
>> -	return tc->time_zero + quot * tc->time_mult +
>> -	       ((rem * tc->time_mult) >> tc->time_shift);
>> -}
>> -
>>   int perf_read_tsc_conversion(const struct perf_event_mmap_page *pc,
>>   			     struct perf_tsc_conversion *tc)
>>   {
>> diff --git a/tools/perf/arch/x86/util/tsc.h b/tools/perf/arch/x86/util/tsc.h
>> index 2affe03..2edc4d3 100644
>> --- a/tools/perf/arch/x86/util/tsc.h
>> +++ b/tools/perf/arch/x86/util/tsc.h
>> @@ -14,7 +14,4 @@ struct perf_event_mmap_page;
>>   int perf_read_tsc_conversion(const struct perf_event_mmap_page *pc,
>>   			     struct perf_tsc_conversion *tc);
>>
>> -u64 perf_time_to_tsc(u64 ns, struct perf_tsc_conversion *tc);
>> -u64 tsc_to_perf_time(u64 cyc, struct perf_tsc_conversion *tc);
>> -
>>   #endif /* TOOLS_PERF_ARCH_X86_UTIL_TSC_H__ */
>> diff --git a/tools/perf/tests/perf-time-to-tsc.c b/tools/perf/tests/perf-time-to-tsc.c
>> index 3b7cd4d..0372f6e 100644
>> --- a/tools/perf/tests/perf-time-to-tsc.c
>> +++ b/tools/perf/tests/perf-time-to-tsc.c
>> @@ -8,10 +8,9 @@
>>   #include "evsel.h"
>>   #include "thread_map.h"
>>   #include "cpumap.h"
>> +#include "tsc.h"
>>   #include "tests.h"
>>
>> -#include "../arch/x86/util/tsc.h"
>> -
>>   #define CHECK__(x) {				\
>>   	while ((x) < 0) {			\
>>   		pr_debug(#x " failed!\n");	\
>> diff --git a/tools/perf/util/tsc.c b/tools/perf/util/tsc.c
>> new file mode 100644
>> index 0000000..ef4749836
>> --- /dev/null
>> +++ b/tools/perf/util/tsc.c
>> @@ -0,0 +1,25 @@
>> +#include <linux/compiler.h>
>> +#include <linux/types.h>
>> +
>> +#include "tsc.h"
>> +
>> +u64 perf_time_to_tsc(u64 ns, struct perf_tsc_conversion *tc)
>> +{
>> +	u64 t, quot, rem;
>> +
>> +	t = ns - tc->time_zero;
>> +	quot = t / tc->time_mult;
>> +	rem  = t % tc->time_mult;
>> +	return (quot << tc->time_shift) +
>> +	       (rem << tc->time_shift) / tc->time_mult;
>> +}
>> +
>> +u64 tsc_to_perf_time(u64 cyc, struct perf_tsc_conversion *tc)
>> +{
>> +	u64 quot, rem;
>> +
>> +	quot = cyc >> tc->time_shift;
>> +	rem  = cyc & ((1 << tc->time_shift) - 1);
>> +	return tc->time_zero + quot * tc->time_mult +
>> +	       ((rem * tc->time_mult) >> tc->time_shift);
>> +}
>> diff --git a/tools/perf/util/tsc.h b/tools/perf/util/tsc.h
>> new file mode 100644
>> index 0000000..4eca848
>> --- /dev/null
>> +++ b/tools/perf/util/tsc.h
>> @@ -0,0 +1,11 @@
>> +#ifndef __PERF_TSC_H
>> +#define __PERF_TSC_H
>> +
>> +#include <linux/types.h>
>> +
>> +#include "../arch/x86/util/tsc.h"
>> +
>> +u64 perf_time_to_tsc(u64 ns, struct perf_tsc_conversion *tc);
>> +u64 tsc_to_perf_time(u64 cyc, struct perf_tsc_conversion *tc);
>> +
>> +#endif
>> --
>> 1.8.3.2

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

* Re: [PATCH 15/41] perf script: Improve srcline display for BTS
  2014-07-15 14:16   ` Arnaldo Carvalho de Melo
@ 2014-07-15 17:51     ` Adrian Hunter
  2014-07-16  2:08     ` David Ahern
  1 sibling, 0 replies; 122+ messages in thread
From: Adrian Hunter @ 2014-07-15 17:51 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Peter Zijlstra, linux-kernel, David Ahern, Frederic Weisbecker,
	Jiri Olsa, Namhyung Kim, Paul Mackerras, Stephane Eranian

On 15/07/2014 5:16 p.m., Arnaldo Carvalho de Melo wrote:
> Em Mon, Jul 14, 2014 at 01:02:39PM +0300, Adrian Hunter escreveu:
>> Change the order of the output to put the srcline last.
>> e.g. old format:
>>
>>            4028fc main+0x2c (/bin/ls)
>>    /build/buildd/coreutils-8.20/src/ls.c:1269 =>           40d8a0 set_program_name+0x0 (/bin/ls)
>>
>> new format:
>>
>>            4028fc main+0x2c (/bin/ls) =>           40d8a0 set_program_name+0x0 (/bin/ls)
>>    /build/buildd/coreutils-8.20/src/ls.c:1269
>
> David,
>
> 	Can I have your acked-by?
>
> Adrian,
>
> 	Can you elaborate on why this is an improvement?

It puts the branch 'from address' and 'to address' on the same line,
which is how it would be without the source line reference.  So it
makes it consistent and much easier to read.


>
> - Arnaldo
>
>> Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
>> ---
>>   tools/perf/builtin-script.c | 20 +++++++++++++++-----
>>   1 file changed, 15 insertions(+), 5 deletions(-)
>>
>> diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
>> index 9e9c91f..333b15e 100644
>> --- a/tools/perf/builtin-script.c
>> +++ b/tools/perf/builtin-script.c
>> @@ -427,15 +427,22 @@ static void print_sample_bts(union perf_event *event,
>>   			     struct addr_location *al)
>>   {
>>   	struct perf_event_attr *attr = &evsel->attr;
>> +	bool print_srcline_last = false;
>>
>>   	/* print branch_from information */
>>   	if (PRINT_FIELD(IP)) {
>> -		if (!symbol_conf.use_callchain)
>> -			printf(" ");
>> -		else
>> +		unsigned int print_opts = output[attr->type].print_ip_opts;
>> +
>> +		if (symbol_conf.use_callchain && sample->callchain) {
>>   			printf("\n");
>> -		perf_evsel__print_ip(evsel, sample, al,
>> -				     output[attr->type].print_ip_opts,
>> +		} else {
>> +			printf(" ");
>> +			if (print_opts & PRINT_IP_OPT_SRCLINE) {
>> +				print_srcline_last = true;
>> +				print_opts &= ~PRINT_IP_OPT_SRCLINE;
>> +			}
>> +		}
>> +		perf_evsel__print_ip(evsel, sample, al, print_opts,
>>   				     PERF_MAX_STACK_DEPTH);
>>   	}
>>
>> @@ -447,6 +454,9 @@ static void print_sample_bts(union perf_event *event,
>>   	     !output[attr->type].user_set))
>>   		print_sample_addr(event, sample, al->machine, thread, attr);
>>
>> +	if (print_srcline_last)
>> +		map__fprintf_srcline(al->map, al->addr, "\n  ", stdout);
>> +
>>   	printf("\n");
>>   }
>>
>> --
>> 1.8.3.2

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

* Re: [PATCH 24/41] perf tools: Add cpu to struct thread
  2014-07-15 14:24   ` Arnaldo Carvalho de Melo
@ 2014-07-15 17:58     ` Adrian Hunter
  0 siblings, 0 replies; 122+ messages in thread
From: Adrian Hunter @ 2014-07-15 17:58 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Peter Zijlstra, linux-kernel, David Ahern, Frederic Weisbecker,
	Jiri Olsa, Namhyung Kim, Paul Mackerras, Stephane Eranian

On 15/07/2014 5:24 p.m., Arnaldo Carvalho de Melo wrote:
> Em Mon, Jul 14, 2014 at 01:02:48PM +0300, Adrian Hunter escreveu:
>> Tools may wish to track on which cpu a thread
>> is running.  Add 'cpu' to struct thread for
>> that purpose.
>>
>> This will be used to determine the cpu when
>> decoding a per-thread Instruction Trace.
>
> Humm, is this the last cpu we got some event telling the cpu was running
> on? Continuing looking at the patches...

Yes.  Intel PT decoding uses sched_switch events to determine which
task is running on which cpu.  The Intel PT data comes straight
from the hardware which doesn't know about linux threads.

>
> - Arnaldo
>
>> Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
>> ---
>>   tools/perf/util/thread.c | 1 +
>>   tools/perf/util/thread.h | 1 +
>>   2 files changed, 2 insertions(+)
>>
>> diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c
>> index b9a3ee4..2f8c0c1 100644
>> --- a/tools/perf/util/thread.c
>> +++ b/tools/perf/util/thread.c
>> @@ -69,6 +69,7 @@ struct thread *thread__new(pid_t pid, pid_t tid)
>>   		thread->pid_ = pid;
>>   		thread->tid = tid;
>>   		thread->ppid = -1;
>> +		thread->cpu = -1;
>>   		INIT_LIST_HEAD(&thread->comm_list);
>>
>>   		comm_str = malloc(32);
>> diff --git a/tools/perf/util/thread.h b/tools/perf/util/thread.h
>> index b4269af..e4920ff 100644
>> --- a/tools/perf/util/thread.h
>> +++ b/tools/perf/util/thread.h
>> @@ -17,6 +17,7 @@ struct thread {
>>   	pid_t			pid_; /* Not all tools update this */
>>   	pid_t			tid;
>>   	pid_t			ppid;
>> +	int			cpu;
>>   	char			shortname[3];
>>   	bool			comm_set;
>>   	bool			dead; /* if set thread has exited */
>> --
>> 1.8.3.2

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

* Re: [PATCH 34/41] perf evlist: Add 'system_wide' option
  2014-07-15 15:03   ` Arnaldo Carvalho de Melo
@ 2014-07-15 18:05     ` Adrian Hunter
  0 siblings, 0 replies; 122+ messages in thread
From: Adrian Hunter @ 2014-07-15 18:05 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Peter Zijlstra, linux-kernel, David Ahern, Frederic Weisbecker,
	Jiri Olsa, Namhyung Kim, Paul Mackerras, Stephane Eranian

On 15/07/2014 6:03 p.m., Arnaldo Carvalho de Melo wrote:
> Em Mon, Jul 14, 2014 at 01:02:58PM +0300, Adrian Hunter escreveu:
>> Add an option to cause a selected event
>> to be opened always without a pid when
>> configured by perf_evsel__config().
>>
>> This is needed when using the sched_switch
>> tracepoint to follow object code execution.
>> sched_switch occurs before the task
>> switch and so it cannot record it in a
>> context limited to that task.  Note
>> that also means that sched_switch is
>> useless when capturing data per-thread,
>> as is the 'context-switches' software
>> event for the same reason.
>
> clever, but humm, need to be judicious when allocating things like the
> pollfd, I think, more below...
>
> ... after going thru the whole patch, its not clear how pollfd usage
> takes into account the fact that some of the evsels don't have
> thread_map->nr entries, but just one, will continue reading...
>
>> Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
>> ---
>>   tools/perf/util/evlist.c | 45 +++++++++++++++++++++++++++++++++++++--------
>>   tools/perf/util/evsel.c  | 31 ++++++++++++++++++++++++++-----
>>   tools/perf/util/evsel.h  |  1 +
>>   3 files changed, 64 insertions(+), 13 deletions(-)
>>
>> diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
>> index 282e83e..c295b7b 100644
>> --- a/tools/perf/util/evlist.c
>> +++ b/tools/perf/util/evlist.c
>> @@ -265,17 +265,27 @@ int perf_evlist__add_newtp(struct perf_evlist *evlist,
>>   	return 0;
>>   }
>>
>> +static int perf_evlist__nr_threads(struct perf_evlist *evlist,
>> +				   struct perf_evsel *evsel)
>> +{
>> +	if (evsel->system_wide)
>> +		return 1;
>> +	else
>> +		return thread_map__nr(evlist->threads);
>> +}
>> +
>>   void perf_evlist__disable(struct perf_evlist *evlist)
>>   {
>>   	int cpu, thread;
>>   	struct perf_evsel *pos;
>>   	int nr_cpus = cpu_map__nr(evlist->cpus);
>> -	int nr_threads = thread_map__nr(evlist->threads);
>> +	int nr_threads;
>>
>>   	for (cpu = 0; cpu < nr_cpus; cpu++) {
>>   		evlist__for_each(evlist, pos) {
>>   			if (!perf_evsel__is_group_leader(pos) || !pos->fd)
>>   				continue;
>> +			nr_threads = perf_evlist__nr_threads(evlist, pos);
>>   			for (thread = 0; thread < nr_threads; thread++)
>>   				ioctl(FD(pos, cpu, thread),
>>   				      PERF_EVENT_IOC_DISABLE, 0);
>> @@ -288,12 +298,13 @@ void perf_evlist__enable(struct perf_evlist *evlist)
>>   	int cpu, thread;
>>   	struct perf_evsel *pos;
>>   	int nr_cpus = cpu_map__nr(evlist->cpus);
>> -	int nr_threads = thread_map__nr(evlist->threads);
>> +	int nr_threads;
>>
>>   	for (cpu = 0; cpu < nr_cpus; cpu++) {
>>   		evlist__for_each(evlist, pos) {
>>   			if (!perf_evsel__is_group_leader(pos) || !pos->fd)
>>   				continue;
>> +			nr_threads = perf_evlist__nr_threads(evlist, pos);
>>   			for (thread = 0; thread < nr_threads; thread++)
>>   				ioctl(FD(pos, cpu, thread),
>>   				      PERF_EVENT_IOC_ENABLE, 0);
>> @@ -305,12 +316,14 @@ int perf_evlist__disable_event(struct perf_evlist *evlist,
>>   			       struct perf_evsel *evsel)
>>   {
>>   	int cpu, thread, err;
>> +	int nr_cpus = cpu_map__nr(evlist->cpus);
>> +	int nr_threads = perf_evlist__nr_threads(evlist, evsel);
>>
>>   	if (!evsel->fd)
>>   		return 0;
>>
>> -	for (cpu = 0; cpu < evlist->cpus->nr; cpu++) {
>> -		for (thread = 0; thread < evlist->threads->nr; thread++) {
>> +	for (cpu = 0; cpu < nr_cpus; cpu++) {
>> +		for (thread = 0; thread < nr_threads; thread++) {
>>   			err = ioctl(FD(evsel, cpu, thread),
>>   				    PERF_EVENT_IOC_DISABLE, 0);
>>   			if (err)
>> @@ -324,12 +337,14 @@ int perf_evlist__enable_event(struct perf_evlist *evlist,
>>   			      struct perf_evsel *evsel)
>>   {
>>   	int cpu, thread, err;
>> +	int nr_cpus = cpu_map__nr(evlist->cpus);
>> +	int nr_threads = perf_evlist__nr_threads(evlist, evsel);
>>
>>   	if (!evsel->fd)
>>   		return -EINVAL;
>>
>> -	for (cpu = 0; cpu < evlist->cpus->nr; cpu++) {
>> -		for (thread = 0; thread < evlist->threads->nr; thread++) {
>> +	for (cpu = 0; cpu < nr_cpus; cpu++) {
>> +		for (thread = 0; thread < nr_threads; thread++) {
>>   			err = ioctl(FD(evsel, cpu, thread),
>>   				    PERF_EVENT_IOC_ENABLE, 0);
>>   			if (err)
>
> All the above seems ok, the threads (x axis) array is flat when syswide, ok.
>
>> @@ -343,7 +358,16 @@ static int perf_evlist__alloc_pollfd(struct perf_evlist *evlist)
>>   {
>>   	int nr_cpus = cpu_map__nr(evlist->cpus);
>>   	int nr_threads = thread_map__nr(evlist->threads);
>> -	int nfds = nr_cpus * nr_threads * evlist->nr_entries;
>> +	int nfds = 0;
>> +	struct perf_evsel *evsel;
>> +
>> +	list_for_each_entry(evsel, &evlist->entries, node) {
>> +		if (evsel->system_wide)
>> +			nfds += nr_cpus;
>> +		else
>> +			nfds += nr_cpus * nr_threads;
>> +	}
>
> But here looks tricky, will look how the evlist->pollfd is used...
>
>> +
>>   	evlist->pollfd = malloc(sizeof(struct pollfd) * nfds);
>>   	return evlist->pollfd != NULL ? 0 : -ENOMEM;
>>   }
>> @@ -636,7 +660,12 @@ static int perf_evlist__mmap_per_evsel(struct perf_evlist *evlist, int idx,
>>   	struct perf_evsel *evsel;
>>
>>   	evlist__for_each(evlist, evsel) {
>> -		int fd = FD(evsel, cpu, thread);
>> +		int fd;
>> +
>> +		if (evsel->system_wide && thread)
>> +			continue;
>
> Discard after thread 0, i.e. the first, ok.
>
>> +
>> +		fd = FD(evsel, cpu, thread);
>>
>>   		if (*output == -1) {
>>   			*output = fd;
>> diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
>> index 90f58cd..7540b5f 100644
>> --- a/tools/perf/util/evsel.c
>> +++ b/tools/perf/util/evsel.c
>> @@ -691,6 +691,10 @@ void perf_evsel__config(struct perf_evsel *evsel, struct record_opts *opts)
>>   int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthreads)
>>   {
>>   	int cpu, thread;
>> +
>> +	if (evsel->system_wide)
>> +		nthreads = 1;
>
> flatten it, ok
>
>> +
>>   	evsel->fd = xyarray__new(ncpus, nthreads, sizeof(int));
>>
>>   	if (evsel->fd) {
>> @@ -709,6 +713,9 @@ static int perf_evsel__run_ioctl(struct perf_evsel *evsel, int ncpus, int nthrea
>>   {
>>   	int cpu, thread;
>>
>> +	if (evsel->system_wide)
>> +		nthreads = 1;
>> +
>
> Ditto.
>
>>   	for (cpu = 0; cpu < ncpus; cpu++) {
>>   		for (thread = 0; thread < nthreads; thread++) {
>>   			int fd = FD(evsel, cpu, thread),
>> @@ -739,6 +746,9 @@ int perf_evsel__enable(struct perf_evsel *evsel, int ncpus, int nthreads)
>>
>>   int perf_evsel__alloc_id(struct perf_evsel *evsel, int ncpus, int nthreads)
>>   {
>> +	if (evsel->system_wide)
>> +		nthreads = 1;
>> +
>>   	evsel->sample_id = xyarray__new(ncpus, nthreads, sizeof(struct perf_sample_id));
>
> These are per evsel, so can be flattened when we get to it,
> evlist->pollfd is per evlist, so mixes syswide with !syswide,  that is why I'm scratching my head at this
> point...

pollfd is not a 2-dimensional array.  It is just a 1-dimensional array.
So it just needs to be the right length.

>
>>   	if (evsel->sample_id == NULL)
>>   		return -ENOMEM;
>> @@ -783,6 +793,9 @@ void perf_evsel__close_fd(struct perf_evsel *evsel, int ncpus, int nthreads)
>>   {
>>   	int cpu, thread;
>>
>> +	if (evsel->system_wide)
>> +		nthreads = 1;
>> +
>>   	for (cpu = 0; cpu < ncpus; cpu++)
>>   		for (thread = 0; thread < nthreads; ++thread) {
>>   			close(FD(evsel, cpu, thread));
>> @@ -871,6 +884,9 @@ int __perf_evsel__read(struct perf_evsel *evsel,
>>   	int cpu, thread;
>>   	struct perf_counts_values *aggr = &evsel->counts->aggr, count;
>>
>> +	if (evsel->system_wide)
>> +		nthreads = 1;
>> +
>>   	aggr->val = aggr->ena = aggr->run = 0;
>>
>>   	for (cpu = 0; cpu < ncpus; cpu++) {
>> @@ -993,13 +1009,18 @@ static size_t perf_event_attr__fprintf(struct perf_event_attr *attr, FILE *fp)
>>   static int __perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus,
>>   			      struct thread_map *threads)
>>   {
>> -	int cpu, thread;
>> +	int cpu, thread, nthreads;
>>   	unsigned long flags = 0;
>>   	int pid = -1, err;
>>   	enum { NO_CHANGE, SET_TO_MAX, INCREASED_MAX } set_rlimit = NO_CHANGE;
>>
>> +	if (evsel->system_wide)
>> +		nthreads = 1;
>> +	else
>> +		nthreads = threads->nr;
>> +
>>   	if (evsel->fd == NULL &&
>> -	    perf_evsel__alloc_fd(evsel, cpus->nr, threads->nr) < 0)
>> +	    perf_evsel__alloc_fd(evsel, cpus->nr, nthreads) < 0)
>>   		return -ENOMEM;
>>
>>   	if (evsel->cgrp) {
>> @@ -1021,10 +1042,10 @@ retry_sample_id:
>>
>>   	for (cpu = 0; cpu < cpus->nr; cpu++) {
>>
>> -		for (thread = 0; thread < threads->nr; thread++) {
>> +		for (thread = 0; thread < nthreads; thread++) {
>>   			int group_fd;
>>
>> -			if (!evsel->cgrp)
>> +			if (!evsel->cgrp && !evsel->system_wide)
>>   				pid = threads->map[thread];
>>
>>   			group_fd = get_group_fd(evsel, cpu, thread);
>> @@ -1094,7 +1115,7 @@ out_close:
>>   			close(FD(evsel, cpu, thread));
>>   			FD(evsel, cpu, thread) = -1;
>>   		}
>> -		thread = threads->nr;
>> +		thread = nthreads;
>>   	} while (--cpu >= 0);
>>   	return err;
>>   }
>> diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
>> index d7f93ce..dbb2a0d 100644
>> --- a/tools/perf/util/evsel.h
>> +++ b/tools/perf/util/evsel.h
>> @@ -85,6 +85,7 @@ struct perf_evsel {
>>   	bool 			needs_swap;
>>   	bool			no_aux_samples;
>>   	bool			immediate;
>> +	bool			system_wide;
>>   	/* parse modifier helper */
>>   	int			exclude_GH;
>>   	int			nr_members;
>> --
>> 1.8.3.2

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

* Re: [PATCH 38/41] perf session: Add perf_session__deliver_synth_event()
  2014-07-15 15:17   ` Arnaldo Carvalho de Melo
@ 2014-07-15 18:32     ` Adrian Hunter
  0 siblings, 0 replies; 122+ messages in thread
From: Adrian Hunter @ 2014-07-15 18:32 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Peter Zijlstra, linux-kernel, David Ahern, Frederic Weisbecker,
	Jiri Olsa, Namhyung Kim, Paul Mackerras, Stephane Eranian

On 15/07/2014 6:17 p.m., Arnaldo Carvalho de Melo wrote:
> Em Mon, Jul 14, 2014 at 01:03:02PM +0300, Adrian Hunter escreveu:
>> Add a function to deliver synthesized events from
>> within a session.
>
> Why not put this in perf_session_deliver_event (and fix its naming,
> renaming it to perf_session__deliver_event)?
>
> The way you did makes me wonder why you want to fallback to
> perf_session_deliver_event, i.e. would a normal event come thru a
> function which name implies it should be used only for synth events?
>
> Also that events_stats__inc() looks suspicious there :-\

What happens is Intel PT (or Intel BTS) data is decoded which
results in (mostly) branch data.  So "branches" events are
synthesized and injected into the event stream using
perf_session__deliver_synth_event().

The structure of perf_session__deliver_synth_event() reflects
the fact that "user" events (not from the kernel) are processed
differently to "real" events (from the kernel or synthesized).

The synthesized branches events are then consumed by the tools
just as though they came directly from the perf.data file
- so updating stats is normal.


>
> - Arnaldo
>
>> Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
>> ---
>>   tools/perf/util/session.c | 14 ++++++++++++++
>>   tools/perf/util/session.h |  5 +++++
>>   2 files changed, 19 insertions(+)
>>
>> diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
>> index 708e1c1..433884c 100644
>> --- a/tools/perf/util/session.c
>> +++ b/tools/perf/util/session.c
>> @@ -1066,6 +1066,20 @@ static s64 perf_session__process_user_event(struct perf_session *session,
>>   	}
>>   }
>>
>> +int perf_session__deliver_synth_event(struct perf_session *session,
>> +				      union perf_event *event,
>> +				      struct perf_sample *sample,
>> +				      struct perf_tool *tool)
>> +{
>> +	events_stats__inc(&session->stats, event->header.type);
>> +
>> +	if (event->header.type >= PERF_RECORD_USER_TYPE_START)
>> +		return perf_session__process_user_event(session, event, tool,
>> +							0);
>> +
>> +	return perf_session_deliver_event(session, event, sample, tool, 0);
>> +}
>> +
>>   static void event_swap(union perf_event *event, bool sample_id_all)
>>   {
>>   	perf_event__swap_op swap;
>> diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h
>> index 39327ca..86f1bb4 100644
>> --- a/tools/perf/util/session.h
>> +++ b/tools/perf/util/session.h
>> @@ -130,6 +130,11 @@ extern volatile int session_done;
>>
>>   #define session_done()	(*(volatile int *)(&session_done))
>>
>> +int perf_session__deliver_synth_event(struct perf_session *session,
>> +				      union perf_event *event,
>> +				      struct perf_sample *sample,
>> +				      struct perf_tool *tool);
>> +
>>   int perf_event__process_id_index(struct perf_tool *tool,
>>   				 union perf_event *event,
>>   				 struct perf_session *session);
>> --
>> 1.8.3.2

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

* Re: [PATCH 02/41] perf tools: Fix map groups of threads with unknown pids
  2014-07-15 11:33     ` Adrian Hunter
@ 2014-07-15 19:33       ` Arnaldo Carvalho de Melo
  2014-07-16  8:07         ` [PATCH V2 " Adrian Hunter
  0 siblings, 1 reply; 122+ messages in thread
From: Arnaldo Carvalho de Melo @ 2014-07-15 19:33 UTC (permalink / raw)
  To: Adrian Hunter
  Cc: Peter Zijlstra, linux-kernel, David Ahern, Frederic Weisbecker,
	Jiri Olsa, Namhyung Kim, Paul Mackerras, Stephane Eranian

Em Tue, Jul 15, 2014 at 02:33:01PM +0300, Adrian Hunter escreveu:
> On 07/14/2014 11:18 PM, Arnaldo Carvalho de Melo wrote:
> > Because there is nothing in this function (thread__join_map_groups),
> > checking if it is operating on a thread that has an unknown pid.

> > So, please consider merging this and its sole caller,
> > machine__update_thread_pid, so that the test is in the same function as
> > the assumption that it is operating on a thread with an unknown pid.

> You have it in your tree now.  Do you want another patch
> to do that?

Sorry, ended up push it together with the rest, fixed up now, removed it
and added some more from your kit, please work from there.

Let me know if you find any problem with the merge process so far.

Thanks,

- Arnaldo

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

* Re: [PATCH 15/41] perf script: Improve srcline display for BTS
  2014-07-15 14:16   ` Arnaldo Carvalho de Melo
  2014-07-15 17:51     ` Adrian Hunter
@ 2014-07-16  2:08     ` David Ahern
  1 sibling, 0 replies; 122+ messages in thread
From: David Ahern @ 2014-07-16  2:08 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo, Adrian Hunter, Stephane Eranian
  Cc: Peter Zijlstra, linux-kernel, Frederic Weisbecker, Jiri Olsa,
	Namhyung Kim, Paul Mackerras



On 07/15/2014 08:16 AM, Arnaldo Carvalho de Melo wrote:
> Em Mon, Jul 14, 2014 at 01:02:39PM +0300, Adrian Hunter escreveu:
>> Change the order of the output to put the srcline last.
>> e.g. old format:
>>
>>            4028fc main+0x2c (/bin/ls)
>>    /build/buildd/coreutils-8.20/src/ls.c:1269 =>           40d8a0 set_program_name+0x0 (/bin/ls)
>>
>> new format:
>>
>>            4028fc main+0x2c (/bin/ls) =>           40d8a0 set_program_name+0x0 (/bin/ls)
>>    /build/buildd/coreutils-8.20/src/ls.c:1269
>
> David,
>
> 	Can I have your acked-by?

I believe Stephane is the one who wrote print_sample_bts and bts 
analysis pieces.

David

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

* [PATCH V2 0/2] perf tools: Allow deletion of a thread with no map groups
  2014-07-14 20:43   ` Arnaldo Carvalho de Melo
@ 2014-07-16  7:19     ` Adrian Hunter
  2014-07-16  7:19       ` [PATCH 1/2] " Adrian Hunter
  2014-07-16  7:19       ` [PATCH V2 2/2] perf tools: Fix leak of 'struct thread' on error path Adrian Hunter
  0 siblings, 2 replies; 122+ messages in thread
From: Adrian Hunter @ 2014-07-16  7:19 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Peter Zijlstra, David Ahern, Frederic Weisbecker, Jiri Olsa,
	Namhyung Kim, Paul Mackerras, Stephane Eranian, linux-kernel

Hi

Here is the patch split in two.

Regards
Adrian

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

* [PATCH 1/2] perf tools: Allow deletion of a thread with no map groups
  2014-07-16  7:19     ` [PATCH V2 0/2] perf tools: Allow deletion of a thread with no map groups Adrian Hunter
@ 2014-07-16  7:19       ` Adrian Hunter
  2014-07-18  4:27         ` [tip:perf/core] perf thread: " tip-bot for Adrian Hunter
  2014-07-16  7:19       ` [PATCH V2 2/2] perf tools: Fix leak of 'struct thread' on error path Adrian Hunter
  1 sibling, 1 reply; 122+ messages in thread
From: Adrian Hunter @ 2014-07-16  7:19 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Peter Zijlstra, David Ahern, Frederic Weisbecker, Jiri Olsa,
	Namhyung Kim, Paul Mackerras, Stephane Eranian, linux-kernel

It needs to be possible to call thread__delete() on
a thread with no map groups.  This is needed for
a subsequent patch which deletes a thread on the
error path before map groups have been attached.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
 tools/perf/util/thread.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c
index 7a32f44..b9c36ef 100644
--- a/tools/perf/util/thread.c
+++ b/tools/perf/util/thread.c
@@ -60,8 +60,10 @@ void thread__delete(struct thread *thread)
 {
 	struct comm *comm, *tmp;
 
-	map_groups__put(thread->mg);
-	thread->mg = NULL;
+	if (thread->mg) {
+		map_groups__put(thread->mg);
+		thread->mg = NULL;
+	}
 	list_for_each_entry_safe(comm, tmp, &thread->comm_list, list) {
 		list_del(&comm->list);
 		comm__free(comm);
-- 
1.8.3.2


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

* [PATCH V2 2/2] perf tools: Fix leak of 'struct thread' on error path
  2014-07-16  7:19     ` [PATCH V2 0/2] perf tools: Allow deletion of a thread with no map groups Adrian Hunter
  2014-07-16  7:19       ` [PATCH 1/2] " Adrian Hunter
@ 2014-07-16  7:19       ` Adrian Hunter
  2014-07-18  4:27         ` [tip:perf/core] perf machine: " tip-bot for Adrian Hunter
  1 sibling, 1 reply; 122+ messages in thread
From: Adrian Hunter @ 2014-07-16  7:19 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Peter Zijlstra, David Ahern, Frederic Weisbecker, Jiri Olsa,
	Namhyung Kim, Paul Mackerras, Stephane Eranian, linux-kernel

__machine__findnew_thread() creates a 'struct thread'
but does not free it on the error path.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
 tools/perf/util/machine.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index 5b80877..b75af25 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -325,8 +325,10 @@ static struct thread *__machine__findnew_thread(struct machine *machine,
 		 * within thread__init_map_groups to find the thread
 		 * leader and that would screwed the rb tree.
 		 */
-		if (thread__init_map_groups(th, machine))
+		if (thread__init_map_groups(th, machine)) {
+			thread__delete(th);
 			return NULL;
+		}
 	}
 
 	return th;
-- 
1.8.3.2


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

* [PATCH V2 02/41] perf tools: Fix map groups of threads with unknown pids
  2014-07-15 19:33       ` Arnaldo Carvalho de Melo
@ 2014-07-16  8:07         ` Adrian Hunter
  2014-07-18  4:26           ` [tip:perf/core] perf machine: " tip-bot for Adrian Hunter
  0 siblings, 1 reply; 122+ messages in thread
From: Adrian Hunter @ 2014-07-16  8:07 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Peter Zijlstra, David Ahern, Frederic Weisbecker, Jiri Olsa,
	Namhyung Kim, Paul Mackerras, Stephane Eranian, linux-kernel

Events like sched_switch do not provide a pid (tgid)
which can result in threads with an unknown pid.  If
the pid is later discovered, join the map groups.
Note the thread's map groups should be empty because
they are populated by MMAP events which do provide the
pid and tid.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
 tools/perf/util/machine.c | 57 ++++++++++++++++++++++++++++++++++++++++++-----
 tools/perf/util/map.c     | 14 ++++++++++++
 tools/perf/util/map.h     |  1 +
 3 files changed, 66 insertions(+), 6 deletions(-)

diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index b75af25..93c8b6f 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -272,6 +272,52 @@ void machines__set_id_hdr_size(struct machines *machines, u16 id_hdr_size)
 	return;
 }
 
+static void machine__update_thread_pid(struct machine *machine,
+				       struct thread *th, pid_t pid)
+{
+	struct thread *leader;
+
+	if (pid == th->pid_ || pid == -1 || th->pid_ != -1)
+		return;
+
+	th->pid_ = pid;
+
+	if (th->pid_ == th->tid)
+		return;
+
+	leader = machine__findnew_thread(machine, th->pid_, th->pid_);
+	if (!leader)
+		goto out_err;
+
+	if (!leader->mg)
+		leader->mg = map_groups__new();
+
+	if (!leader->mg)
+		goto out_err;
+
+	if (th->mg == leader->mg)
+		return;
+
+	if (th->mg) {
+		/*
+		 * Maps are created from MMAP events which provide the pid and
+		 * tid.  Consequently there never should be any maps on a thread
+		 * with an unknown pid.  Just print an error if there are.
+		 */
+		if (!map_groups__empty(th->mg))
+			pr_err("Discarding thread maps for %d:%d\n",
+			       th->pid_, th->tid);
+		map_groups__delete(th->mg);
+	}
+
+	th->mg = map_groups__get(leader->mg);
+
+	return;
+
+out_err:
+	pr_err("Failed to join map groups for %d:%d\n", th->pid_, th->tid);
+}
+
 static struct thread *__machine__findnew_thread(struct machine *machine,
 						pid_t pid, pid_t tid,
 						bool create)
@@ -285,10 +331,10 @@ static struct thread *__machine__findnew_thread(struct machine *machine,
 	 * so most of the time we dont have to look up
 	 * the full rbtree:
 	 */
-	if (machine->last_match && machine->last_match->tid == tid) {
-		if (pid != -1 && pid != machine->last_match->pid_)
-			machine->last_match->pid_ = pid;
-		return machine->last_match;
+	th = machine->last_match;
+	if (th && th->tid == tid) {
+		machine__update_thread_pid(machine, th, pid);
+		return th;
 	}
 
 	while (*p != NULL) {
@@ -297,8 +343,7 @@ static struct thread *__machine__findnew_thread(struct machine *machine,
 
 		if (th->tid == tid) {
 			machine->last_match = th;
-			if (pid != -1 && pid != th->pid_)
-				th->pid_ = pid;
+			machine__update_thread_pid(machine, th, pid);
 			return th;
 		}
 
diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c
index 25c571f..7af1480 100644
--- a/tools/perf/util/map.c
+++ b/tools/perf/util/map.c
@@ -454,6 +454,20 @@ void map_groups__exit(struct map_groups *mg)
 	}
 }
 
+bool map_groups__empty(struct map_groups *mg)
+{
+	int i;
+
+	for (i = 0; i < MAP__NR_TYPES; ++i) {
+		if (maps__first(&mg->maps[i]))
+			return false;
+		if (!list_empty(&mg->removed_maps[i]))
+			return false;
+	}
+
+	return true;
+}
+
 struct map_groups *map_groups__new(void)
 {
 	struct map_groups *mg = malloc(sizeof(*mg));
diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h
index 7758c72..5806a90 100644
--- a/tools/perf/util/map.h
+++ b/tools/perf/util/map.h
@@ -66,6 +66,7 @@ struct map_groups {
 
 struct map_groups *map_groups__new(void);
 void map_groups__delete(struct map_groups *mg);
+bool map_groups__empty(struct map_groups *mg);
 
 static inline struct map_groups *map_groups__get(struct map_groups *mg)
 {
-- 
1.8.3.2


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

* Re: [PATCH 12/41] perf tools: Fix leak of 'struct thread' on error path
  2014-07-14 10:02 ` [PATCH 12/41] perf tools: Fix leak of 'struct thread' on error path Adrian Hunter
  2014-07-14 20:43   ` Arnaldo Carvalho de Melo
@ 2014-07-16 14:02   ` Jiri Olsa
  2014-07-16 14:26     ` Adrian Hunter
  1 sibling, 1 reply; 122+ messages in thread
From: Jiri Olsa @ 2014-07-16 14:02 UTC (permalink / raw)
  To: Adrian Hunter
  Cc: Arnaldo Carvalho de Melo, Peter Zijlstra, linux-kernel,
	David Ahern, Frederic Weisbecker, Namhyung Kim, Paul Mackerras,
	Stephane Eranian

On Mon, Jul 14, 2014 at 01:02:36PM +0300, Adrian Hunter wrote:
> __machine__findnew_thread() creates a 'struct thread'
> but does not free it on the error path.
> 
> Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
> ---
>  tools/perf/util/machine.c | 4 +++-
>  tools/perf/util/thread.c  | 6 ++++--
>  2 files changed, 7 insertions(+), 3 deletions(-)
> 
> diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
> index c1c5ca3..18eaf31 100644
> --- a/tools/perf/util/machine.c
> +++ b/tools/perf/util/machine.c
> @@ -349,8 +349,10 @@ static struct thread *__machine__findnew_thread(struct machine *machine,
>  		 * within thread__init_map_groups to find the thread
>  		 * leader and that would screwed the rb tree.
>  		 */
> -		if (thread__init_map_groups(th, machine))
> +		if (thread__init_map_groups(th, machine)) {
> +			thread__delete(th);
>  			return NULL;
> +		}
>  	}
>  
>  	return th;
> diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c
> index 149e417..b9a3ee4 100644
> --- a/tools/perf/util/thread.c
> +++ b/tools/perf/util/thread.c
> @@ -95,8 +95,10 @@ void thread__delete(struct thread *thread)
>  {
>  	struct comm *comm, *tmp;
>  
> -	map_groups__put(thread->mg);
> -	thread->mg = NULL;
> +	if (thread->mg) {
> +		map_groups__put(thread->mg);
> +		thread->mg = NULL;
> +	}

I dont think this is ^^^ needed..  each thread has ->mg defined

jirka

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

* Re: [PATCH 13/41] perf tools: Add machine__kernel_ip()
  2014-07-14 10:02 ` [PATCH 13/41] perf tools: Add machine__kernel_ip() Adrian Hunter
@ 2014-07-16 14:15   ` Jiri Olsa
  2014-07-16 14:22     ` Adrian Hunter
  0 siblings, 1 reply; 122+ messages in thread
From: Jiri Olsa @ 2014-07-16 14:15 UTC (permalink / raw)
  To: Adrian Hunter
  Cc: Arnaldo Carvalho de Melo, Peter Zijlstra, linux-kernel,
	David Ahern, Frederic Weisbecker, Namhyung Kim, Paul Mackerras,
	Stephane Eranian

On Mon, Jul 14, 2014 at 01:02:37PM +0300, Adrian Hunter wrote:

SNIP

> +
> +int machine__get_kernel_start(struct machine *machine)
> +{
> +	struct map *map = machine__kernel_map(machine, MAP__FUNCTION);
> +	int err = 0;
> +
> +	/*
> +	 * The only addresses above 2^63 are kernel addresses of a 64-bit
> +	 * kernel.  Note that addresses are unsigned so that on a 32-bit system
> +	 * all addresses including kernel addresses are less than 2^32.  In
> +	 * that case (32-bit system), if the kernel mapping is unknown, all
> +	 * addresses will be assumed to be in user space - see
> +	 * machine__kernel_ip().
> +	 */
> +	machine->kernel_start = 1ULL << 63;
> +	if (map) {
> +		err = map__load(map, machine->symbol_filter);
> +		if (map->start)
> +			machine->kernel_start = map->start;
> +	}
> +	return err;
> +}

we just recently got machine__get_kernel_start_addr function,
I think we want just one function for this

jirka

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

* Re: [PATCH 18/41] perf tools: Record whether a dso has data
  2014-07-14 10:02 ` [PATCH 18/41] perf tools: Record whether a dso has data Adrian Hunter
@ 2014-07-16 14:20   ` Jiri Olsa
  2014-07-17  8:43     ` [PATCH 0/2] perf tools: Fix incorrect fd error comparison Adrian Hunter
  0 siblings, 1 reply; 122+ messages in thread
From: Jiri Olsa @ 2014-07-16 14:20 UTC (permalink / raw)
  To: Adrian Hunter
  Cc: Arnaldo Carvalho de Melo, Peter Zijlstra, linux-kernel,
	David Ahern, Frederic Weisbecker, Namhyung Kim, Paul Mackerras,
	Stephane Eranian

On Mon, Jul 14, 2014 at 01:02:42PM +0300, Adrian Hunter wrote:
> Add 'data_status' to record whether a dso has data
> (i.e. an object file) as follows:
> 
> 	dso->data_status	meaning
> 	----------------------------------
> 	0			don't know
> 	-1			no data
> 	1			has data

please add enum for this

> 
> Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
> ---
>  tools/perf/util/dso.c | 5 ++++-
>  tools/perf/util/dso.h | 1 +
>  2 files changed, 5 insertions(+), 1 deletion(-)
> 
> diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c
> index fc006fe..91a4eb4 100644
> --- a/tools/perf/util/dso.c
> +++ b/tools/perf/util/dso.c
> @@ -556,8 +556,11 @@ static ssize_t data_read_offset(struct dso *dso, u64 offset,
>  ssize_t dso__data_read_offset(struct dso *dso, struct machine *machine,
>  			      u64 offset, u8 *data, ssize_t size)
>  {
> -	if (dso__data_fd(dso, machine) < 0)
> +	if (dso__data_fd(dso, machine) < 0) {
> +		dso->data.data_status = -1;
>  		return -1;
> +	}
> +	dso->data.data_status = 1;

we have more callers to dso__data_fd, so I think we want
to setup dso->data.data_status within dso__data_fd

jirka

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

* Re: [PATCH 13/41] perf tools: Add machine__kernel_ip()
  2014-07-16 14:15   ` Jiri Olsa
@ 2014-07-16 14:22     ` Adrian Hunter
  2014-08-11 12:23       ` Jiri Olsa
  0 siblings, 1 reply; 122+ messages in thread
From: Adrian Hunter @ 2014-07-16 14:22 UTC (permalink / raw)
  To: Jiri Olsa
  Cc: Arnaldo Carvalho de Melo, Peter Zijlstra, linux-kernel,
	David Ahern, Frederic Weisbecker, Namhyung Kim, Paul Mackerras,
	Stephane Eranian

On 16/07/2014 5:15 p.m., Jiri Olsa wrote:
> On Mon, Jul 14, 2014 at 01:02:37PM +0300, Adrian Hunter wrote:
>
> SNIP
>
>> +
>> +int machine__get_kernel_start(struct machine *machine)
>> +{
>> +	struct map *map = machine__kernel_map(machine, MAP__FUNCTION);
>> +	int err = 0;
>> +
>> +	/*
>> +	 * The only addresses above 2^63 are kernel addresses of a 64-bit
>> +	 * kernel.  Note that addresses are unsigned so that on a 32-bit system
>> +	 * all addresses including kernel addresses are less than 2^32.  In
>> +	 * that case (32-bit system), if the kernel mapping is unknown, all
>> +	 * addresses will be assumed to be in user space - see
>> +	 * machine__kernel_ip().
>> +	 */
>> +	machine->kernel_start = 1ULL << 63;
>> +	if (map) {
>> +		err = map__load(map, machine->symbol_filter);
>> +		if (map->start)
>> +			machine->kernel_start = map->start;
>> +	}
>> +	return err;
>> +}
>
> we just recently got machine__get_kernel_start_addr function,
> I think we want just one function for this

They do quite different things.


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

* Re: [PATCH 20/41] perf tools: Let a user specify a PMU event without any config terms
  2014-07-14 10:02 ` [PATCH 20/41] perf tools: Let a user specify a PMU event without any config terms Adrian Hunter
@ 2014-07-16 14:25   ` Jiri Olsa
  2014-07-16 15:04     ` Adrian Hunter
  0 siblings, 1 reply; 122+ messages in thread
From: Jiri Olsa @ 2014-07-16 14:25 UTC (permalink / raw)
  To: Adrian Hunter
  Cc: Arnaldo Carvalho de Melo, Peter Zijlstra, linux-kernel,
	David Ahern, Frederic Weisbecker, Namhyung Kim, Paul Mackerras,
	Stephane Eranian

On Mon, Jul 14, 2014 at 01:02:44PM +0300, Adrian Hunter wrote:
> This enables a PMU event to be specified in the form:
> 
> 	pmu//
> 
> which is effectively the same as:
> 
> 	pmu/config=0/
> 
> This patch is a precursor to defining
> default config for a PMU.

I understand the need for default config, but could you please elaborate
why do we want to parse 'pmu//' as an event string string?

thanks,
jirka

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

* Re: [PATCH 12/41] perf tools: Fix leak of 'struct thread' on error path
  2014-07-16 14:02   ` [PATCH 12/41] perf tools: " Jiri Olsa
@ 2014-07-16 14:26     ` Adrian Hunter
  0 siblings, 0 replies; 122+ messages in thread
From: Adrian Hunter @ 2014-07-16 14:26 UTC (permalink / raw)
  To: Jiri Olsa
  Cc: Arnaldo Carvalho de Melo, Peter Zijlstra, linux-kernel,
	David Ahern, Frederic Weisbecker, Namhyung Kim, Paul Mackerras,
	Stephane Eranian

On 16/07/2014 5:02 p.m., Jiri Olsa wrote:
> On Mon, Jul 14, 2014 at 01:02:36PM +0300, Adrian Hunter wrote:
>> __machine__findnew_thread() creates a 'struct thread'
>> but does not free it on the error path.
>>
>> Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
>> ---
>>   tools/perf/util/machine.c | 4 +++-
>>   tools/perf/util/thread.c  | 6 ++++--
>>   2 files changed, 7 insertions(+), 3 deletions(-)
>>
>> diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
>> index c1c5ca3..18eaf31 100644
>> --- a/tools/perf/util/machine.c
>> +++ b/tools/perf/util/machine.c
>> @@ -349,8 +349,10 @@ static struct thread *__machine__findnew_thread(struct machine *machine,
>>   		 * within thread__init_map_groups to find the thread
>>   		 * leader and that would screwed the rb tree.
>>   		 */
>> -		if (thread__init_map_groups(th, machine))
>> +		if (thread__init_map_groups(th, machine)) {
>> +			thread__delete(th);
>>   			return NULL;
>> +		}
>>   	}
>>
>>   	return th;
>> diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c
>> index 149e417..b9a3ee4 100644
>> --- a/tools/perf/util/thread.c
>> +++ b/tools/perf/util/thread.c
>> @@ -95,8 +95,10 @@ void thread__delete(struct thread *thread)
>>   {
>>   	struct comm *comm, *tmp;
>>
>> -	map_groups__put(thread->mg);
>> -	thread->mg = NULL;
>> +	if (thread->mg) {
>> +		map_groups__put(thread->mg);
>> +		thread->mg = NULL;
>> +	}
>
> I dont think this is ^^^ needed..  each thread has ->mg defined

On the error path the thread does not yet have an mg.

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

* Re: [PATCH 20/41] perf tools: Let a user specify a PMU event without any config terms
  2014-07-16 14:25   ` Jiri Olsa
@ 2014-07-16 15:04     ` Adrian Hunter
  2014-07-16 18:22       ` Jiri Olsa
  0 siblings, 1 reply; 122+ messages in thread
From: Adrian Hunter @ 2014-07-16 15:04 UTC (permalink / raw)
  To: Jiri Olsa
  Cc: Arnaldo Carvalho de Melo, Peter Zijlstra, linux-kernel,
	David Ahern, Frederic Weisbecker, Namhyung Kim, Paul Mackerras,
	Stephane Eranian

On 16/07/2014 5:25 p.m., Jiri Olsa wrote:
> On Mon, Jul 14, 2014 at 01:02:44PM +0300, Adrian Hunter wrote:
>> This enables a PMU event to be specified in the form:
>>
>> 	pmu//
>>
>> which is effectively the same as:
>>
>> 	pmu/config=0/
>>
>> This patch is a precursor to defining
>> default config for a PMU.
>
> I understand the need for default config, but could you please elaborate
> why do we want to parse 'pmu//' as an event string string?

Currently the parser requires the slashes to identify a PMU event
as opposed to a hardware or other kind of event.

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

* Re: [PATCH 20/41] perf tools: Let a user specify a PMU event without any config terms
  2014-07-16 15:04     ` Adrian Hunter
@ 2014-07-16 18:22       ` Jiri Olsa
  2014-08-29 18:48         ` Adrian Hunter
  0 siblings, 1 reply; 122+ messages in thread
From: Jiri Olsa @ 2014-07-16 18:22 UTC (permalink / raw)
  To: Adrian Hunter
  Cc: Arnaldo Carvalho de Melo, Peter Zijlstra, linux-kernel,
	David Ahern, Frederic Weisbecker, Namhyung Kim, Paul Mackerras,
	Stephane Eranian

On Wed, Jul 16, 2014 at 06:04:44PM +0300, Adrian Hunter wrote:
> On 16/07/2014 5:25 p.m., Jiri Olsa wrote:
> >On Mon, Jul 14, 2014 at 01:02:44PM +0300, Adrian Hunter wrote:
> >>This enables a PMU event to be specified in the form:
> >>
> >>	pmu//
> >>
> >>which is effectively the same as:
> >>
> >>	pmu/config=0/
> >>
> >>This patch is a precursor to defining
> >>default config for a PMU.
> >
> >I understand the need for default config, but could you please elaborate
> >why do we want to parse 'pmu//' as an event string string?
> 
> Currently the parser requires the slashes to identify a PMU event
> as opposed to a hardware or other kind of event.

right, so why do we want to parse 'pmu//' as an event string? ;-)

jirka

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

* [PATCH 0/2] perf tools: Fix incorrect fd error comparison
  2014-07-16 14:20   ` Jiri Olsa
@ 2014-07-17  8:43     ` Adrian Hunter
  2014-07-17  8:43       ` [PATCH 1/2] " Adrian Hunter
  2014-07-17  8:43       ` [PATCH V2 2/2] perf tools: Record whether a dso has data Adrian Hunter
  0 siblings, 2 replies; 122+ messages in thread
From: Adrian Hunter @ 2014-07-17  8:43 UTC (permalink / raw)
  To: Jiri Olsa
  Cc: Arnaldo Carvalho de Melo, Peter Zijlstra, David Ahern,
	Frederic Weisbecker, Namhyung Kim, Paul Mackerras,
	Stephane Eranian, linux-kernel

On 07/16/2014 05:20 PM, Jiri Olsa wrote:> On Mon, Jul 14, 2014 at 01:02:42PM +0300, Adrian Hunter wrote:
>> Add 'data_status' to record whether a dso has data
>> (i.e. an object file) as follows:
>>
>> 	dso->data_status	meaning
>> 	----------------------------------
>> 	0			don't know
>> 	-1			no data
>> 	1			has data
> 
> please add enum for this

Ok

> 
>>
>> Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
>> ---
>>  tools/perf/util/dso.c | 5 ++++-
>>  tools/perf/util/dso.h | 1 +
>>  2 files changed, 5 insertions(+), 1 deletion(-)
>>
>> diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c
>> index fc006fe..91a4eb4 100644
>> --- a/tools/perf/util/dso.c
>> +++ b/tools/perf/util/dso.c
>> @@ -556,8 +556,11 @@ static ssize_t data_read_offset(struct dso *dso, u64 offset,
>>  ssize_t dso__data_read_offset(struct dso *dso, struct machine *machine,
>>  			      u64 offset, u8 *data, ssize_t size)
>>  {
>> -	if (dso__data_fd(dso, machine) < 0)
>> +	if (dso__data_fd(dso, machine) < 0) {
>> +		dso->data.data_status = -1;
>>  		return -1;
>> +	}
>> +	dso->data.data_status = 1;
> 
> we have more callers to dso__data_fd, so I think we want
> to setup dso->data.data_status within dso__data_fd

Ok.  Here are 2 patches because I noticed another thing.

Adrian Hunter (2):
      perf tools: Fix incorrect fd error comparison
      perf tools: Record whether a dso has data

 tools/perf/util/dso.c | 27 +++++++++++++++++----------
 tools/perf/util/dso.h |  7 +++++++
 2 files changed, 24 insertions(+), 10 deletions(-)

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

* [PATCH 1/2] perf tools: Fix incorrect fd error comparison
  2014-07-17  8:43     ` [PATCH 0/2] perf tools: Fix incorrect fd error comparison Adrian Hunter
@ 2014-07-17  8:43       ` Adrian Hunter
  2014-07-22  7:51         ` Jiri Olsa
  2014-07-28  8:21         ` [tip:perf/core] " tip-bot for Adrian Hunter
  2014-07-17  8:43       ` [PATCH V2 2/2] perf tools: Record whether a dso has data Adrian Hunter
  1 sibling, 2 replies; 122+ messages in thread
From: Adrian Hunter @ 2014-07-17  8:43 UTC (permalink / raw)
  To: Jiri Olsa
  Cc: Arnaldo Carvalho de Melo, Peter Zijlstra, David Ahern,
	Frederic Weisbecker, Namhyung Kim, Paul Mackerras,
	Stephane Eranian, linux-kernel

Zero is a valid fd.  Error comparison should check
for negative fd.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
 tools/perf/util/dso.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c
index fc006fe..28cf747 100644
--- a/tools/perf/util/dso.c
+++ b/tools/perf/util/dso.c
@@ -216,7 +216,7 @@ static int open_dso(struct dso *dso, struct machine *machine)
 {
 	int fd = __open_dso(dso, machine);
 
-	if (fd > 0) {
+	if (fd >= 0) {
 		dso__list_add(dso);
 		/*
 		 * Check if we crossed the allowed number
-- 
1.8.3.2


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

* [PATCH V2 2/2] perf tools: Record whether a dso has data
  2014-07-17  8:43     ` [PATCH 0/2] perf tools: Fix incorrect fd error comparison Adrian Hunter
  2014-07-17  8:43       ` [PATCH 1/2] " Adrian Hunter
@ 2014-07-17  8:43       ` Adrian Hunter
  2014-07-17  8:58         ` [PATCH V3] " Adrian Hunter
  1 sibling, 1 reply; 122+ messages in thread
From: Adrian Hunter @ 2014-07-17  8:43 UTC (permalink / raw)
  To: Jiri Olsa
  Cc: Arnaldo Carvalho de Melo, Peter Zijlstra, David Ahern,
	Frederic Weisbecker, Namhyung Kim, Paul Mackerras,
	Stephane Eranian, linux-kernel

Add 'data_status' to record whether a dso has data
(i.e. an object file) as follows:

	dso->data_status	meaning
	----------------------------------
	0			don't know
	-1			no data
	1			has data

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
 tools/perf/util/dso.c | 25 ++++++++++++++++---------
 tools/perf/util/dso.h |  7 +++++++
 2 files changed, 23 insertions(+), 9 deletions(-)

diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c
index 28cf747..af274f0 100644
--- a/tools/perf/util/dso.c
+++ b/tools/perf/util/dso.c
@@ -332,25 +332,28 @@ int dso__data_fd(struct dso *dso, struct machine *machine)
 	int i = 0;
 
 	if (dso->data.fd >= 0)
-		return dso->data.fd;
+		goto out;
 
 	if (dso->binary_type != DSO_BINARY_TYPE__NOT_FOUND) {
 		dso->data.fd = open_dso(dso, machine);
-		return dso->data.fd;
+		goto out;
 	}
 
 	do {
-		int fd;
-
 		dso->binary_type = binary_type_data[i++];
 
-		fd = open_dso(dso, machine);
-		if (fd >= 0)
-			return dso->data.fd = fd;
+		dso->data.fd = open_dso(dso, machine);
+		if (dso->data.fd >= 0)
+			goto out;
 
 	} while (dso->binary_type != DSO_BINARY_TYPE__NOT_FOUND);
+out:
+	if (dso->data.fd >= 0)
+		dso->data.data_status = DSO_DATA_STATUS_OK;
+	else
+		dso->data.data_status = DSO_DATA_STATUS_ERROR;
 
-	return -EINVAL;
+	return dso->data.fd;
 }
 
 static void
@@ -556,8 +559,11 @@ static ssize_t data_read_offset(struct dso *dso, u64 offset,
 ssize_t dso__data_read_offset(struct dso *dso, struct machine *machine,
 			      u64 offset, u8 *data, ssize_t size)
 {
-	if (dso__data_fd(dso, machine) < 0)
+	if (dso__data_fd(dso, machine) < 0) {
+		dso->data.data_status = -1;
 		return -1;
+	}
+	dso->data.data_status = 1;
 
 	return data_read_offset(dso, offset, data, size);
 }
@@ -701,6 +707,7 @@ struct dso *dso__new(const char *name)
 			dso->symbols[i] = dso->symbol_names[i] = RB_ROOT;
 		dso->data.cache = RB_ROOT;
 		dso->data.fd = -1;
+		dso->data.data_status = DSO_DATA_STATUS_UNKNOWN;
 		dso->symtab_type = DSO_BINARY_TYPE__NOT_FOUND;
 		dso->binary_type = DSO_BINARY_TYPE__NOT_FOUND;
 		dso->is_64_bit = (sizeof(void *) == 8);
diff --git a/tools/perf/util/dso.h b/tools/perf/util/dso.h
index c239e86..07d0a58 100644
--- a/tools/perf/util/dso.h
+++ b/tools/perf/util/dso.h
@@ -40,6 +40,12 @@ enum dso_swap_type {
 	DSO_SWAP__YES,
 };
 
+enum dso_data_status {
+	DSO_DATA_STATUS_ERROR	= -1,
+	DSO_DATA_STATUS_UNKNOWN	= 0,
+	DSO_DATA_STATUS_OK	= 1,
+};
+
 #define DSO__SWAP(dso, type, val)			\
 ({							\
 	type ____r = val;				\
@@ -104,6 +110,7 @@ struct dso {
 	struct {
 		struct rb_root	 cache;
 		int		 fd;
+		int		 data_status;
 		size_t		 file_size;
 		struct list_head open_entry;
 	} data;
-- 
1.8.3.2


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

* [PATCH V3] perf tools: Record whether a dso has data
  2014-07-17  8:43       ` [PATCH V2 2/2] perf tools: Record whether a dso has data Adrian Hunter
@ 2014-07-17  8:58         ` Adrian Hunter
  2014-07-22  7:55           ` Jiri Olsa
  0 siblings, 1 reply; 122+ messages in thread
From: Adrian Hunter @ 2014-07-17  8:58 UTC (permalink / raw)
  To: Jiri Olsa
  Cc: Arnaldo Carvalho de Melo, Peter Zijlstra, David Ahern,
	Frederic Weisbecker, Namhyung Kim, Paul Mackerras,
	Stephane Eranian, linux-kernel

Add 'data_status' to record whether a dso has data
(i.e. an object file)

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
 tools/perf/util/dso.c | 20 ++++++++++++--------
 tools/perf/util/dso.h |  7 +++++++
 2 files changed, 19 insertions(+), 8 deletions(-)

diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c
index 28cf747..08eb028 100644
--- a/tools/perf/util/dso.c
+++ b/tools/perf/util/dso.c
@@ -332,25 +332,28 @@ int dso__data_fd(struct dso *dso, struct machine *machine)
 	int i = 0;
 
 	if (dso->data.fd >= 0)
-		return dso->data.fd;
+		goto out;
 
 	if (dso->binary_type != DSO_BINARY_TYPE__NOT_FOUND) {
 		dso->data.fd = open_dso(dso, machine);
-		return dso->data.fd;
+		goto out;
 	}
 
 	do {
-		int fd;
-
 		dso->binary_type = binary_type_data[i++];
 
-		fd = open_dso(dso, machine);
-		if (fd >= 0)
-			return dso->data.fd = fd;
+		dso->data.fd = open_dso(dso, machine);
+		if (dso->data.fd >= 0)
+			goto out;
 
 	} while (dso->binary_type != DSO_BINARY_TYPE__NOT_FOUND);
+out:
+	if (dso->data.fd >= 0)
+		dso->data.data_status = DSO_DATA_STATUS_OK;
+	else
+		dso->data.data_status = DSO_DATA_STATUS_ERROR;
 
-	return -EINVAL;
+	return dso->data.fd;
 }
 
 static void
@@ -701,6 +704,7 @@ struct dso *dso__new(const char *name)
 			dso->symbols[i] = dso->symbol_names[i] = RB_ROOT;
 		dso->data.cache = RB_ROOT;
 		dso->data.fd = -1;
+		dso->data.data_status = DSO_DATA_STATUS_UNKNOWN;
 		dso->symtab_type = DSO_BINARY_TYPE__NOT_FOUND;
 		dso->binary_type = DSO_BINARY_TYPE__NOT_FOUND;
 		dso->is_64_bit = (sizeof(void *) == 8);
diff --git a/tools/perf/util/dso.h b/tools/perf/util/dso.h
index c239e86..07d0a58 100644
--- a/tools/perf/util/dso.h
+++ b/tools/perf/util/dso.h
@@ -40,6 +40,12 @@ enum dso_swap_type {
 	DSO_SWAP__YES,
 };
 
+enum dso_data_status {
+	DSO_DATA_STATUS_ERROR	= -1,
+	DSO_DATA_STATUS_UNKNOWN	= 0,
+	DSO_DATA_STATUS_OK	= 1,
+};
+
 #define DSO__SWAP(dso, type, val)			\
 ({							\
 	type ____r = val;				\
@@ -104,6 +110,7 @@ struct dso {
 	struct {
 		struct rb_root	 cache;
 		int		 fd;
+		int		 data_status;
 		size_t		 file_size;
 		struct list_head open_entry;
 	} data;
-- 
1.8.3.2


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

* [tip:perf/core] perf machine: Fix the value used for unknown pids
  2014-07-14 10:02 ` [PATCH 01/41] perf tools: Fix the value used for unknown pids Adrian Hunter
@ 2014-07-18  4:23   ` tip-bot for Adrian Hunter
  0 siblings, 0 replies; 122+ messages in thread
From: tip-bot for Adrian Hunter @ 2014-07-18  4:23 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: acme, linux-kernel, eranian, paulus, hpa, mingo, peterz,
	namhyung, jolsa, fweisbec, adrian.hunter, dsahern, tglx

Commit-ID:  1fcb8768636d38cb6fdfeef83a5ee596c4bd9c56
Gitweb:     http://git.kernel.org/tip/1fcb8768636d38cb6fdfeef83a5ee596c4bd9c56
Author:     Adrian Hunter <adrian.hunter@intel.com>
AuthorDate: Mon, 14 Jul 2014 13:02:25 +0300
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Wed, 16 Jul 2014 17:57:33 -0300

perf machine: Fix the value used for unknown pids

The value used for unknown pids cannot be zero because that is used by
the "idle" task.

Use -1 instead.  Also handle the unknown pid case when creating map
groups.

Note that, threads with an unknown pid should not occur because fork (or
synthesized) events precede the thread's existence.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/r/1405332185-4050-2-git-send-email-adrian.hunter@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/builtin-sched.c | 12 ++++++------
 tools/perf/util/machine.c  |  6 +++---
 tools/perf/util/session.c  |  5 +++--
 tools/perf/util/thread.c   |  2 +-
 4 files changed, 13 insertions(+), 12 deletions(-)

diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c
index c38d06c..b7f555a 100644
--- a/tools/perf/builtin-sched.c
+++ b/tools/perf/builtin-sched.c
@@ -935,8 +935,8 @@ static int latency_switch_event(struct perf_sched *sched,
 		return -1;
 	}
 
-	sched_out = machine__findnew_thread(machine, 0, prev_pid);
-	sched_in = machine__findnew_thread(machine, 0, next_pid);
+	sched_out = machine__findnew_thread(machine, -1, prev_pid);
+	sched_in = machine__findnew_thread(machine, -1, next_pid);
 
 	out_events = thread_atoms_search(&sched->atom_root, sched_out, &sched->cmp_pid);
 	if (!out_events) {
@@ -979,7 +979,7 @@ static int latency_runtime_event(struct perf_sched *sched,
 {
 	const u32 pid	   = perf_evsel__intval(evsel, sample, "pid");
 	const u64 runtime  = perf_evsel__intval(evsel, sample, "runtime");
-	struct thread *thread = machine__findnew_thread(machine, 0, pid);
+	struct thread *thread = machine__findnew_thread(machine, -1, pid);
 	struct work_atoms *atoms = thread_atoms_search(&sched->atom_root, thread, &sched->cmp_pid);
 	u64 timestamp = sample->time;
 	int cpu = sample->cpu;
@@ -1012,7 +1012,7 @@ static int latency_wakeup_event(struct perf_sched *sched,
 	struct thread *wakee;
 	u64 timestamp = sample->time;
 
-	wakee = machine__findnew_thread(machine, 0, pid);
+	wakee = machine__findnew_thread(machine, -1, pid);
 	atoms = thread_atoms_search(&sched->atom_root, wakee, &sched->cmp_pid);
 	if (!atoms) {
 		if (thread_atoms_insert(sched, wakee))
@@ -1072,7 +1072,7 @@ static int latency_migrate_task_event(struct perf_sched *sched,
 	if (sched->profile_cpu == -1)
 		return 0;
 
-	migrant = machine__findnew_thread(machine, 0, pid);
+	migrant = machine__findnew_thread(machine, -1, pid);
 	atoms = thread_atoms_search(&sched->atom_root, migrant, &sched->cmp_pid);
 	if (!atoms) {
 		if (thread_atoms_insert(sched, migrant))
@@ -1290,7 +1290,7 @@ static int map_switch_event(struct perf_sched *sched, struct perf_evsel *evsel,
 		return -1;
 	}
 
-	sched_in = machine__findnew_thread(machine, 0, next_pid);
+	sched_in = machine__findnew_thread(machine, -1, next_pid);
 
 	sched->curr_thread[this_cpu] = sched_in;
 
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index e9b943a..5b80877 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -34,7 +34,7 @@ int machine__init(struct machine *machine, const char *root_dir, pid_t pid)
 		return -ENOMEM;
 
 	if (pid != HOST_KERNEL_ID) {
-		struct thread *thread = machine__findnew_thread(machine, 0,
+		struct thread *thread = machine__findnew_thread(machine, -1,
 								pid);
 		char comm[64];
 
@@ -286,7 +286,7 @@ static struct thread *__machine__findnew_thread(struct machine *machine,
 	 * the full rbtree:
 	 */
 	if (machine->last_match && machine->last_match->tid == tid) {
-		if (pid && pid != machine->last_match->pid_)
+		if (pid != -1 && pid != machine->last_match->pid_)
 			machine->last_match->pid_ = pid;
 		return machine->last_match;
 	}
@@ -297,7 +297,7 @@ static struct thread *__machine__findnew_thread(struct machine *machine,
 
 		if (th->tid == tid) {
 			machine->last_match = th;
-			if (pid && pid != th->pid_)
+			if (pid != -1 && pid != th->pid_)
 				th->pid_ = pid;
 			return th;
 		}
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 64a186e..c2f4ca9 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -1083,13 +1083,14 @@ void perf_event_header__bswap(struct perf_event_header *hdr)
 
 struct thread *perf_session__findnew(struct perf_session *session, pid_t pid)
 {
-	return machine__findnew_thread(&session->machines.host, 0, pid);
+	return machine__findnew_thread(&session->machines.host, -1, pid);
 }
 
 static struct thread *perf_session__register_idle_thread(struct perf_session *session)
 {
-	struct thread *thread = perf_session__findnew(session, 0);
+	struct thread *thread;
 
+	thread = machine__findnew_thread(&session->machines.host, 0, 0);
 	if (thread == NULL || thread__set_comm(thread, "swapper", 0)) {
 		pr_err("problem inserting idle task.\n");
 		thread = NULL;
diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c
index 2fde0d5..7a32f44 100644
--- a/tools/perf/util/thread.c
+++ b/tools/perf/util/thread.c
@@ -13,7 +13,7 @@ int thread__init_map_groups(struct thread *thread, struct machine *machine)
 	struct thread *leader;
 	pid_t pid = thread->pid_;
 
-	if (pid == thread->tid) {
+	if (pid == thread->tid || pid == -1) {
 		thread->mg = map_groups__new();
 	} else {
 		leader = machine__findnew_thread(machine, pid, pid);

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

* [tip:perf/core] perf script: Display PERF_RECORD_MISC_COMM_EXEC flag
  2014-07-14 10:02 ` [PATCH 03/41] perf script: Display PERF_RECORD_MISC_COMM_EXEC flag Adrian Hunter
@ 2014-07-18  4:23   ` tip-bot for Adrian Hunter
  0 siblings, 0 replies; 122+ messages in thread
From: tip-bot for Adrian Hunter @ 2014-07-18  4:23 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: acme, linux-kernel, eranian, paulus, hpa, mingo, peterz,
	namhyung, jolsa, fweisbec, adrian.hunter, dsahern, tglx

Commit-ID:  022c50d09c2c2bc31506ad16c4bcba7fb418ce34
Gitweb:     http://git.kernel.org/tip/022c50d09c2c2bc31506ad16c4bcba7fb418ce34
Author:     Adrian Hunter <adrian.hunter@intel.com>
AuthorDate: Mon, 14 Jul 2014 13:02:27 +0300
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Wed, 16 Jul 2014 17:57:34 -0300

perf script: Display PERF_RECORD_MISC_COMM_EXEC flag

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/r/1405332185-4050-4-git-send-email-adrian.hunter@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/event.c | 9 ++++++++-
 tools/perf/util/evsel.c | 3 ++-
 2 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index d0281bd..198c4cc 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -603,7 +603,14 @@ int perf_event__synthesize_kernel_mmap(struct perf_tool *tool,
 
 size_t perf_event__fprintf_comm(union perf_event *event, FILE *fp)
 {
-	return fprintf(fp, ": %s:%d\n", event->comm.comm, event->comm.tid);
+	const char *s;
+
+	if (event->header.misc & PERF_RECORD_MISC_COMM_EXEC)
+		s = " exec";
+	else
+		s = "";
+
+	return fprintf(fp, "%s: %s:%d\n", s, event->comm.comm, event->comm.tid);
 }
 
 int perf_event__process_comm(struct perf_tool *tool __maybe_unused,
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 8606175..b760d32 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -960,6 +960,7 @@ static size_t perf_event_attr__fprintf(struct perf_event_attr *attr, FILE *fp)
 	ret += PRINT_ATTR2(exclude_user, exclude_kernel);
 	ret += PRINT_ATTR2(exclude_hv, exclude_idle);
 	ret += PRINT_ATTR2(mmap, comm);
+	ret += PRINT_ATTR2(mmap2, comm_exec);
 	ret += PRINT_ATTR2(freq, inherit_stat);
 	ret += PRINT_ATTR2(enable_on_exec, task);
 	ret += PRINT_ATTR2(watermark, precise_ip);
@@ -967,7 +968,6 @@ static size_t perf_event_attr__fprintf(struct perf_event_attr *attr, FILE *fp)
 	ret += PRINT_ATTR2(exclude_host, exclude_guest);
 	ret += PRINT_ATTR2N("excl.callchain_kern", exclude_callchain_kernel,
 			    "excl.callchain_user", exclude_callchain_user);
-	ret += PRINT_ATTR_U32(mmap2);
 
 	ret += PRINT_ATTR_U32(wakeup_events);
 	ret += PRINT_ATTR_U32(wakeup_watermark);
@@ -1940,6 +1940,7 @@ int perf_evsel__fprintf(struct perf_evsel *evsel,
 		if_print(mmap);
 		if_print(mmap2);
 		if_print(comm);
+		if_print(comm_exec);
 		if_print(freq);
 		if_print(inherit_stat);
 		if_print(enable_on_exec);

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

* [tip:perf/core] perf record: Select comm_exec flag if supported
  2014-07-14 10:02 ` [PATCH 04/41] perf record: Select comm_exec flag if supported Adrian Hunter
@ 2014-07-18  4:23   ` tip-bot for Adrian Hunter
  0 siblings, 0 replies; 122+ messages in thread
From: tip-bot for Adrian Hunter @ 2014-07-18  4:23 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: acme, linux-kernel, eranian, paulus, hpa, mingo, peterz,
	namhyung, jolsa, fweisbec, adrian.hunter, dsahern, tglx

Commit-ID:  39e09d40bea440d9cfe645b55aff251294318669
Gitweb:     http://git.kernel.org/tip/39e09d40bea440d9cfe645b55aff251294318669
Author:     Adrian Hunter <adrian.hunter@intel.com>
AuthorDate: Mon, 14 Jul 2014 13:02:28 +0300
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Wed, 16 Jul 2014 17:57:34 -0300

perf record: Select comm_exec flag if supported

The comm_exec flag on the attribute can later be found in the perf.data
file allowing a tool to know in advance if the captured data has the
flag.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/r/1405332185-4050-5-git-send-email-adrian.hunter@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/record.c | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/tools/perf/util/record.c b/tools/perf/util/record.c
index 049e0a0..1657231 100644
--- a/tools/perf/util/record.c
+++ b/tools/perf/util/record.c
@@ -69,15 +69,26 @@ static void perf_probe_sample_identifier(struct perf_evsel *evsel)
 	evsel->attr.sample_type |= PERF_SAMPLE_IDENTIFIER;
 }
 
+static void perf_probe_comm_exec(struct perf_evsel *evsel)
+{
+	evsel->attr.comm_exec = 1;
+}
+
 bool perf_can_sample_identifier(void)
 {
 	return perf_probe_api(perf_probe_sample_identifier);
 }
 
+static bool perf_can_comm_exec(void)
+{
+	return perf_probe_api(perf_probe_comm_exec);
+}
+
 void perf_evlist__config(struct perf_evlist *evlist, struct record_opts *opts)
 {
 	struct perf_evsel *evsel;
 	bool use_sample_identifier = false;
+	bool use_comm_exec;
 
 	/*
 	 * Set the evsel leader links before we configure attributes,
@@ -89,8 +100,13 @@ void perf_evlist__config(struct perf_evlist *evlist, struct record_opts *opts)
 	if (evlist->cpus->map[0] < 0)
 		opts->no_inherit = true;
 
-	evlist__for_each(evlist, evsel)
+	use_comm_exec = perf_can_comm_exec();
+
+	evlist__for_each(evlist, evsel) {
 		perf_evsel__config(evsel, opts);
+		if (!evsel->idx && use_comm_exec)
+			evsel->attr.comm_exec = 1;
+	}
 
 	if (evlist->nr_entries > 1) {
 		struct perf_evsel *first = perf_evlist__first(evlist);

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

* [tip:perf/core] perf tools: Fix missing kernel map load
  2014-07-14 10:02 ` [PATCH 07/41] perf tools: Fix missing kernel map load Adrian Hunter
@ 2014-07-18  4:23   ` tip-bot for Adrian Hunter
  0 siblings, 0 replies; 122+ messages in thread
From: tip-bot for Adrian Hunter @ 2014-07-18  4:23 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: acme, linux-kernel, eranian, paulus, hpa, mingo, peterz,
	namhyung, jolsa, fweisbec, adrian.hunter, dsahern, tglx

Commit-ID:  1f2a7069b6e895487b1d9229f5f62799cc4ea0aa
Gitweb:     http://git.kernel.org/tip/1f2a7069b6e895487b1d9229f5f62799cc4ea0aa
Author:     Adrian Hunter <adrian.hunter@intel.com>
AuthorDate: Mon, 14 Jul 2014 13:02:31 +0300
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Wed, 16 Jul 2014 17:57:34 -0300

perf tools: Fix missing kernel map load

thread__find_addr_map() falls back to trying the kernel maps if the
address is negative and is not found in userspace maps.  As commented in
the code, the kernel maps must be "loaded" before use.  This patch
ensures that happens under the fallback condition also.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/r/1405332185-4050-8-git-send-email-adrian.hunter@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/event.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index 198c4cc..7e0e8ae 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -788,6 +788,7 @@ try_again:
 		    cpumode == PERF_RECORD_MISC_USER &&
 		    machine && mg != &machine->kmaps) {
 			mg = &machine->kmaps;
+			load_map = true;
 			goto try_again;
 		}
 	} else {

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

* [tip:perf/core] perf symbols: Fix missing GNU IFUNC symbols
  2014-07-14 10:02 ` [PATCH 09/41] perf tools: Fix missing GNU IFUNC symbols Adrian Hunter
@ 2014-07-18  4:24   ` tip-bot for Adrian Hunter
  0 siblings, 0 replies; 122+ messages in thread
From: tip-bot for Adrian Hunter @ 2014-07-18  4:24 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: acme, linux-kernel, eranian, paulus, hpa, mingo, peterz,
	namhyung, jolsa, fweisbec, adrian.hunter, dsahern, tglx

Commit-ID:  a2f3b6bf0adadcb5f9383c60aa1355e0f9cba3da
Gitweb:     http://git.kernel.org/tip/a2f3b6bf0adadcb5f9383c60aa1355e0f9cba3da
Author:     Adrian Hunter <adrian.hunter@intel.com>
AuthorDate: Mon, 14 Jul 2014 13:02:33 +0300
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Wed, 16 Jul 2014 17:57:34 -0300

perf symbols: Fix missing GNU IFUNC symbols

Symbols of type STT_GNU_IFUNC are functions so accept them as such.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/r/1405332185-4050-10-git-send-email-adrian.hunter@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/symbol-elf.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c
index 6864661..dce5ccf 100644
--- a/tools/perf/util/symbol-elf.c
+++ b/tools/perf/util/symbol-elf.c
@@ -49,7 +49,8 @@ static inline uint8_t elf_sym__type(const GElf_Sym *sym)
 
 static inline int elf_sym__is_function(const GElf_Sym *sym)
 {
-	return elf_sym__type(sym) == STT_FUNC &&
+	return (elf_sym__type(sym) == STT_FUNC ||
+		elf_sym__type(sym) == STT_GNU_IFUNC) &&
 	       sym->st_name != 0 &&
 	       sym->st_shndx != SHN_UNDEF;
 }

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

* [tip:perf/core] perf inject: Fix build id injection
  2014-07-14 10:02 ` [PATCH 10/41] perf inject: Fix build id injection Adrian Hunter
@ 2014-07-18  4:24   ` tip-bot for Adrian Hunter
  0 siblings, 0 replies; 122+ messages in thread
From: tip-bot for Adrian Hunter @ 2014-07-18  4:24 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: acme, linux-kernel, eranian, paulus, hpa, mingo, peterz,
	namhyung, jolsa, fweisbec, adrian.hunter, dsahern, tglx

Commit-ID:  e38b43c3f3fd8ebe6f558400d1647a923bc19d44
Gitweb:     http://git.kernel.org/tip/e38b43c3f3fd8ebe6f558400d1647a923bc19d44
Author:     Adrian Hunter <adrian.hunter@intel.com>
AuthorDate: Mon, 14 Jul 2014 13:02:34 +0300
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Wed, 16 Jul 2014 17:57:34 -0300

perf inject: Fix build id injection

Build Ids won't be injected unless the build id feature flag is set.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/r/1405332185-4050-11-git-send-email-adrian.hunter@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/builtin-inject.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c
index 16c7c11..cf6a605 100644
--- a/tools/perf/builtin-inject.c
+++ b/tools/perf/builtin-inject.c
@@ -389,6 +389,9 @@ static int __cmd_inject(struct perf_inject *inject)
 	ret = perf_session__process_events(session, &inject->tool);
 
 	if (!file_out->is_pipe) {
+		if (inject->build_ids)
+			perf_header__set_feat(&session->header,
+					      HEADER_BUILD_ID);
 		session->header.data_size = inject->bytes_written;
 		perf_session__write_header(session, session->evlist, file_out->fd, true);
 	}

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

* [tip:perf/core] perf callchain: Fix appending a callchain from a previous sample
  2014-07-14 10:02 ` [PATCH 11/41] perf tools: Fix appending a callchain from a previous sample Adrian Hunter
@ 2014-07-18  4:24   ` tip-bot for Adrian Hunter
  0 siblings, 0 replies; 122+ messages in thread
From: tip-bot for Adrian Hunter @ 2014-07-18  4:24 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: acme, linux-kernel, eranian, paulus, hpa, mingo, peterz,
	namhyung, jolsa, fweisbec, adrian.hunter, dsahern, tglx

Commit-ID:  4d40b051b1ac41ecbc818deed27750b4c1697520
Gitweb:     http://git.kernel.org/tip/4d40b051b1ac41ecbc818deed27750b4c1697520
Author:     Adrian Hunter <adrian.hunter@intel.com>
AuthorDate: Mon, 14 Jul 2014 13:02:35 +0300
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Wed, 16 Jul 2014 17:57:35 -0300

perf callchain: Fix appending a callchain from a previous sample

hist_entry__append_callchain() must check if the sample has a callcahin
or it will append the callchain from a previous sample.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/r/1405332185-4050-12-git-send-email-adrian.hunter@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/callchain.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c
index 48b6d3f..437ee09 100644
--- a/tools/perf/util/callchain.c
+++ b/tools/perf/util/callchain.c
@@ -626,7 +626,7 @@ int sample__resolve_callchain(struct perf_sample *sample, struct symbol **parent
 
 int hist_entry__append_callchain(struct hist_entry *he, struct perf_sample *sample)
 {
-	if (!symbol_conf.use_callchain)
+	if (!symbol_conf.use_callchain || sample->callchain == NULL)
 		return 0;
 	return callchain_append(he->callchain, &callchain_cursor, sample->period);
 }

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

* [tip:perf/core] perf buildid-cache: Apply force option to copying kcore
  2014-07-14 10:02 ` [PATCH 14/41] perf buildid-cache: Apply force option to copying kcore Adrian Hunter
@ 2014-07-18  4:24   ` tip-bot for Adrian Hunter
  0 siblings, 0 replies; 122+ messages in thread
From: tip-bot for Adrian Hunter @ 2014-07-18  4:24 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: acme, linux-kernel, eranian, paulus, hpa, mingo, peterz,
	namhyung, jolsa, fweisbec, adrian.hunter, dsahern, tglx

Commit-ID:  5173fbb8a11b2857aeec9e5f4e9568d4e1b84dbd
Gitweb:     http://git.kernel.org/tip/5173fbb8a11b2857aeec9e5f4e9568d4e1b84dbd
Author:     Adrian Hunter <adrian.hunter@intel.com>
AuthorDate: Mon, 14 Jul 2014 13:02:38 +0300
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Wed, 16 Jul 2014 17:57:35 -0300

perf buildid-cache: Apply force option to copying kcore

Currently a copy of kcore is not made if there is one already with the
same modules at the same addresses.

Change this to make a copy anyway if the force (-f) option is also used.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/r/1405332185-4050-15-git-send-email-adrian.hunter@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/builtin-buildid-cache.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/tools/perf/builtin-buildid-cache.c b/tools/perf/builtin-buildid-cache.c
index b22dbb1..2a2c78f 100644
--- a/tools/perf/builtin-buildid-cache.c
+++ b/tools/perf/builtin-buildid-cache.c
@@ -125,7 +125,8 @@ static int build_id_cache__kcore_existing(const char *from_dir, char *to_dir,
 	return ret;
 }
 
-static int build_id_cache__add_kcore(const char *filename, const char *debugdir)
+static int build_id_cache__add_kcore(const char *filename, const char *debugdir,
+				     bool force)
 {
 	char dir[32], sbuildid[BUILD_ID_SIZE * 2 + 1];
 	char from_dir[PATH_MAX], to_dir[PATH_MAX];
@@ -144,7 +145,8 @@ static int build_id_cache__add_kcore(const char *filename, const char *debugdir)
 	scnprintf(to_dir, sizeof(to_dir), "%s/[kernel.kcore]/%s",
 		  debugdir, sbuildid);
 
-	if (!build_id_cache__kcore_existing(from_dir, to_dir, sizeof(to_dir))) {
+	if (!force &&
+	    !build_id_cache__kcore_existing(from_dir, to_dir, sizeof(to_dir))) {
 		pr_debug("same kcore found in %s\n", to_dir);
 		return 0;
 	}
@@ -389,7 +391,7 @@ int cmd_buildid_cache(int argc, const char **argv,
 	}
 
 	if (kcore_filename &&
-	    build_id_cache__add_kcore(kcore_filename, debugdir))
+	    build_id_cache__add_kcore(kcore_filename, debugdir, force))
 		pr_warning("Couldn't add %s\n", kcore_filename);
 
 	return ret;

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

* [tip:perf/core] perf symbols: Record whether a dso is 64-bit
  2014-07-14 10:02 ` [PATCH 17/41] perf tools: Record whether a dso is 64-bit Adrian Hunter
@ 2014-07-18  4:24   ` tip-bot for Adrian Hunter
  0 siblings, 0 replies; 122+ messages in thread
From: tip-bot for Adrian Hunter @ 2014-07-18  4:24 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: acme, linux-kernel, eranian, paulus, hpa, mingo, peterz,
	namhyung, jolsa, fweisbec, adrian.hunter, dsahern, tglx

Commit-ID:  c6d8f2a4a0c5e366330a6a2a94c06b652f4ca554
Gitweb:     http://git.kernel.org/tip/c6d8f2a4a0c5e366330a6a2a94c06b652f4ca554
Author:     Adrian Hunter <adrian.hunter@intel.com>
AuthorDate: Mon, 14 Jul 2014 13:02:41 +0300
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Wed, 16 Jul 2014 17:57:35 -0300

perf symbols: Record whether a dso is 64-bit

Add a flag to 'struct dso' to record if the dso is 64-bit or not.
Update the flag when reading the ELF.

This is needed for instruction decoding.  For example, x86 instruction
decoding depends on whether or not the 64-bit instruction set is used.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/r/1405332185-4050-18-git-send-email-adrian.hunter@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/dso.c            |  1 +
 tools/perf/util/dso.h            |  1 +
 tools/perf/util/symbol-elf.c     |  3 +++
 tools/perf/util/symbol-minimal.c | 22 ++++++++++++++++++++++
 tools/perf/util/symbol.c         |  1 +
 tools/perf/util/symbol.h         |  1 +
 6 files changed, 29 insertions(+)

diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c
index 819f104..fc006fe 100644
--- a/tools/perf/util/dso.c
+++ b/tools/perf/util/dso.c
@@ -703,6 +703,7 @@ struct dso *dso__new(const char *name)
 		dso->data.fd = -1;
 		dso->symtab_type = DSO_BINARY_TYPE__NOT_FOUND;
 		dso->binary_type = DSO_BINARY_TYPE__NOT_FOUND;
+		dso->is_64_bit = (sizeof(void *) == 8);
 		dso->loaded = 0;
 		dso->rel = 0;
 		dso->sorted_by_name = 0;
diff --git a/tools/perf/util/dso.h b/tools/perf/util/dso.h
index ad553ba..c239e86 100644
--- a/tools/perf/util/dso.h
+++ b/tools/perf/util/dso.h
@@ -90,6 +90,7 @@ struct dso {
 	u8		 annotate_warned:1;
 	u8		 short_name_allocated:1;
 	u8		 long_name_allocated:1;
+	u8		 is_64_bit:1;
 	u8		 sorted_by_name;
 	u8		 loaded;
 	u8		 rel;
diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c
index dce5ccf..cef8f42 100644
--- a/tools/perf/util/symbol-elf.c
+++ b/tools/perf/util/symbol-elf.c
@@ -599,6 +599,8 @@ int symsrc__init(struct symsrc *ss, struct dso *dso, const char *name,
 			goto out_elf_end;
 	}
 
+	ss->is_64_bit = (gelf_getclass(elf) == ELFCLASS64);
+
 	ss->symtab = elf_section_by_name(elf, &ehdr, &ss->symshdr, ".symtab",
 			NULL);
 	if (ss->symshdr.sh_type != SHT_SYMTAB)
@@ -699,6 +701,7 @@ int dso__load_sym(struct dso *dso, struct map *map,
 	bool remap_kernel = false, adjust_kernel_syms = false;
 
 	dso->symtab_type = syms_ss->type;
+	dso->is_64_bit = syms_ss->is_64_bit;
 	dso->rel = syms_ss->ehdr.e_type == ET_REL;
 
 	/*
diff --git a/tools/perf/util/symbol-minimal.c b/tools/perf/util/symbol-minimal.c
index bd15f49..101f55d 100644
--- a/tools/perf/util/symbol-minimal.c
+++ b/tools/perf/util/symbol-minimal.c
@@ -288,6 +288,23 @@ int dso__synthesize_plt_symbols(struct dso *dso __maybe_unused,
 	return 0;
 }
 
+static int fd__is_64_bit(int fd)
+{
+	u8 e_ident[EI_NIDENT];
+
+	if (lseek(fd, 0, SEEK_SET))
+		return -1;
+
+	if (readn(fd, e_ident, sizeof(e_ident)) != sizeof(e_ident))
+		return -1;
+
+	if (memcmp(e_ident, ELFMAG, SELFMAG) ||
+	    e_ident[EI_VERSION] != EV_CURRENT)
+		return -1;
+
+	return e_ident[EI_CLASS] == ELFCLASS64;
+}
+
 int dso__load_sym(struct dso *dso, struct map *map __maybe_unused,
 		  struct symsrc *ss,
 		  struct symsrc *runtime_ss __maybe_unused,
@@ -295,6 +312,11 @@ int dso__load_sym(struct dso *dso, struct map *map __maybe_unused,
 		  int kmodule __maybe_unused)
 {
 	unsigned char *build_id[BUILD_ID_SIZE];
+	int ret;
+
+	ret = fd__is_64_bit(ss->fd);
+	if (ret >= 0)
+		dso->is_64_bit = ret;
 
 	if (filename__read_build_id(ss->name, build_id, BUILD_ID_SIZE) > 0) {
 		dso__set_build_id(dso, build_id);
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index 2e6a2e2..ae2e446 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -1065,6 +1065,7 @@ static int dso__load_kcore(struct dso *dso, struct map *map,
 			      &is_64_bit);
 	if (err)
 		goto out_err;
+	dso->is_64_bit = is_64_bit;
 
 	if (list_empty(&md.maps)) {
 		err = -EINVAL;
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index a81877b..436169d 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -216,6 +216,7 @@ struct symsrc {
 	GElf_Shdr dynshdr;
 
 	bool adjust_symbols;
+	bool is_64_bit;
 #endif
 };
 

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

* [tip:perf/core] perf symbols: Do not attempt to read data from kallsyms
  2014-07-14 10:02 ` [PATCH 19/41] perf tools: Do not attempt to read data from kallsyms Adrian Hunter
@ 2014-07-18  4:25   ` tip-bot for Adrian Hunter
  0 siblings, 0 replies; 122+ messages in thread
From: tip-bot for Adrian Hunter @ 2014-07-18  4:25 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: acme, linux-kernel, eranian, paulus, hpa, mingo, peterz,
	namhyung, jolsa, fweisbec, adrian.hunter, dsahern, tglx

Commit-ID:  bdac0bcf779250e89b96d4a3f381ebaf02c2f4a9
Gitweb:     http://git.kernel.org/tip/bdac0bcf779250e89b96d4a3f381ebaf02c2f4a9
Author:     Adrian Hunter <adrian.hunter@intel.com>
AuthorDate: Mon, 14 Jul 2014 13:02:43 +0300
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Wed, 16 Jul 2014 17:57:35 -0300

perf symbols: Do not attempt to read data from kallsyms

Record kallsyms binary type so that tools will not
attempt to read binary data from it.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/r/1405332185-4050-20-git-send-email-adrian.hunter@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/symbol.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index ae2e446..156ae36 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -1664,6 +1664,7 @@ do_kallsyms:
 	free(kallsyms_allocated_filename);
 
 	if (err > 0 && !dso__is_kcore(dso)) {
+		dso->binary_type = DSO_BINARY_TYPE__KALLSYMS;
 		dso__set_long_name(dso, "[kernel.kallsyms]", false);
 		map__fixup_start(map);
 		map__fixup_end(map);
@@ -1711,6 +1712,7 @@ static int dso__load_guest_kernel_sym(struct dso *dso, struct map *map,
 	if (err > 0)
 		pr_debug("Using %s for symbols\n", kallsyms_filename);
 	if (err > 0 && !dso__is_kcore(dso)) {
+		dso->binary_type = DSO_BINARY_TYPE__GUEST_KALLSYMS;
 		machine__mmap_name(machine, path, sizeof(path));
 		dso__set_long_name(dso, strdup(path), true);
 		map__fixup_start(map);

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

* [tip:perf/core] perf symbols: Add ability to iterate over a dso' s symbols
  2014-07-14 10:02 ` [PATCH 26/41] perf tools: Add ability to iterate over a dso's symbols Adrian Hunter
@ 2014-07-18  4:25   ` tip-bot for Adrian Hunter
  0 siblings, 0 replies; 122+ messages in thread
From: tip-bot for Adrian Hunter @ 2014-07-18  4:25 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: acme, linux-kernel, eranian, paulus, hpa, mingo, peterz,
	namhyung, jolsa, fweisbec, adrian.hunter, dsahern, tglx

Commit-ID:  9c00a81b6aafc4ed375a43e7a54e6cf2d720c7c6
Gitweb:     http://git.kernel.org/tip/9c00a81b6aafc4ed375a43e7a54e6cf2d720c7c6
Author:     Adrian Hunter <adrian.hunter@intel.com>
AuthorDate: Mon, 14 Jul 2014 13:02:50 +0300
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Wed, 16 Jul 2014 17:57:35 -0300

perf symbols: Add ability to iterate over a dso's symbols

Expose dso__first_symbol() and dso__next_symbol() to make it possible to
iterate over a dso's symbols.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/r/1405332185-4050-27-git-send-email-adrian.hunter@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/symbol.c | 17 ++++++++++++++++-
 tools/perf/util/symbol.h |  3 +++
 2 files changed, 19 insertions(+), 1 deletion(-)

diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index 156ae36..eb06746 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -342,6 +342,16 @@ static struct symbol *symbols__first(struct rb_root *symbols)
 	return NULL;
 }
 
+static struct symbol *symbols__next(struct symbol *sym)
+{
+	struct rb_node *n = rb_next(&sym->rb_node);
+
+	if (n)
+		return rb_entry(n, struct symbol, rb_node);
+
+	return NULL;
+}
+
 struct symbol_name_rb_node {
 	struct rb_node	rb_node;
 	struct symbol	sym;
@@ -412,11 +422,16 @@ struct symbol *dso__find_symbol(struct dso *dso,
 	return symbols__find(&dso->symbols[type], addr);
 }
 
-static struct symbol *dso__first_symbol(struct dso *dso, enum map_type type)
+struct symbol *dso__first_symbol(struct dso *dso, enum map_type type)
 {
 	return symbols__first(&dso->symbols[type]);
 }
 
+struct symbol *dso__next_symbol(struct symbol *sym)
+{
+	return symbols__next(sym);
+}
+
 struct symbol *dso__find_symbol_by_name(struct dso *dso, enum map_type type,
 					const char *name)
 {
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index 436169d..ee2d3cc 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -240,6 +240,9 @@ struct symbol *dso__find_symbol(struct dso *dso, enum map_type type,
 struct symbol *dso__find_symbol_by_name(struct dso *dso, enum map_type type,
 					const char *name);
 
+struct symbol *dso__first_symbol(struct dso *dso, enum map_type type);
+struct symbol *dso__next_symbol(struct symbol *sym);
+
 int filename__read_build_id(const char *filename, void *bf, size_t size);
 int sysfs__read_build_id(const char *filename, void *bf, size_t size);
 int modules__parse(const char *filename, void *arg,

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

* [tip:perf/core] perf session: Flag if the event stream is entirely in memory
  2014-07-14 10:02 ` [PATCH 27/41] perf session: Flag if the event stream is entirely in memory Adrian Hunter
@ 2014-07-18  4:25   ` tip-bot for Adrian Hunter
  0 siblings, 0 replies; 122+ messages in thread
From: tip-bot for Adrian Hunter @ 2014-07-18  4:25 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: acme, linux-kernel, eranian, paulus, hpa, mingo, peterz,
	namhyung, jolsa, fweisbec, adrian.hunter, dsahern, tglx

Commit-ID:  919d86d3a3109d7d4f0d7347f34711ee2f8e6609
Gitweb:     http://git.kernel.org/tip/919d86d3a3109d7d4f0d7347f34711ee2f8e6609
Author:     Adrian Hunter <adrian.hunter@intel.com>
AuthorDate: Mon, 14 Jul 2014 13:02:51 +0300
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Wed, 16 Jul 2014 17:57:36 -0300

perf session: Flag if the event stream is entirely in memory

Flag if the event stream is a file that has been mmapped in one go.

This is useful, for example, if a tool needs to keep an event for later
reference.  If the new flag is set, a pointer to the event can be
retained, otherwise the event must be copied.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/r/1405332185-4050-28-git-send-email-adrian.hunter@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/session.c | 9 ++++++++-
 tools/perf/util/session.h | 3 +++
 2 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index c2f4ca9..eac14ce 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -1297,8 +1297,10 @@ int __perf_session__process_events(struct perf_session *session,
 	ui_progress__init(&prog, file_size, "Processing events...");
 
 	mmap_size = MMAP_SIZE;
-	if (mmap_size > file_size)
+	if (mmap_size > file_size) {
 		mmap_size = file_size;
+		session->one_mmap = true;
+	}
 
 	memset(mmaps, 0, sizeof(mmaps));
 
@@ -1320,6 +1322,10 @@ remap:
 	mmaps[map_idx] = buf;
 	map_idx = (map_idx + 1) & (ARRAY_SIZE(mmaps) - 1);
 	file_pos = file_offset + head;
+	if (session->one_mmap) {
+		session->one_mmap_addr = buf;
+		session->one_mmap_offset = file_offset;
+	}
 
 more:
 	event = fetch_mmaped_event(session, head, mmap_size, buf);
@@ -1365,6 +1371,7 @@ out_err:
 	ui_progress__finish();
 	perf_session__warn_about_errors(session, tool);
 	perf_session_free_sample_buffers(session);
+	session->one_mmap = false;
 	return err;
 }
 
diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h
index 3140f8a..0321013 100644
--- a/tools/perf/util/session.h
+++ b/tools/perf/util/session.h
@@ -36,6 +36,9 @@ struct perf_session {
 	struct trace_event	tevent;
 	struct events_stats	stats;
 	bool			repipe;
+	bool			one_mmap;
+	void			*one_mmap_addr;
+	u64			one_mmap_offset;
 	struct ordered_samples	ordered_samples;
 	struct perf_data_file	*file;
 };

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

* [tip:perf/core] perf evlist: Pass mmap parameters in a struct
  2014-07-14 10:02 ` [PATCH 28/41] perf evlist: Pass mmap parameters in a struct Adrian Hunter
@ 2014-07-18  4:25   ` tip-bot for Adrian Hunter
  0 siblings, 0 replies; 122+ messages in thread
From: tip-bot for Adrian Hunter @ 2014-07-18  4:25 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: acme, linux-kernel, eranian, paulus, hpa, mingo, peterz,
	namhyung, jolsa, fweisbec, adrian.hunter, dsahern, tglx

Commit-ID:  a8a8f3eb5de55aeaf007c18572668e8ec463547b
Gitweb:     http://git.kernel.org/tip/a8a8f3eb5de55aeaf007c18572668e8ec463547b
Author:     Adrian Hunter <adrian.hunter@intel.com>
AuthorDate: Mon, 14 Jul 2014 13:02:52 +0300
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Wed, 16 Jul 2014 17:57:36 -0300

perf evlist: Pass mmap parameters in a struct

In preparation for adding more mmap parameters, pass existing parameters
in a struct.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/r/1405332185-4050-29-git-send-email-adrian.hunter@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/evlist.c | 46 ++++++++++++++++++++++++++--------------------
 1 file changed, 26 insertions(+), 20 deletions(-)

diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index c51223a..814e954 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -606,12 +606,17 @@ static int perf_evlist__alloc_mmap(struct perf_evlist *evlist)
 	return evlist->mmap != NULL ? 0 : -ENOMEM;
 }
 
-static int __perf_evlist__mmap(struct perf_evlist *evlist,
-			       int idx, int prot, int mask, int fd)
+struct mmap_params {
+	int prot;
+	int mask;
+};
+
+static int __perf_evlist__mmap(struct perf_evlist *evlist, int idx,
+			       struct mmap_params *mp, int fd)
 {
 	evlist->mmap[idx].prev = 0;
-	evlist->mmap[idx].mask = mask;
-	evlist->mmap[idx].base = mmap(NULL, evlist->mmap_len, prot,
+	evlist->mmap[idx].mask = mp->mask;
+	evlist->mmap[idx].base = mmap(NULL, evlist->mmap_len, mp->prot,
 				      MAP_SHARED, fd, 0);
 	if (evlist->mmap[idx].base == MAP_FAILED) {
 		pr_debug2("failed to mmap perf event ring buffer, error %d\n",
@@ -625,8 +630,8 @@ static int __perf_evlist__mmap(struct perf_evlist *evlist,
 }
 
 static int perf_evlist__mmap_per_evsel(struct perf_evlist *evlist, int idx,
-				       int prot, int mask, int cpu, int thread,
-				       int *output)
+				       struct mmap_params *mp, int cpu,
+				       int thread, int *output)
 {
 	struct perf_evsel *evsel;
 
@@ -635,8 +640,7 @@ static int perf_evlist__mmap_per_evsel(struct perf_evlist *evlist, int idx,
 
 		if (*output == -1) {
 			*output = fd;
-			if (__perf_evlist__mmap(evlist, idx, prot, mask,
-						*output) < 0)
+			if (__perf_evlist__mmap(evlist, idx, mp, *output) < 0)
 				return -1;
 		} else {
 			if (ioctl(fd, PERF_EVENT_IOC_SET_OUTPUT, *output) != 0)
@@ -651,8 +655,8 @@ static int perf_evlist__mmap_per_evsel(struct perf_evlist *evlist, int idx,
 	return 0;
 }
 
-static int perf_evlist__mmap_per_cpu(struct perf_evlist *evlist, int prot,
-				     int mask)
+static int perf_evlist__mmap_per_cpu(struct perf_evlist *evlist,
+				     struct mmap_params *mp)
 {
 	int cpu, thread;
 	int nr_cpus = cpu_map__nr(evlist->cpus);
@@ -663,8 +667,8 @@ static int perf_evlist__mmap_per_cpu(struct perf_evlist *evlist, int prot,
 		int output = -1;
 
 		for (thread = 0; thread < nr_threads; thread++) {
-			if (perf_evlist__mmap_per_evsel(evlist, cpu, prot, mask,
-							cpu, thread, &output))
+			if (perf_evlist__mmap_per_evsel(evlist, cpu, mp, cpu,
+							thread, &output))
 				goto out_unmap;
 		}
 	}
@@ -677,8 +681,8 @@ out_unmap:
 	return -1;
 }
 
-static int perf_evlist__mmap_per_thread(struct perf_evlist *evlist, int prot,
-					int mask)
+static int perf_evlist__mmap_per_thread(struct perf_evlist *evlist,
+					struct mmap_params *mp)
 {
 	int thread;
 	int nr_threads = thread_map__nr(evlist->threads);
@@ -687,8 +691,8 @@ static int perf_evlist__mmap_per_thread(struct perf_evlist *evlist, int prot,
 	for (thread = 0; thread < nr_threads; thread++) {
 		int output = -1;
 
-		if (perf_evlist__mmap_per_evsel(evlist, thread, prot, mask, 0,
-						thread, &output))
+		if (perf_evlist__mmap_per_evsel(evlist, thread, mp, 0, thread,
+						&output))
 			goto out_unmap;
 	}
 
@@ -793,7 +797,9 @@ int perf_evlist__mmap(struct perf_evlist *evlist, unsigned int pages,
 	struct perf_evsel *evsel;
 	const struct cpu_map *cpus = evlist->cpus;
 	const struct thread_map *threads = evlist->threads;
-	int prot = PROT_READ | (overwrite ? 0 : PROT_WRITE), mask;
+	struct mmap_params mp = {
+		.prot = PROT_READ | (overwrite ? 0 : PROT_WRITE),
+	};
 
 	if (evlist->mmap == NULL && perf_evlist__alloc_mmap(evlist) < 0)
 		return -ENOMEM;
@@ -804,7 +810,7 @@ int perf_evlist__mmap(struct perf_evlist *evlist, unsigned int pages,
 	evlist->overwrite = overwrite;
 	evlist->mmap_len = perf_evlist__mmap_size(pages);
 	pr_debug("mmap size %zuB\n", evlist->mmap_len);
-	mask = evlist->mmap_len - page_size - 1;
+	mp.mask = evlist->mmap_len - page_size - 1;
 
 	evlist__for_each(evlist, evsel) {
 		if ((evsel->attr.read_format & PERF_FORMAT_ID) &&
@@ -814,9 +820,9 @@ int perf_evlist__mmap(struct perf_evlist *evlist, unsigned int pages,
 	}
 
 	if (cpu_map__empty(cpus))
-		return perf_evlist__mmap_per_thread(evlist, prot, mask);
+		return perf_evlist__mmap_per_thread(evlist, &mp);
 
-	return perf_evlist__mmap_per_cpu(evlist, prot, mask);
+	return perf_evlist__mmap_per_cpu(evlist, &mp);
 }
 
 int perf_evlist__create_maps(struct perf_evlist *evlist, struct target *target)

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

* [tip:perf/core] perf tools: Add feature test for __sync_val_compare_and_swap
  2014-07-14 10:02 ` [PATCH 29/41] perf tools: Add feature test for __sync_val_compare_and_swap Adrian Hunter
@ 2014-07-18  4:26   ` tip-bot for Adrian Hunter
  0 siblings, 0 replies; 122+ messages in thread
From: tip-bot for Adrian Hunter @ 2014-07-18  4:26 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: acme, linux-kernel, eranian, paulus, hpa, mingo, peterz,
	namhyung, jolsa, fweisbec, adrian.hunter, dsahern, tglx

Commit-ID:  f6d313699a9612a30fabe05bf2c9302c1408b5cf
Gitweb:     http://git.kernel.org/tip/f6d313699a9612a30fabe05bf2c9302c1408b5cf
Author:     Adrian Hunter <adrian.hunter@intel.com>
AuthorDate: Mon, 14 Jul 2014 13:02:53 +0300
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Wed, 16 Jul 2014 17:57:36 -0300

perf tools: Add feature test for __sync_val_compare_and_swap

Add a feature test for __sync_val_compare_and_swap() and
__sync_bool_compare_and_swap()

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/r/1405332185-4050-30-git-send-email-adrian.hunter@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/config/Makefile                                 |  6 ++++++
 tools/perf/config/feature-checks/Makefile                  |  4 ++++
 tools/perf/config/feature-checks/test-all.c                |  5 +++++
 .../config/feature-checks/test-sync-compare-and-swap.c     | 14 ++++++++++++++
 4 files changed, 29 insertions(+)

diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile
index b7f42d5..1f67aa0 100644
--- a/tools/perf/config/Makefile
+++ b/tools/perf/config/Makefile
@@ -164,6 +164,7 @@ CORE_FEATURE_TESTS =			\
 	backtrace			\
 	dwarf				\
 	fortify-source			\
+	sync-compare-and-swap		\
 	glibc				\
 	gtk2				\
 	gtk2-infobar			\
@@ -199,6 +200,7 @@ LIB_FEATURE_TESTS =			\
 VF_FEATURE_TESTS =			\
 	backtrace			\
 	fortify-source			\
+	sync-compare-and-swap		\
 	gtk2-infobar			\
 	libelf-getphdrnum		\
 	libelf-mmap			\
@@ -272,6 +274,10 @@ CFLAGS += -I$(LIB_INCLUDE)
 
 CFLAGS += -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE
 
+ifeq ($(feature-sync-compare-and-swap), 1)
+  CFLAGS += -DHAVE_SYNC_COMPARE_AND_SWAP_SUPPORT
+endif
+
 ifndef NO_BIONIC
   $(call feature_check,bionic)
   ifeq ($(feature-bionic), 1)
diff --git a/tools/perf/config/feature-checks/Makefile b/tools/perf/config/feature-checks/Makefile
index 64c84e5..6088f8d 100644
--- a/tools/perf/config/feature-checks/Makefile
+++ b/tools/perf/config/feature-checks/Makefile
@@ -5,6 +5,7 @@ FILES=					\
 	test-bionic.bin			\
 	test-dwarf.bin			\
 	test-fortify-source.bin		\
+	test-sync-compare-and-swap.bin	\
 	test-glibc.bin			\
 	test-gtk2.bin			\
 	test-gtk2-infobar.bin		\
@@ -141,6 +142,9 @@ test-timerfd.bin:
 test-libdw-dwarf-unwind.bin:
 	$(BUILD)
 
+test-sync-compare-and-swap.bin:
+	$(BUILD) -Werror
+
 -include *.d
 
 ###############################
diff --git a/tools/perf/config/feature-checks/test-all.c b/tools/perf/config/feature-checks/test-all.c
index fe5c1e5..a7d022e 100644
--- a/tools/perf/config/feature-checks/test-all.c
+++ b/tools/perf/config/feature-checks/test-all.c
@@ -89,6 +89,10 @@
 # include "test-libdw-dwarf-unwind.c"
 #undef main
 
+#define main main_test_sync_compare_and_swap
+# include "test-sync-compare-and-swap.c"
+#undef main
+
 int main(int argc, char *argv[])
 {
 	main_test_libpython();
@@ -111,6 +115,7 @@ int main(int argc, char *argv[])
 	main_test_timerfd();
 	main_test_stackprotector_all();
 	main_test_libdw_dwarf_unwind();
+	main_test_sync_compare_and_swap(argc, argv);
 
 	return 0;
 }
diff --git a/tools/perf/config/feature-checks/test-sync-compare-and-swap.c b/tools/perf/config/feature-checks/test-sync-compare-and-swap.c
new file mode 100644
index 0000000..c34d4ca
--- /dev/null
+++ b/tools/perf/config/feature-checks/test-sync-compare-and-swap.c
@@ -0,0 +1,14 @@
+#include <stdint.h>
+
+volatile uint64_t x;
+
+int main(int argc, char *argv[])
+{
+	uint64_t old, new = argc;
+
+	argv = argv;
+	do {
+		old = __sync_val_compare_and_swap(&x, 0, 0);
+	} while (!__sync_bool_compare_and_swap(&x, old, new));
+	return old == new;
+}

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

* [tip:perf/core] perf tools: Add option macro OPT_CALLBACK_OPTARG
  2014-07-14 10:02 ` [PATCH 30/41] perf tools: Add option macro OPT_CALLBACK_OPTARG Adrian Hunter
@ 2014-07-18  4:26   ` tip-bot for Adrian Hunter
  0 siblings, 0 replies; 122+ messages in thread
From: tip-bot for Adrian Hunter @ 2014-07-18  4:26 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: acme, linux-kernel, eranian, paulus, hpa, mingo, peterz,
	namhyung, jolsa, fweisbec, adrian.hunter, dsahern, tglx

Commit-ID:  ea8e08a16a1e6566be3f775c0bd351fa52ab6b9d
Gitweb:     http://git.kernel.org/tip/ea8e08a16a1e6566be3f775c0bd351fa52ab6b9d
Author:     Adrian Hunter <adrian.hunter@intel.com>
AuthorDate: Mon, 14 Jul 2014 13:02:54 +0300
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Wed, 16 Jul 2014 17:57:36 -0300

perf tools: Add option macro OPT_CALLBACK_OPTARG

Add an option macro that is the same as OPT_CALLBACK except that the
argument is optional and it is possible to associate additional data
with it.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/r/1405332185-4050-31-git-send-email-adrian.hunter@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/parse-options.h | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/tools/perf/util/parse-options.h b/tools/perf/util/parse-options.h
index d8dac8a..b59ba85 100644
--- a/tools/perf/util/parse-options.h
+++ b/tools/perf/util/parse-options.h
@@ -98,6 +98,7 @@ struct option {
 	parse_opt_cb *callback;
 	intptr_t defval;
 	bool *set;
+	void *data;
 };
 
 #define check_vtype(v, type) ( BUILD_BUG_ON_ZERO(!__builtin_types_compatible_p(typeof(v), type)) + v )
@@ -131,6 +132,10 @@ struct option {
 	{ .type = OPTION_CALLBACK, .short_name = (s), .long_name = (l),\
 	.value = (v), (a), .help = (h), .callback = (f), .defval = (intptr_t)d,\
 	.flags = PARSE_OPT_LASTARG_DEFAULT | PARSE_OPT_NOARG}
+#define OPT_CALLBACK_OPTARG(s, l, v, d, a, h, f) \
+	{ .type = OPTION_CALLBACK, .short_name = (s), .long_name = (l), \
+	  .value = (v), (a), .help = (h), .callback = (f), \
+	  .flags = PARSE_OPT_OPTARG, .data = (d) }
 
 /* parse_options() will filter out the processed options and leave the
  * non-option argments in argv[].

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

* [tip:perf/core] perf evsel: Add 'no_aux_samples' option
  2014-07-14 10:02 ` [PATCH 32/41] perf evsel: Add 'no_aux_samples' option Adrian Hunter
@ 2014-07-18  4:26   ` tip-bot for Adrian Hunter
  0 siblings, 0 replies; 122+ messages in thread
From: tip-bot for Adrian Hunter @ 2014-07-18  4:26 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: acme, linux-kernel, eranian, paulus, hpa, mingo, peterz,
	namhyung, jolsa, fweisbec, adrian.hunter, dsahern, tglx

Commit-ID:  6ff1ce763921f605aaf98c7a828b7df24d6923dc
Gitweb:     http://git.kernel.org/tip/6ff1ce763921f605aaf98c7a828b7df24d6923dc
Author:     Adrian Hunter <adrian.hunter@intel.com>
AuthorDate: Mon, 14 Jul 2014 13:02:56 +0300
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Wed, 16 Jul 2014 17:57:36 -0300

perf evsel: Add 'no_aux_samples' option

Add an option to prevent additional samples being added to a selected
event by perf_evsel__config().

This is needed when using the sched_switch tracepoint to follow object
code execution.  Since sched_switch will be used only for switch
information, additional sampling is wasteful.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/r/1405332185-4050-33-git-send-email-adrian.hunter@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/evsel.c | 6 +++---
 tools/perf/util/evsel.h | 1 +
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index b760d32..40626e5 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -623,7 +623,7 @@ void perf_evsel__config(struct perf_evsel *evsel, struct record_opts *opts)
 		attr->mmap_data = track;
 	}
 
-	if (opts->call_graph_enabled)
+	if (opts->call_graph_enabled && !evsel->no_aux_samples)
 		perf_evsel__config_callgraph(evsel, opts);
 
 	if (target__has_cpu(&opts->target))
@@ -637,7 +637,7 @@ void perf_evsel__config(struct perf_evsel *evsel, struct record_opts *opts)
 	     target__has_cpu(&opts->target) || per_cpu))
 		perf_evsel__set_sample_bit(evsel, TIME);
 
-	if (opts->raw_samples) {
+	if (opts->raw_samples && !evsel->no_aux_samples) {
 		perf_evsel__set_sample_bit(evsel, TIME);
 		perf_evsel__set_sample_bit(evsel, RAW);
 		perf_evsel__set_sample_bit(evsel, CPU);
@@ -650,7 +650,7 @@ void perf_evsel__config(struct perf_evsel *evsel, struct record_opts *opts)
 		attr->watermark = 0;
 		attr->wakeup_events = 1;
 	}
-	if (opts->branch_stack) {
+	if (opts->branch_stack && !evsel->no_aux_samples) {
 		perf_evsel__set_sample_bit(evsel, BRANCH_STACK);
 		attr->branch_sample_type = opts->branch_stack;
 	}
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index a52e9a5..8dfec05 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -83,6 +83,7 @@ struct perf_evsel {
 	int			is_pos;
 	bool 			supported;
 	bool 			needs_swap;
+	bool			no_aux_samples;
 	/* parse modifier helper */
 	int			exclude_GH;
 	int			nr_members;

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

* [tip:perf/core] perf evsel: Add 'immediate' option
  2014-07-14 10:02 ` [PATCH 33/41] perf evsel: Add 'immediate' option Adrian Hunter
@ 2014-07-18  4:26   ` tip-bot for Adrian Hunter
  0 siblings, 0 replies; 122+ messages in thread
From: tip-bot for Adrian Hunter @ 2014-07-18  4:26 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: acme, linux-kernel, eranian, paulus, hpa, mingo, peterz,
	namhyung, jolsa, fweisbec, adrian.hunter, dsahern, tglx

Commit-ID:  2afd2bcfc3a026d6e4c2184bf41ccd74eb05758b
Gitweb:     http://git.kernel.org/tip/2afd2bcfc3a026d6e4c2184bf41ccd74eb05758b
Author:     Adrian Hunter <adrian.hunter@intel.com>
AuthorDate: Mon, 14 Jul 2014 13:02:57 +0300
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Wed, 16 Jul 2014 17:57:37 -0300

perf evsel: Add 'immediate' option

Add an option to cause a selected event to be enabled immediately when
configured by perf_evsel__config().

This is needed when using the sched_switch tracepoint to follow object
code execution.  By having sched_switch enabled immediately the first
sched_switch event precedes the start of other tracing.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/r/1405332185-4050-34-git-send-email-adrian.hunter@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/evsel.c | 5 +++++
 tools/perf/util/evsel.h | 1 +
 2 files changed, 6 insertions(+)

diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 40626e5..90f58cd 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -681,6 +681,11 @@ void perf_evsel__config(struct perf_evsel *evsel, struct record_opts *opts)
 	if (target__none(&opts->target) && perf_evsel__is_group_leader(evsel) &&
 		!opts->initial_delay)
 		attr->enable_on_exec = 1;
+
+	if (evsel->immediate) {
+		attr->disabled = 0;
+		attr->enable_on_exec = 0;
+	}
 }
 
 int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthreads)
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index 8dfec05..d7f93ce 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -84,6 +84,7 @@ struct perf_evsel {
 	bool 			supported;
 	bool 			needs_swap;
 	bool			no_aux_samples;
+	bool			immediate;
 	/* parse modifier helper */
 	int			exclude_GH;
 	int			nr_members;

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

* [tip:perf/core] perf machine: Fix map groups of threads with unknown pids
  2014-07-16  8:07         ` [PATCH V2 " Adrian Hunter
@ 2014-07-18  4:26           ` tip-bot for Adrian Hunter
  0 siblings, 0 replies; 122+ messages in thread
From: tip-bot for Adrian Hunter @ 2014-07-18  4:26 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: acme, linux-kernel, eranian, paulus, hpa, mingo, peterz,
	namhyung, jolsa, fweisbec, adrian.hunter, dsahern, tglx

Commit-ID:  29ce36121e6738012aaf00d983d25260627f2b0d
Gitweb:     http://git.kernel.org/tip/29ce36121e6738012aaf00d983d25260627f2b0d
Author:     Adrian Hunter <adrian.hunter@intel.com>
AuthorDate: Wed, 16 Jul 2014 11:07:13 +0300
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Thu, 17 Jul 2014 10:31:02 -0300

perf machine: Fix map groups of threads with unknown pids

Events like sched_switch do not provide a pid (tgid) which can result in
threads with an unknown pid.  If the pid is later discovered, join the
map groups.

Note the thread's map groups should be empty because they are populated
by MMAP events which do provide the pid and tid.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/r/1405498033-23817-1-git-send-email-adrian.hunter@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/machine.c | 57 ++++++++++++++++++++++++++++++++++++++++++-----
 tools/perf/util/map.c     | 14 ++++++++++++
 tools/perf/util/map.h     |  1 +
 3 files changed, 66 insertions(+), 6 deletions(-)

diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index 5b80877..5484fa4 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -272,6 +272,52 @@ void machines__set_id_hdr_size(struct machines *machines, u16 id_hdr_size)
 	return;
 }
 
+static void machine__update_thread_pid(struct machine *machine,
+				       struct thread *th, pid_t pid)
+{
+	struct thread *leader;
+
+	if (pid == th->pid_ || pid == -1 || th->pid_ != -1)
+		return;
+
+	th->pid_ = pid;
+
+	if (th->pid_ == th->tid)
+		return;
+
+	leader = machine__findnew_thread(machine, th->pid_, th->pid_);
+	if (!leader)
+		goto out_err;
+
+	if (!leader->mg)
+		leader->mg = map_groups__new();
+
+	if (!leader->mg)
+		goto out_err;
+
+	if (th->mg == leader->mg)
+		return;
+
+	if (th->mg) {
+		/*
+		 * Maps are created from MMAP events which provide the pid and
+		 * tid.  Consequently there never should be any maps on a thread
+		 * with an unknown pid.  Just print an error if there are.
+		 */
+		if (!map_groups__empty(th->mg))
+			pr_err("Discarding thread maps for %d:%d\n",
+			       th->pid_, th->tid);
+		map_groups__delete(th->mg);
+	}
+
+	th->mg = map_groups__get(leader->mg);
+
+	return;
+
+out_err:
+	pr_err("Failed to join map groups for %d:%d\n", th->pid_, th->tid);
+}
+
 static struct thread *__machine__findnew_thread(struct machine *machine,
 						pid_t pid, pid_t tid,
 						bool create)
@@ -285,10 +331,10 @@ static struct thread *__machine__findnew_thread(struct machine *machine,
 	 * so most of the time we dont have to look up
 	 * the full rbtree:
 	 */
-	if (machine->last_match && machine->last_match->tid == tid) {
-		if (pid != -1 && pid != machine->last_match->pid_)
-			machine->last_match->pid_ = pid;
-		return machine->last_match;
+	th = machine->last_match;
+	if (th && th->tid == tid) {
+		machine__update_thread_pid(machine, th, pid);
+		return th;
 	}
 
 	while (*p != NULL) {
@@ -297,8 +343,7 @@ static struct thread *__machine__findnew_thread(struct machine *machine,
 
 		if (th->tid == tid) {
 			machine->last_match = th;
-			if (pid != -1 && pid != th->pid_)
-				th->pid_ = pid;
+			machine__update_thread_pid(machine, th, pid);
 			return th;
 		}
 
diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c
index 25c571f..7af1480 100644
--- a/tools/perf/util/map.c
+++ b/tools/perf/util/map.c
@@ -454,6 +454,20 @@ void map_groups__exit(struct map_groups *mg)
 	}
 }
 
+bool map_groups__empty(struct map_groups *mg)
+{
+	int i;
+
+	for (i = 0; i < MAP__NR_TYPES; ++i) {
+		if (maps__first(&mg->maps[i]))
+			return false;
+		if (!list_empty(&mg->removed_maps[i]))
+			return false;
+	}
+
+	return true;
+}
+
 struct map_groups *map_groups__new(void)
 {
 	struct map_groups *mg = malloc(sizeof(*mg));
diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h
index 7758c72..5806a90 100644
--- a/tools/perf/util/map.h
+++ b/tools/perf/util/map.h
@@ -66,6 +66,7 @@ struct map_groups {
 
 struct map_groups *map_groups__new(void);
 void map_groups__delete(struct map_groups *mg);
+bool map_groups__empty(struct map_groups *mg);
 
 static inline struct map_groups *map_groups__get(struct map_groups *mg)
 {

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

* [tip:perf/core] perf thread: Allow deletion of a thread with no map groups
  2014-07-16  7:19       ` [PATCH 1/2] " Adrian Hunter
@ 2014-07-18  4:27         ` tip-bot for Adrian Hunter
  0 siblings, 0 replies; 122+ messages in thread
From: tip-bot for Adrian Hunter @ 2014-07-18  4:27 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: acme, linux-kernel, eranian, paulus, hpa, mingo, peterz,
	namhyung, jolsa, fweisbec, adrian.hunter, dsahern, tglx

Commit-ID:  9608b84e4dd95341b88cad646b114811f5bccbba
Gitweb:     http://git.kernel.org/tip/9608b84e4dd95341b88cad646b114811f5bccbba
Author:     Adrian Hunter <adrian.hunter@intel.com>
AuthorDate: Wed, 16 Jul 2014 10:19:43 +0300
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Thu, 17 Jul 2014 10:32:35 -0300

perf thread: Allow deletion of a thread with no map groups

It needs to be possible to call thread__delete() on a thread with no map
groups.

This is needed for a subsequent patch which deletes a thread on the
error path before map groups have been attached.

Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/r/1405495184-20441-2-git-send-email-adrian.hunter@intel.com
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/thread.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c
index 7a32f44..b9c36ef 100644
--- a/tools/perf/util/thread.c
+++ b/tools/perf/util/thread.c
@@ -60,8 +60,10 @@ void thread__delete(struct thread *thread)
 {
 	struct comm *comm, *tmp;
 
-	map_groups__put(thread->mg);
-	thread->mg = NULL;
+	if (thread->mg) {
+		map_groups__put(thread->mg);
+		thread->mg = NULL;
+	}
 	list_for_each_entry_safe(comm, tmp, &thread->comm_list, list) {
 		list_del(&comm->list);
 		comm__free(comm);

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

* [tip:perf/core] perf machine: Fix leak of 'struct thread' on error path
  2014-07-16  7:19       ` [PATCH V2 2/2] perf tools: Fix leak of 'struct thread' on error path Adrian Hunter
@ 2014-07-18  4:27         ` tip-bot for Adrian Hunter
  0 siblings, 0 replies; 122+ messages in thread
From: tip-bot for Adrian Hunter @ 2014-07-18  4:27 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: acme, linux-kernel, eranian, paulus, hpa, mingo, peterz,
	namhyung, jolsa, fweisbec, adrian.hunter, dsahern, tglx

Commit-ID:  418029b7324f8b90ac1dfbc8a44555d6905be761
Gitweb:     http://git.kernel.org/tip/418029b7324f8b90ac1dfbc8a44555d6905be761
Author:     Adrian Hunter <adrian.hunter@intel.com>
AuthorDate: Wed, 16 Jul 2014 10:19:44 +0300
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Thu, 17 Jul 2014 10:34:07 -0300

perf machine: Fix leak of 'struct thread' on error path

__machine__findnew_thread() creates a 'struct thread' but does not free
it on the error path. Fix it.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/r/1405495184-20441-3-git-send-email-adrian.hunter@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/machine.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index 5484fa4..93c8b6f 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -370,8 +370,10 @@ static struct thread *__machine__findnew_thread(struct machine *machine,
 		 * within thread__init_map_groups to find the thread
 		 * leader and that would screwed the rb tree.
 		 */
-		if (thread__init_map_groups(th, machine))
+		if (thread__init_map_groups(th, machine)) {
+			thread__delete(th);
 			return NULL;
+		}
 	}
 
 	return th;

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

* [tip:perf/core] perf tools: Allow TSC conversion on any arch
  2014-07-14 10:03 ` [PATCH 39/41] perf tools: Allow TSC conversion on any arch Adrian Hunter
  2014-07-15 15:20   ` Arnaldo Carvalho de Melo
@ 2014-07-18  4:28   ` tip-bot for Adrian Hunter
  1 sibling, 0 replies; 122+ messages in thread
From: tip-bot for Adrian Hunter @ 2014-07-18  4:28 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: acme, linux-kernel, eranian, paulus, hpa, mingo, peterz,
	namhyung, jolsa, fweisbec, adrian.hunter, dsahern, tglx

Commit-ID:  0b437860818dc717f6a9e8a5089223a8414f5fff
Gitweb:     http://git.kernel.org/tip/0b437860818dc717f6a9e8a5089223a8414f5fff
Author:     Adrian Hunter <adrian.hunter@intel.com>
AuthorDate: Mon, 14 Jul 2014 13:03:03 +0300
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Thu, 17 Jul 2014 12:59:00 -0300

perf tools: Allow TSC conversion on any arch

It is possible to record a perf.data file on one architecture and
process it on another.

Consequently, TSC conversion functions need to be moved out of the arch
directory.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/r/1405332185-4050-40-git-send-email-adrian.hunter@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/Makefile.perf            |  2 ++
 tools/perf/arch/x86/util/tsc.c      | 22 +---------------------
 tools/perf/arch/x86/util/tsc.h      |  3 ---
 tools/perf/tests/perf-time-to-tsc.c |  3 +--
 tools/perf/util/tsc.c               | 25 +++++++++++++++++++++++++
 tools/perf/util/tsc.h               | 11 +++++++++++
 6 files changed, 40 insertions(+), 26 deletions(-)

diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index 90c4983..3308b22 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -295,6 +295,7 @@ LIB_H += util/intlist.h
 LIB_H += util/perf_regs.h
 LIB_H += util/unwind.h
 LIB_H += util/vdso.h
+LIB_H += util/tsc.h
 LIB_H += ui/helpline.h
 LIB_H += ui/progress.h
 LIB_H += ui/util.h
@@ -374,6 +375,7 @@ LIB_OBJS += $(OUTPUT)util/stat.o
 LIB_OBJS += $(OUTPUT)util/record.o
 LIB_OBJS += $(OUTPUT)util/srcline.o
 LIB_OBJS += $(OUTPUT)util/data.o
+LIB_OBJS += $(OUTPUT)util/tsc.o
 
 LIB_OBJS += $(OUTPUT)ui/setup.o
 LIB_OBJS += $(OUTPUT)ui/helpline.o
diff --git a/tools/perf/arch/x86/util/tsc.c b/tools/perf/arch/x86/util/tsc.c
index 40021fa..3655f24 100644
--- a/tools/perf/arch/x86/util/tsc.c
+++ b/tools/perf/arch/x86/util/tsc.c
@@ -6,29 +6,9 @@
 #include "../../perf.h"
 #include <linux/types.h>
 #include "../../util/debug.h"
+#include "../../util/tsc.h"
 #include "tsc.h"
 
-u64 perf_time_to_tsc(u64 ns, struct perf_tsc_conversion *tc)
-{
-	u64 t, quot, rem;
-
-	t = ns - tc->time_zero;
-	quot = t / tc->time_mult;
-	rem  = t % tc->time_mult;
-	return (quot << tc->time_shift) +
-	       (rem << tc->time_shift) / tc->time_mult;
-}
-
-u64 tsc_to_perf_time(u64 cyc, struct perf_tsc_conversion *tc)
-{
-	u64 quot, rem;
-
-	quot = cyc >> tc->time_shift;
-	rem  = cyc & ((1 << tc->time_shift) - 1);
-	return tc->time_zero + quot * tc->time_mult +
-	       ((rem * tc->time_mult) >> tc->time_shift);
-}
-
 int perf_read_tsc_conversion(const struct perf_event_mmap_page *pc,
 			     struct perf_tsc_conversion *tc)
 {
diff --git a/tools/perf/arch/x86/util/tsc.h b/tools/perf/arch/x86/util/tsc.h
index 2affe03..2edc4d3 100644
--- a/tools/perf/arch/x86/util/tsc.h
+++ b/tools/perf/arch/x86/util/tsc.h
@@ -14,7 +14,4 @@ struct perf_event_mmap_page;
 int perf_read_tsc_conversion(const struct perf_event_mmap_page *pc,
 			     struct perf_tsc_conversion *tc);
 
-u64 perf_time_to_tsc(u64 ns, struct perf_tsc_conversion *tc);
-u64 tsc_to_perf_time(u64 cyc, struct perf_tsc_conversion *tc);
-
 #endif /* TOOLS_PERF_ARCH_X86_UTIL_TSC_H__ */
diff --git a/tools/perf/tests/perf-time-to-tsc.c b/tools/perf/tests/perf-time-to-tsc.c
index 3b7cd4d..0372f6e 100644
--- a/tools/perf/tests/perf-time-to-tsc.c
+++ b/tools/perf/tests/perf-time-to-tsc.c
@@ -8,10 +8,9 @@
 #include "evsel.h"
 #include "thread_map.h"
 #include "cpumap.h"
+#include "tsc.h"
 #include "tests.h"
 
-#include "../arch/x86/util/tsc.h"
-
 #define CHECK__(x) {				\
 	while ((x) < 0) {			\
 		pr_debug(#x " failed!\n");	\
diff --git a/tools/perf/util/tsc.c b/tools/perf/util/tsc.c
new file mode 100644
index 0000000..ef4749836
--- /dev/null
+++ b/tools/perf/util/tsc.c
@@ -0,0 +1,25 @@
+#include <linux/compiler.h>
+#include <linux/types.h>
+
+#include "tsc.h"
+
+u64 perf_time_to_tsc(u64 ns, struct perf_tsc_conversion *tc)
+{
+	u64 t, quot, rem;
+
+	t = ns - tc->time_zero;
+	quot = t / tc->time_mult;
+	rem  = t % tc->time_mult;
+	return (quot << tc->time_shift) +
+	       (rem << tc->time_shift) / tc->time_mult;
+}
+
+u64 tsc_to_perf_time(u64 cyc, struct perf_tsc_conversion *tc)
+{
+	u64 quot, rem;
+
+	quot = cyc >> tc->time_shift;
+	rem  = cyc & ((1 << tc->time_shift) - 1);
+	return tc->time_zero + quot * tc->time_mult +
+	       ((rem * tc->time_mult) >> tc->time_shift);
+}
diff --git a/tools/perf/util/tsc.h b/tools/perf/util/tsc.h
new file mode 100644
index 0000000..4eca848
--- /dev/null
+++ b/tools/perf/util/tsc.h
@@ -0,0 +1,11 @@
+#ifndef __PERF_TSC_H
+#define __PERF_TSC_H
+
+#include <linux/types.h>
+
+#include "../arch/x86/util/tsc.h"
+
+u64 perf_time_to_tsc(u64 ns, struct perf_tsc_conversion *tc);
+u64 tsc_to_perf_time(u64 cyc, struct perf_tsc_conversion *tc);
+
+#endif

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

* Re: [PATCH 1/2] perf tools: Fix incorrect fd error comparison
  2014-07-17  8:43       ` [PATCH 1/2] " Adrian Hunter
@ 2014-07-22  7:51         ` Jiri Olsa
  2014-07-28  8:21         ` [tip:perf/core] " tip-bot for Adrian Hunter
  1 sibling, 0 replies; 122+ messages in thread
From: Jiri Olsa @ 2014-07-22  7:51 UTC (permalink / raw)
  To: Adrian Hunter
  Cc: Arnaldo Carvalho de Melo, Peter Zijlstra, David Ahern,
	Frederic Weisbecker, Namhyung Kim, Paul Mackerras,
	Stephane Eranian, linux-kernel

On Thu, Jul 17, 2014 at 11:43:09AM +0300, Adrian Hunter wrote:
> Zero is a valid fd.  Error comparison should check
> for negative fd.
> 
> Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>

Acked-by: Jiri Olsa <jolsa@kernel.org>

thanks,
jirka

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

* Re: [PATCH V3] perf tools: Record whether a dso has data
  2014-07-17  8:58         ` [PATCH V3] " Adrian Hunter
@ 2014-07-22  7:55           ` Jiri Olsa
  2014-07-22 13:24             ` Adrian Hunter
  0 siblings, 1 reply; 122+ messages in thread
From: Jiri Olsa @ 2014-07-22  7:55 UTC (permalink / raw)
  To: Adrian Hunter
  Cc: Arnaldo Carvalho de Melo, Peter Zijlstra, David Ahern,
	Frederic Weisbecker, Namhyung Kim, Paul Mackerras,
	Stephane Eranian, linux-kernel

On Thu, Jul 17, 2014 at 11:58:30AM +0300, Adrian Hunter wrote:
> Add 'data_status' to record whether a dso has data
> (i.e. an object file)

I might have seen it in your last patsent, but forgot.. what is
this data_status going to be used for?

SNIP

> diff --git a/tools/perf/util/dso.h b/tools/perf/util/dso.h
> index c239e86..07d0a58 100644
> --- a/tools/perf/util/dso.h
> +++ b/tools/perf/util/dso.h
> @@ -40,6 +40,12 @@ enum dso_swap_type {
>  	DSO_SWAP__YES,
>  };
>  
> +enum dso_data_status {
> +	DSO_DATA_STATUS_ERROR	= -1,
> +	DSO_DATA_STATUS_UNKNOWN	= 0,
> +	DSO_DATA_STATUS_OK	= 1,
> +};
> +
>  #define DSO__SWAP(dso, type, val)			\
>  ({							\
>  	type ____r = val;				\
> @@ -104,6 +110,7 @@ struct dso {
>  	struct {
>  		struct rb_root	 cache;
>  		int		 fd;
> +		int		 data_status;

also please call it just 'status' it's already in 'data' struct

thanks,
jirka

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

* Re: [PATCH V3] perf tools: Record whether a dso has data
  2014-07-22  7:55           ` Jiri Olsa
@ 2014-07-22 13:24             ` Adrian Hunter
  0 siblings, 0 replies; 122+ messages in thread
From: Adrian Hunter @ 2014-07-22 13:24 UTC (permalink / raw)
  To: Jiri Olsa
  Cc: Arnaldo Carvalho de Melo, Peter Zijlstra, David Ahern,
	Frederic Weisbecker, Namhyung Kim, Paul Mackerras,
	Stephane Eranian, linux-kernel

On 07/22/2014 10:55 AM, Jiri Olsa wrote:
> On Thu, Jul 17, 2014 at 11:58:30AM +0300, Adrian Hunter wrote:
>> Add 'data_status' to record whether a dso has data
>> (i.e. an object file)
> 
> I might have seen it in your last patsent, but forgot.. what is
> this data_status going to be used for?

I have changed it a bit in the latest posting.  It was originally
for two purposes:
	1. to prevent repeatedly attempting to open a file that
was not there (very time consuming if you do it millions of times)
	2. to report the error exactly once

But I realized it did not meet the 2nd objective so I have added
another patch that does.  See "perf tools: Add dso__data_status_seen()"

> 
> SNIP
> 
>> diff --git a/tools/perf/util/dso.h b/tools/perf/util/dso.h
>> index c239e86..07d0a58 100644
>> --- a/tools/perf/util/dso.h
>> +++ b/tools/perf/util/dso.h
>> @@ -40,6 +40,12 @@ enum dso_swap_type {
>>  	DSO_SWAP__YES,
>>  };
>>  
>> +enum dso_data_status {
>> +	DSO_DATA_STATUS_ERROR	= -1,
>> +	DSO_DATA_STATUS_UNKNOWN	= 0,
>> +	DSO_DATA_STATUS_OK	= 1,
>> +};
>> +
>>  #define DSO__SWAP(dso, type, val)			\
>>  ({							\
>>  	type ____r = val;				\
>> @@ -104,6 +110,7 @@ struct dso {
>>  	struct {
>>  		struct rb_root	 cache;
>>  		int		 fd;
>> +		int		 data_status;
> 
> also please call it just 'status' it's already in 'data' struct

I made that change too.



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

* Re: [PATCH 05/41] perf tools: Identify which comms are from exec
  2014-07-15 11:43     ` Adrian Hunter
@ 2014-07-23 14:07       ` Arnaldo Carvalho de Melo
  2014-07-23 14:09         ` Arnaldo Carvalho de Melo
  0 siblings, 1 reply; 122+ messages in thread
From: Arnaldo Carvalho de Melo @ 2014-07-23 14:07 UTC (permalink / raw)
  To: Adrian Hunter
  Cc: Peter Zijlstra, linux-kernel, David Ahern, Frederic Weisbecker,
	Jiri Olsa, Namhyung Kim, Paul Mackerras, Stephane Eranian

Em Tue, Jul 15, 2014 at 02:43:08PM +0300, Adrian Hunter escreveu:
> >> @@ -106,6 +107,8 @@ int comm__override(struct comm *comm, const char *str, u64 timestamp)
> >>  	comm_str__put(old);
> >>  	comm->comm_str = new;
> >>  	comm->start = timestamp;
> >> +	if (exec && !comm->exec)
> >> +		comm->exec = true;

> > Why do you need the !comm->exec test?
 
> Dunno

I saw that you kept it in the last patchkit submitted, I'll just drop
it, needless obfuscation.

- Arnaldo

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

* Re: [PATCH 05/41] perf tools: Identify which comms are from exec
  2014-07-23 14:07       ` Arnaldo Carvalho de Melo
@ 2014-07-23 14:09         ` Arnaldo Carvalho de Melo
  2014-07-23 16:46           ` Adrian Hunter
  0 siblings, 1 reply; 122+ messages in thread
From: Arnaldo Carvalho de Melo @ 2014-07-23 14:09 UTC (permalink / raw)
  To: Adrian Hunter
  Cc: Peter Zijlstra, linux-kernel, David Ahern, Frederic Weisbecker,
	Jiri Olsa, Namhyung Kim, Paul Mackerras, Stephane Eranian

Em Wed, Jul 23, 2014 at 11:07:52AM -0300, Arnaldo Carvalho de Melo escreveu:
> Em Tue, Jul 15, 2014 at 02:43:08PM +0300, Adrian Hunter escreveu:
> > >> @@ -106,6 +107,8 @@ int comm__override(struct comm *comm, const char *str, u64 timestamp)
> > >>  	comm_str__put(old);
> > >>  	comm->comm_str = new;
> > >>  	comm->start = timestamp;
> > >> +	if (exec && !comm->exec)
> > >> +		comm->exec = true;
> 
> > > Why do you need the !comm->exec test?
>  
> > Dunno
> 
> I saw that you kept it in the last patchkit submitted, I'll just drop
> it, needless obfuscation.

Also why do you need to "identify which comms are from exec", was it
good for?

- Arnaldo

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

* Re: [PATCH 05/41] perf tools: Identify which comms are from exec
  2014-07-23 14:09         ` Arnaldo Carvalho de Melo
@ 2014-07-23 16:46           ` Adrian Hunter
  2014-07-23 16:53             ` Arnaldo Carvalho de Melo
  0 siblings, 1 reply; 122+ messages in thread
From: Adrian Hunter @ 2014-07-23 16:46 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Peter Zijlstra, linux-kernel, David Ahern, Frederic Weisbecker,
	Jiri Olsa, Namhyung Kim, Paul Mackerras, Stephane Eranian

On 23/07/2014 5:09 p.m., Arnaldo Carvalho de Melo wrote:
> Em Wed, Jul 23, 2014 at 11:07:52AM -0300, Arnaldo Carvalho de Melo escreveu:
>> Em Tue, Jul 15, 2014 at 02:43:08PM +0300, Adrian Hunter escreveu:
>>>>> @@ -106,6 +107,8 @@ int comm__override(struct comm *comm, const char *str, u64 timestamp)
>>>>>   	comm_str__put(old);
>>>>>   	comm->comm_str = new;
>>>>>   	comm->start = timestamp;
>>>>> +	if (exec && !comm->exec)
>>>>> +		comm->exec = true;
>>
>>>> Why do you need the !comm->exec test?
>>
>>> Dunno
>>
>> I saw that you kept it in the last patchkit submitted, I'll just drop
>> it, needless obfuscation.

Sorry I forgot.

>
> Also why do you need to "identify which comms are from exec", was it
> good for?

It is for grouping together all the data from a single execution, which
is needed for pairing calls and returns e.g. any outstanding calls when
a process exec's will never return.

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

* Re: [PATCH 05/41] perf tools: Identify which comms are from exec
  2014-07-23 16:46           ` Adrian Hunter
@ 2014-07-23 16:53             ` Arnaldo Carvalho de Melo
  0 siblings, 0 replies; 122+ messages in thread
From: Arnaldo Carvalho de Melo @ 2014-07-23 16:53 UTC (permalink / raw)
  To: Adrian Hunter
  Cc: Peter Zijlstra, linux-kernel, David Ahern, Frederic Weisbecker,
	Jiri Olsa, Namhyung Kim, Paul Mackerras, Stephane Eranian

Em Wed, Jul 23, 2014 at 07:46:43PM +0300, Adrian Hunter escreveu:
> On 23/07/2014 5:09 p.m., Arnaldo Carvalho de Melo wrote:
> >Em Wed, Jul 23, 2014 at 11:07:52AM -0300, Arnaldo Carvalho de Melo escreveu:
> >>Em Tue, Jul 15, 2014 at 02:43:08PM +0300, Adrian Hunter escreveu:
> >>>>>@@ -106,6 +107,8 @@ int comm__override(struct comm *comm, const char *str, u64 timestamp)
> >>>>>  	comm_str__put(old);
> >>>>>  	comm->comm_str = new;
> >>>>>  	comm->start = timestamp;
> >>>>>+	if (exec && !comm->exec)
> >>>>>+		comm->exec = true;

> >>>>Why do you need the !comm->exec test?

> >>>Dunno

> >>I saw that you kept it in the last patchkit submitted, I'll just drop
> >>it, needless obfuscation.
 
> Sorry I forgot.
 
> >Also why do you need to "identify which comms are from exec", was it
> >good for?
 
> It is for grouping together all the data from a single execution, which
> is needed for pairing calls and returns e.g. any outstanding calls when
> a process exec's will never return.

Ok, thanks, I'll add it to the patch log, as I did with some others.

I'll continue after lunch, what I have so far is in the tmp.perf/core in
my tree, at git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux.git

- Arnaldo

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

* [tip:perf/core] perf tools: Fix incorrect fd error comparison
  2014-07-17  8:43       ` [PATCH 1/2] " Adrian Hunter
  2014-07-22  7:51         ` Jiri Olsa
@ 2014-07-28  8:21         ` tip-bot for Adrian Hunter
  1 sibling, 0 replies; 122+ messages in thread
From: tip-bot for Adrian Hunter @ 2014-07-28  8:21 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: acme, linux-kernel, eranian, paulus, hpa, mingo, jolsa, peterz,
	namhyung, jolsa, fweisbec, adrian.hunter, dsahern, tglx

Commit-ID:  a6f6ae99f12e8154d5cde6e8366fc228f68d6ae5
Gitweb:     http://git.kernel.org/tip/a6f6ae99f12e8154d5cde6e8366fc228f68d6ae5
Author:     Adrian Hunter <adrian.hunter@intel.com>
AuthorDate: Thu, 17 Jul 2014 11:43:09 +0300
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Tue, 22 Jul 2014 10:18:57 -0300

perf tools: Fix incorrect fd error comparison

Zero is a valid fd.  Error comparison should check for negative fd.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Acked-by: Jiri Olsa <jolsa@kernel.org>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/r/1405586590-13657-2-git-send-email-adrian.hunter@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/dso.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c
index fc006fe..28cf747 100644
--- a/tools/perf/util/dso.c
+++ b/tools/perf/util/dso.c
@@ -216,7 +216,7 @@ static int open_dso(struct dso *dso, struct machine *machine)
 {
 	int fd = __open_dso(dso, machine);
 
-	if (fd > 0) {
+	if (fd >= 0) {
 		dso__list_add(dso);
 		/*
 		 * Check if we crossed the allowed number

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

* Re: [PATCH 13/41] perf tools: Add machine__kernel_ip()
  2014-07-16 14:22     ` Adrian Hunter
@ 2014-08-11 12:23       ` Jiri Olsa
  2014-08-11 12:36         ` Adrian Hunter
  0 siblings, 1 reply; 122+ messages in thread
From: Jiri Olsa @ 2014-08-11 12:23 UTC (permalink / raw)
  To: Adrian Hunter
  Cc: Arnaldo Carvalho de Melo, Peter Zijlstra, linux-kernel,
	David Ahern, Frederic Weisbecker, Namhyung Kim, Paul Mackerras,
	Stephane Eranian

On Wed, Jul 16, 2014 at 05:22:22PM +0300, Adrian Hunter wrote:
> On 16/07/2014 5:15 p.m., Jiri Olsa wrote:
> >On Mon, Jul 14, 2014 at 01:02:37PM +0300, Adrian Hunter wrote:
> >
> >SNIP
> >
> >>+
> >>+int machine__get_kernel_start(struct machine *machine)
> >>+{
> >>+	struct map *map = machine__kernel_map(machine, MAP__FUNCTION);
> >>+	int err = 0;
> >>+
> >>+	/*
> >>+	 * The only addresses above 2^63 are kernel addresses of a 64-bit
> >>+	 * kernel.  Note that addresses are unsigned so that on a 32-bit system
> >>+	 * all addresses including kernel addresses are less than 2^32.  In
> >>+	 * that case (32-bit system), if the kernel mapping is unknown, all
> >>+	 * addresses will be assumed to be in user space - see
> >>+	 * machine__kernel_ip().
> >>+	 */
> >>+	machine->kernel_start = 1ULL << 63;
> >>+	if (map) {
> >>+		err = map__load(map, machine->symbol_filter);
> >>+		if (map->start)
> >>+			machine->kernel_start = map->start;
> >>+	}
> >>+	return err;
> >>+}
> >
> >we just recently got machine__get_kernel_start_addr function,
> >I think we want just one function for this
> 
> They do quite different things.
> 

so one of those two should have different name

jirka

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

* Re: [PATCH 13/41] perf tools: Add machine__kernel_ip()
  2014-08-11 12:23       ` Jiri Olsa
@ 2014-08-11 12:36         ` Adrian Hunter
  2014-08-11 12:43           ` Jiri Olsa
  0 siblings, 1 reply; 122+ messages in thread
From: Adrian Hunter @ 2014-08-11 12:36 UTC (permalink / raw)
  To: Jiri Olsa
  Cc: Arnaldo Carvalho de Melo, Peter Zijlstra, linux-kernel,
	David Ahern, Frederic Weisbecker, Namhyung Kim, Paul Mackerras,
	Stephane Eranian

On 08/11/2014 03:23 PM, Jiri Olsa wrote:
> On Wed, Jul 16, 2014 at 05:22:22PM +0300, Adrian Hunter wrote:
>> On 16/07/2014 5:15 p.m., Jiri Olsa wrote:
>>> On Mon, Jul 14, 2014 at 01:02:37PM +0300, Adrian Hunter wrote:
>>>
>>> SNIP
>>>
>>>> +
>>>> +int machine__get_kernel_start(struct machine *machine)
>>>> +{
>>>> +	struct map *map = machine__kernel_map(machine, MAP__FUNCTION);
>>>> +	int err = 0;
>>>> +
>>>> +	/*
>>>> +	 * The only addresses above 2^63 are kernel addresses of a 64-bit
>>>> +	 * kernel.  Note that addresses are unsigned so that on a 32-bit system
>>>> +	 * all addresses including kernel addresses are less than 2^32.  In
>>>> +	 * that case (32-bit system), if the kernel mapping is unknown, all
>>>> +	 * addresses will be assumed to be in user space - see
>>>> +	 * machine__kernel_ip().
>>>> +	 */
>>>> +	machine->kernel_start = 1ULL << 63;
>>>> +	if (map) {
>>>> +		err = map__load(map, machine->symbol_filter);
>>>> +		if (map->start)
>>>> +			machine->kernel_start = map->start;
>>>> +	}
>>>> +	return err;
>>>> +}
>>>
>>> we just recently got machine__get_kernel_start_addr function,
>>> I think we want just one function for this
>>
>> They do quite different things.
>>
> 
> so one of those two should have different name

Such as?


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

* Re: [PATCH 13/41] perf tools: Add machine__kernel_ip()
  2014-08-11 12:36         ` Adrian Hunter
@ 2014-08-11 12:43           ` Jiri Olsa
  2014-08-11 12:46             ` Adrian Hunter
  0 siblings, 1 reply; 122+ messages in thread
From: Jiri Olsa @ 2014-08-11 12:43 UTC (permalink / raw)
  To: Adrian Hunter
  Cc: Arnaldo Carvalho de Melo, Peter Zijlstra, linux-kernel,
	David Ahern, Frederic Weisbecker, Namhyung Kim, Paul Mackerras,
	Stephane Eranian

On Mon, Aug 11, 2014 at 03:36:40PM +0300, Adrian Hunter wrote:
> On 08/11/2014 03:23 PM, Jiri Olsa wrote:
> > On Wed, Jul 16, 2014 at 05:22:22PM +0300, Adrian Hunter wrote:
> >> On 16/07/2014 5:15 p.m., Jiri Olsa wrote:
> >>> On Mon, Jul 14, 2014 at 01:02:37PM +0300, Adrian Hunter wrote:
> >>>
> >>> SNIP
> >>>
> >>>> +
> >>>> +int machine__get_kernel_start(struct machine *machine)
> >>>> +{
> >>>> +	struct map *map = machine__kernel_map(machine, MAP__FUNCTION);
> >>>> +	int err = 0;
> >>>> +
> >>>> +	/*
> >>>> +	 * The only addresses above 2^63 are kernel addresses of a 64-bit
> >>>> +	 * kernel.  Note that addresses are unsigned so that on a 32-bit system
> >>>> +	 * all addresses including kernel addresses are less than 2^32.  In
> >>>> +	 * that case (32-bit system), if the kernel mapping is unknown, all
> >>>> +	 * addresses will be assumed to be in user space - see
> >>>> +	 * machine__kernel_ip().
> >>>> +	 */
> >>>> +	machine->kernel_start = 1ULL << 63;
> >>>> +	if (map) {
> >>>> +		err = map__load(map, machine->symbol_filter);
> >>>> +		if (map->start)
> >>>> +			machine->kernel_start = map->start;
> >>>> +	}
> >>>> +	return err;
> >>>> +}
> >>>
> >>> we just recently got machine__get_kernel_start_addr function,
> >>> I think we want just one function for this
> >>
> >> They do quite different things.
> >>
> > 
> > so one of those two should have different name
> 
> Such as?

dont know ;-) but if they do 'quite different things' as u said,
I expect to see that at least in the function name

jirka

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

* Re: [PATCH 13/41] perf tools: Add machine__kernel_ip()
  2014-08-11 12:43           ` Jiri Olsa
@ 2014-08-11 12:46             ` Adrian Hunter
  2014-08-11 12:55               ` Jiri Olsa
  0 siblings, 1 reply; 122+ messages in thread
From: Adrian Hunter @ 2014-08-11 12:46 UTC (permalink / raw)
  To: Jiri Olsa
  Cc: Arnaldo Carvalho de Melo, Peter Zijlstra, linux-kernel,
	David Ahern, Frederic Weisbecker, Namhyung Kim, Paul Mackerras,
	Stephane Eranian

On 08/11/2014 03:43 PM, Jiri Olsa wrote:
> On Mon, Aug 11, 2014 at 03:36:40PM +0300, Adrian Hunter wrote:
>> On 08/11/2014 03:23 PM, Jiri Olsa wrote:
>>> On Wed, Jul 16, 2014 at 05:22:22PM +0300, Adrian Hunter wrote:
>>>> On 16/07/2014 5:15 p.m., Jiri Olsa wrote:
>>>>> On Mon, Jul 14, 2014 at 01:02:37PM +0300, Adrian Hunter wrote:
>>>>>
>>>>> SNIP
>>>>>
>>>>>> +
>>>>>> +int machine__get_kernel_start(struct machine *machine)
>>>>>> +{
>>>>>> +	struct map *map = machine__kernel_map(machine, MAP__FUNCTION);
>>>>>> +	int err = 0;
>>>>>> +
>>>>>> +	/*
>>>>>> +	 * The only addresses above 2^63 are kernel addresses of a 64-bit
>>>>>> +	 * kernel.  Note that addresses are unsigned so that on a 32-bit system
>>>>>> +	 * all addresses including kernel addresses are less than 2^32.  In
>>>>>> +	 * that case (32-bit system), if the kernel mapping is unknown, all
>>>>>> +	 * addresses will be assumed to be in user space - see
>>>>>> +	 * machine__kernel_ip().
>>>>>> +	 */
>>>>>> +	machine->kernel_start = 1ULL << 63;
>>>>>> +	if (map) {
>>>>>> +		err = map__load(map, machine->symbol_filter);
>>>>>> +		if (map->start)
>>>>>> +			machine->kernel_start = map->start;
>>>>>> +	}
>>>>>> +	return err;
>>>>>> +}
>>>>>
>>>>> we just recently got machine__get_kernel_start_addr function,
>>>>> I think we want just one function for this
>>>>
>>>> They do quite different things.
>>>>
>>>
>>> so one of those two should have different name
>>
>> Such as?
> 
> dont know ;-) but if they do 'quite different things' as u said,
> I expect to see that at least in the function name

How about:

	machine__get_kernel_start_addr -> machine__get_running_kernel_start



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

* Re: [PATCH 13/41] perf tools: Add machine__kernel_ip()
  2014-08-11 12:46             ` Adrian Hunter
@ 2014-08-11 12:55               ` Jiri Olsa
  0 siblings, 0 replies; 122+ messages in thread
From: Jiri Olsa @ 2014-08-11 12:55 UTC (permalink / raw)
  To: Adrian Hunter
  Cc: Arnaldo Carvalho de Melo, Peter Zijlstra, linux-kernel,
	David Ahern, Frederic Weisbecker, Namhyung Kim, Paul Mackerras,
	Stephane Eranian

On Mon, Aug 11, 2014 at 03:46:44PM +0300, Adrian Hunter wrote:
> On 08/11/2014 03:43 PM, Jiri Olsa wrote:
> > On Mon, Aug 11, 2014 at 03:36:40PM +0300, Adrian Hunter wrote:
> >> On 08/11/2014 03:23 PM, Jiri Olsa wrote:
> >>> On Wed, Jul 16, 2014 at 05:22:22PM +0300, Adrian Hunter wrote:
> >>>> On 16/07/2014 5:15 p.m., Jiri Olsa wrote:
> >>>>> On Mon, Jul 14, 2014 at 01:02:37PM +0300, Adrian Hunter wrote:
> >>>>>
> >>>>> SNIP
> >>>>>
> >>>>>> +
> >>>>>> +int machine__get_kernel_start(struct machine *machine)
> >>>>>> +{
> >>>>>> +	struct map *map = machine__kernel_map(machine, MAP__FUNCTION);
> >>>>>> +	int err = 0;
> >>>>>> +
> >>>>>> +	/*
> >>>>>> +	 * The only addresses above 2^63 are kernel addresses of a 64-bit
> >>>>>> +	 * kernel.  Note that addresses are unsigned so that on a 32-bit system
> >>>>>> +	 * all addresses including kernel addresses are less than 2^32.  In
> >>>>>> +	 * that case (32-bit system), if the kernel mapping is unknown, all
> >>>>>> +	 * addresses will be assumed to be in user space - see
> >>>>>> +	 * machine__kernel_ip().
> >>>>>> +	 */
> >>>>>> +	machine->kernel_start = 1ULL << 63;
> >>>>>> +	if (map) {
> >>>>>> +		err = map__load(map, machine->symbol_filter);
> >>>>>> +		if (map->start)
> >>>>>> +			machine->kernel_start = map->start;
> >>>>>> +	}
> >>>>>> +	return err;
> >>>>>> +}
> >>>>>
> >>>>> we just recently got machine__get_kernel_start_addr function,
> >>>>> I think we want just one function for this
> >>>>
> >>>> They do quite different things.
> >>>>
> >>>
> >>> so one of those two should have different name
> >>
> >> Such as?
> > 
> > dont know ;-) but if they do 'quite different things' as u said,
> > I expect to see that at least in the function name
> 
> How about:
> 
> 	machine__get_kernel_start_addr -> machine__get_running_kernel_start

sounds good

jirka

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

* Re: [PATCH 34/41] perf evlist: Add 'system_wide' option
  2014-07-14 10:02 ` [PATCH 34/41] perf evlist: Add 'system_wide' option Adrian Hunter
  2014-07-15 15:03   ` Arnaldo Carvalho de Melo
@ 2014-08-11 13:12   ` Jiri Olsa
  2014-08-12  5:52     ` Adrian Hunter
  1 sibling, 1 reply; 122+ messages in thread
From: Jiri Olsa @ 2014-08-11 13:12 UTC (permalink / raw)
  To: Adrian Hunter
  Cc: Arnaldo Carvalho de Melo, Peter Zijlstra, linux-kernel,
	David Ahern, Frederic Weisbecker, Namhyung Kim, Paul Mackerras,
	Stephane Eranian

On Mon, Jul 14, 2014 at 01:02:58PM +0300, Adrian Hunter wrote:
> Add an option to cause a selected event
> to be opened always without a pid when
> configured by perf_evsel__config().
> 
> This is needed when using the sched_switch
> tracepoint to follow object code execution.
> sched_switch occurs before the task
> switch and so it cannot record it in a
> context limited to that task.  Note
> that also means that sched_switch is
> useless when capturing data per-thread,
> as is the 'context-switches' software
> event for the same reason.
> 
> Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
> ---
>  tools/perf/util/evlist.c | 45 +++++++++++++++++++++++++++++++++++++--------
>  tools/perf/util/evsel.c  | 31 ++++++++++++++++++++++++++-----
>  tools/perf/util/evsel.h  |  1 +
>  3 files changed, 64 insertions(+), 13 deletions(-)
> 
> diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
> index 282e83e..c295b7b 100644
> --- a/tools/perf/util/evlist.c
> +++ b/tools/perf/util/evlist.c
> @@ -265,17 +265,27 @@ int perf_evlist__add_newtp(struct perf_evlist *evlist,
>  	return 0;
>  }
>  
> +static int perf_evlist__nr_threads(struct perf_evlist *evlist,
> +				   struct perf_evsel *evsel)
> +{
> +	if (evsel->system_wide)
> +		return 1;
> +	else
> +		return thread_map__nr(evlist->threads);
> +}

how is 'evsel->system_wide' set?

jirka

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

* Re: [PATCH 34/41] perf evlist: Add 'system_wide' option
  2014-08-11 13:12   ` Jiri Olsa
@ 2014-08-12  5:52     ` Adrian Hunter
  0 siblings, 0 replies; 122+ messages in thread
From: Adrian Hunter @ 2014-08-12  5:52 UTC (permalink / raw)
  To: Jiri Olsa
  Cc: Arnaldo Carvalho de Melo, Peter Zijlstra, linux-kernel,
	David Ahern, Frederic Weisbecker, Namhyung Kim, Paul Mackerras,
	Stephane Eranian

On 08/11/2014 04:12 PM, Jiri Olsa wrote:
> On Mon, Jul 14, 2014 at 01:02:58PM +0300, Adrian Hunter wrote:
>> Add an option to cause a selected event
>> to be opened always without a pid when
>> configured by perf_evsel__config().
>>
>> This is needed when using the sched_switch
>> tracepoint to follow object code execution.
>> sched_switch occurs before the task
>> switch and so it cannot record it in a
>> context limited to that task.  Note
>> that also means that sched_switch is
>> useless when capturing data per-thread,
>> as is the 'context-switches' software
>> event for the same reason.
>>
>> Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
>> ---
>>  tools/perf/util/evlist.c | 45 +++++++++++++++++++++++++++++++++++++--------
>>  tools/perf/util/evsel.c  | 31 ++++++++++++++++++++++++++-----
>>  tools/perf/util/evsel.h  |  1 +
>>  3 files changed, 64 insertions(+), 13 deletions(-)
>>
>> diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
>> index 282e83e..c295b7b 100644
>> --- a/tools/perf/util/evlist.c
>> +++ b/tools/perf/util/evlist.c
>> @@ -265,17 +265,27 @@ int perf_evlist__add_newtp(struct perf_evlist *evlist,
>>  	return 0;
>>  }
>>  
>> +static int perf_evlist__nr_threads(struct perf_evlist *evlist,
>> +				   struct perf_evsel *evsel)
>> +{
>> +	if (evsel->system_wide)
>> +		return 1;
>> +	else
>> +		return thread_map__nr(evlist->threads);
>> +}
> 
> how is 'evsel->system_wide' set?

Intel PT sets it for the sched_switch event.



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

* Re: [PATCH 20/41] perf tools: Let a user specify a PMU event without any config terms
  2014-07-16 18:22       ` Jiri Olsa
@ 2014-08-29 18:48         ` Adrian Hunter
  2014-08-30  8:53           ` Jiri Olsa
  0 siblings, 1 reply; 122+ messages in thread
From: Adrian Hunter @ 2014-08-29 18:48 UTC (permalink / raw)
  To: Jiri Olsa
  Cc: Arnaldo Carvalho de Melo, Peter Zijlstra, linux-kernel,
	David Ahern, Frederic Weisbecker, Namhyung Kim, Paul Mackerras,
	Stephane Eranian

On 16/07/2014 9:22 p.m., Jiri Olsa wrote:
> On Wed, Jul 16, 2014 at 06:04:44PM +0300, Adrian Hunter wrote:
>> On 16/07/2014 5:25 p.m., Jiri Olsa wrote:
>>> On Mon, Jul 14, 2014 at 01:02:44PM +0300, Adrian Hunter wrote:
>>>> This enables a PMU event to be specified in the form:
>>>>
>>>> 	pmu//
>>>>
>>>> which is effectively the same as:
>>>>
>>>> 	pmu/config=0/
>>>>
>>>> This patch is a precursor to defining
>>>> default config for a PMU.
>>>
>>> I understand the need for default config, but could you please elaborate
>>> why do we want to parse 'pmu//' as an event string string?
>>
>> Currently the parser requires the slashes to identify a PMU event
>> as opposed to a hardware or other kind of event.
>
> right, so why do we want to parse 'pmu//' as an event string? ;-)

I am not sure what you mean.  Here I am using 'pmu' as a placeholder
for a real PMU name.  So actual event strings are 'intel_bts//' or
'intel_pt//' or 'intel_pt/tsc=0,noretcomp=1/'

The parser uses various tricks to decide what kind of event the event
name actually is e.g. colons indicate a tracepoint.

If you are asking why the parser isn't smart enough to know the event
name is a PMU name, I guess it is either to keep the namespaces separate,
or because it was easier to program it that way.

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

* Re: [PATCH 20/41] perf tools: Let a user specify a PMU event without any config terms
  2014-08-29 18:48         ` Adrian Hunter
@ 2014-08-30  8:53           ` Jiri Olsa
  2014-09-01  6:27             ` Adrian Hunter
  2014-09-01 15:51             ` Arnaldo Carvalho de Melo
  0 siblings, 2 replies; 122+ messages in thread
From: Jiri Olsa @ 2014-08-30  8:53 UTC (permalink / raw)
  To: Adrian Hunter
  Cc: Arnaldo Carvalho de Melo, Peter Zijlstra, linux-kernel,
	David Ahern, Frederic Weisbecker, Namhyung Kim, Paul Mackerras,
	Stephane Eranian

On Fri, Aug 29, 2014 at 09:48:51PM +0300, Adrian Hunter wrote:
> On 16/07/2014 9:22 p.m., Jiri Olsa wrote:
> >On Wed, Jul 16, 2014 at 06:04:44PM +0300, Adrian Hunter wrote:
> >>On 16/07/2014 5:25 p.m., Jiri Olsa wrote:
> >>>On Mon, Jul 14, 2014 at 01:02:44PM +0300, Adrian Hunter wrote:
> >>>>This enables a PMU event to be specified in the form:
> >>>>
> >>>>	pmu//
> >>>>
> >>>>which is effectively the same as:
> >>>>
> >>>>	pmu/config=0/
> >>>>
> >>>>This patch is a precursor to defining
> >>>>default config for a PMU.
> >>>
> >>>I understand the need for default config, but could you please elaborate
> >>>why do we want to parse 'pmu//' as an event string string?
> >>
> >>Currently the parser requires the slashes to identify a PMU event
> >>as opposed to a hardware or other kind of event.
> >
> >right, so why do we want to parse 'pmu//' as an event string? ;-)
> 
> I am not sure what you mean.  Here I am using 'pmu' as a placeholder
> for a real PMU name.  So actual event strings are 'intel_bts//' or
> 'intel_pt//' or 'intel_pt/tsc=0,noretcomp=1/'

so the consequence of default arguments is that you can
specify event just by the pmu name, like:
  -e intel_pt//

which means (with default attributes):
  -e intel_pt/tsc=1,noretcomp=0/

I guess I wanted to hear more elaboration why is this better
than the current way we have by defining an alias, like:

  krava alias: "tsc=1,noretcomp=0"

  -e intel_pt/krava/

which gives the same result

thanks,
jirka

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

* Re: [PATCH 20/41] perf tools: Let a user specify a PMU event without any config terms
  2014-08-30  8:53           ` Jiri Olsa
@ 2014-09-01  6:27             ` Adrian Hunter
  2014-09-01 19:11               ` Jiri Olsa
  2014-09-01 15:51             ` Arnaldo Carvalho de Melo
  1 sibling, 1 reply; 122+ messages in thread
From: Adrian Hunter @ 2014-09-01  6:27 UTC (permalink / raw)
  To: Jiri Olsa
  Cc: Arnaldo Carvalho de Melo, Peter Zijlstra, linux-kernel,
	David Ahern, Frederic Weisbecker, Namhyung Kim, Paul Mackerras,
	Stephane Eranian

On 08/30/2014 11:53 AM, Jiri Olsa wrote:
> On Fri, Aug 29, 2014 at 09:48:51PM +0300, Adrian Hunter wrote:
>> On 16/07/2014 9:22 p.m., Jiri Olsa wrote:
>>> On Wed, Jul 16, 2014 at 06:04:44PM +0300, Adrian Hunter wrote:
>>>> On 16/07/2014 5:25 p.m., Jiri Olsa wrote:
>>>>> On Mon, Jul 14, 2014 at 01:02:44PM +0300, Adrian Hunter wrote:
>>>>>> This enables a PMU event to be specified in the form:
>>>>>>
>>>>>> 	pmu//
>>>>>>
>>>>>> which is effectively the same as:
>>>>>>
>>>>>> 	pmu/config=0/
>>>>>>
>>>>>> This patch is a precursor to defining
>>>>>> default config for a PMU.
>>>>>
>>>>> I understand the need for default config, but could you please elaborate
>>>>> why do we want to parse 'pmu//' as an event string string?
>>>>
>>>> Currently the parser requires the slashes to identify a PMU event
>>>> as opposed to a hardware or other kind of event.
>>>
>>> right, so why do we want to parse 'pmu//' as an event string? ;-)
>>
>> I am not sure what you mean.  Here I am using 'pmu' as a placeholder
>> for a real PMU name.  So actual event strings are 'intel_bts//' or
>> 'intel_pt//' or 'intel_pt/tsc=0,noretcomp=1/'
> 
> so the consequence of default arguments is that you can
> specify event just by the pmu name, like:
>   -e intel_pt//
> 
> which means (with default attributes):
>   -e intel_pt/tsc=1,noretcomp=0/
> 
> I guess I wanted to hear more elaboration why is this better
> than the current way we have by defining an alias, like:
> 
>   krava alias: "tsc=1,noretcomp=0"
> 
>   -e intel_pt/krava/
> 
> which gives the same result

The default value must be provided by perf tools not the kernel e.g.
an older version of perf tools will not be aware of new hardware
features that the kernel may know about.  If the kernel enables
new features by default then the tool may fail.  Thus the default
value has to be under the control of the tools not the kernel, so
a sysfs alias will not work.


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

* Re: [PATCH 20/41] perf tools: Let a user specify a PMU event without any config terms
  2014-08-30  8:53           ` Jiri Olsa
  2014-09-01  6:27             ` Adrian Hunter
@ 2014-09-01 15:51             ` Arnaldo Carvalho de Melo
  2014-09-01 19:15               ` Jiri Olsa
  1 sibling, 1 reply; 122+ messages in thread
From: Arnaldo Carvalho de Melo @ 2014-09-01 15:51 UTC (permalink / raw)
  To: Jiri Olsa
  Cc: Adrian Hunter, Peter Zijlstra, linux-kernel, David Ahern,
	Frederic Weisbecker, Namhyung Kim, Paul Mackerras,
	Stephane Eranian

Em Sat, Aug 30, 2014 at 10:53:10AM +0200, Jiri Olsa escreveu:
> On Fri, Aug 29, 2014 at 09:48:51PM +0300, Adrian Hunter wrote:
> > On 16/07/2014 9:22 p.m., Jiri Olsa wrote:
> > >On Wed, Jul 16, 2014 at 06:04:44PM +0300, Adrian Hunter wrote:
> > >>On 16/07/2014 5:25 p.m., Jiri Olsa wrote:
> > >>>On Mon, Jul 14, 2014 at 01:02:44PM +0300, Adrian Hunter wrote:
> > >>>>This enables a PMU event to be specified in the form:

> > >>>>	pmu//

> > >>>>which is effectively the same as:

> > >>>>	pmu/config=0/

> > >>>>This patch is a precursor to defining
> > >>>>default config for a PMU.

> > >>>I understand the need for default config, but could you please elaborate
> > >>>why do we want to parse 'pmu//' as an event string string?

> > >>Currently the parser requires the slashes to identify a PMU event
> > >>as opposed to a hardware or other kind of event.

> > >right, so why do we want to parse 'pmu//' as an event string? ;-)

> > I am not sure what you mean.  Here I am using 'pmu' as a placeholder
> > for a real PMU name.  So actual event strings are 'intel_bts//' or
> > 'intel_pt//' or 'intel_pt/tsc=0,noretcomp=1/'

> so the consequence of default arguments is that you can
> specify event just by the pmu name, like:
>   -e intel_pt//

> which means (with default attributes):
>   -e intel_pt/tsc=1,noretcomp=0/
 
> I guess I wanted to hear more elaboration why is this better
> than the current way we have by defining an alias, like:
 
>   krava alias: "tsc=1,noretcomp=0"
 
>   -e intel_pt/krava/
 
> which gives the same result

So you propose that we start maintaining some table of aliases that
would be installed by default, etc? "krava" would not be a good name, I
think (:-)), so in this case we would have something like:

	defaults_intel_pt: "tsc=1,noretcomp=0"

	-e intel_pt/defaults_intel_pt/

Which of course gets redundant/long, so, using what Adrian suggests, we
would instead not pass anything between the slashes, and that would mean
"default_" concatenated with the name of the PMU used, so it would
become:

	-e intel_pt//

that would be equivalent to:

	-e intel_pt/defaults_intel_pt/

and also to:

	-e intel_pt/tsc=1,noretcomp=0/

?

I have not looked at the implementation, this is all just from the
information I skimmed in this thread.

- Arnaldo

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

* Re: [PATCH 20/41] perf tools: Let a user specify a PMU event without any config terms
  2014-09-01  6:27             ` Adrian Hunter
@ 2014-09-01 19:11               ` Jiri Olsa
  2014-09-02  5:39                 ` Adrian Hunter
  0 siblings, 1 reply; 122+ messages in thread
From: Jiri Olsa @ 2014-09-01 19:11 UTC (permalink / raw)
  To: Adrian Hunter
  Cc: Arnaldo Carvalho de Melo, Peter Zijlstra, linux-kernel,
	David Ahern, Frederic Weisbecker, Namhyung Kim, Paul Mackerras,
	Stephane Eranian

On Mon, Sep 01, 2014 at 09:27:17AM +0300, Adrian Hunter wrote:
> On 08/30/2014 11:53 AM, Jiri Olsa wrote:
> > On Fri, Aug 29, 2014 at 09:48:51PM +0300, Adrian Hunter wrote:
> >> On 16/07/2014 9:22 p.m., Jiri Olsa wrote:
> >>> On Wed, Jul 16, 2014 at 06:04:44PM +0300, Adrian Hunter wrote:
> >>>> On 16/07/2014 5:25 p.m., Jiri Olsa wrote:
> >>>>> On Mon, Jul 14, 2014 at 01:02:44PM +0300, Adrian Hunter wrote:
> >>>>>> This enables a PMU event to be specified in the form:
> >>>>>>
> >>>>>> 	pmu//
> >>>>>>
> >>>>>> which is effectively the same as:
> >>>>>>
> >>>>>> 	pmu/config=0/
> >>>>>>
> >>>>>> This patch is a precursor to defining
> >>>>>> default config for a PMU.
> >>>>>
> >>>>> I understand the need for default config, but could you please elaborate
> >>>>> why do we want to parse 'pmu//' as an event string string?
> >>>>
> >>>> Currently the parser requires the slashes to identify a PMU event
> >>>> as opposed to a hardware or other kind of event.
> >>>
> >>> right, so why do we want to parse 'pmu//' as an event string? ;-)
> >>
> >> I am not sure what you mean.  Here I am using 'pmu' as a placeholder
> >> for a real PMU name.  So actual event strings are 'intel_bts//' or
> >> 'intel_pt//' or 'intel_pt/tsc=0,noretcomp=1/'
> > 
> > so the consequence of default arguments is that you can
> > specify event just by the pmu name, like:
> >   -e intel_pt//
> > 
> > which means (with default attributes):
> >   -e intel_pt/tsc=1,noretcomp=0/
> > 
> > I guess I wanted to hear more elaboration why is this better
> > than the current way we have by defining an alias, like:
> > 
> >   krava alias: "tsc=1,noretcomp=0"
> > 
> >   -e intel_pt/krava/
> > 
> > which gives the same result
> 
> The default value must be provided by perf tools not the kernel e.g.
> an older version of perf tools will not be aware of new hardware
> features that the kernel may know about.  If the kernel enables
> new features by default then the tool may fail.  Thus the default
> value has to be under the control of the tools not the kernel, so
> a sysfs alias will not work.
> 

I dont follow, could u provide some example?

why the tool needs to understand.. it will just take the alias
and apply/use it? The alias follows the format logic, which tells
how to apply values on perf_event_attr.. and the kernel knows best
what's supported in its version..

jirka

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

* Re: [PATCH 20/41] perf tools: Let a user specify a PMU event without any config terms
  2014-09-01 15:51             ` Arnaldo Carvalho de Melo
@ 2014-09-01 19:15               ` Jiri Olsa
  0 siblings, 0 replies; 122+ messages in thread
From: Jiri Olsa @ 2014-09-01 19:15 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Adrian Hunter, Peter Zijlstra, linux-kernel, David Ahern,
	Frederic Weisbecker, Namhyung Kim, Paul Mackerras,
	Stephane Eranian

On Mon, Sep 01, 2014 at 12:51:42PM -0300, Arnaldo Carvalho de Melo wrote:

SNIP

> >   krava alias: "tsc=1,noretcomp=0"
>  
> >   -e intel_pt/krava/
>  
> > which gives the same result
> 
> So you propose that we start maintaining some table of aliases that
> would be installed by default, etc? "krava" would not be a good name, I
> think (:-)), so in this case we would have something like:
> 
> 	defaults_intel_pt: "tsc=1,noretcomp=0"
> 
> 	-e intel_pt/defaults_intel_pt/
> 
> Which of course gets redundant/long, so, using what Adrian suggests, we
> would instead not pass anything between the slashes, and that would mean
> "default_" concatenated with the name of the PMU used, so it would
> become:
> 
> 	-e intel_pt//
> 
> that would be equivalent to:
> 
> 	-e intel_pt/defaults_intel_pt/
> 
> and also to:
> 
> 	-e intel_pt/tsc=1,noretcomp=0/
> 
> ?
> 
> I have not looked at the implementation, this is all just from the
> information I skimmed in this thread.

well I meant that we already have following directory:
  /sys/devices/cpu/events

for aliases.. files with format definitions (even partial)
I can imagine 'default' file there doing the same job
for the default format set

but I just could be missing something which is not apparent
from changelog ;-)

jirka

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

* Re: [PATCH 20/41] perf tools: Let a user specify a PMU event without any config terms
  2014-09-01 19:11               ` Jiri Olsa
@ 2014-09-02  5:39                 ` Adrian Hunter
  2014-09-02  9:17                   ` Jiri Olsa
  0 siblings, 1 reply; 122+ messages in thread
From: Adrian Hunter @ 2014-09-02  5:39 UTC (permalink / raw)
  To: Jiri Olsa
  Cc: Arnaldo Carvalho de Melo, Peter Zijlstra, linux-kernel,
	David Ahern, Frederic Weisbecker, Namhyung Kim, Paul Mackerras,
	Stephane Eranian

On 09/01/2014 10:11 PM, Jiri Olsa wrote:
> On Mon, Sep 01, 2014 at 09:27:17AM +0300, Adrian Hunter wrote:
>> On 08/30/2014 11:53 AM, Jiri Olsa wrote:
>>> On Fri, Aug 29, 2014 at 09:48:51PM +0300, Adrian Hunter wrote:
>>>> On 16/07/2014 9:22 p.m., Jiri Olsa wrote:
>>>>> On Wed, Jul 16, 2014 at 06:04:44PM +0300, Adrian Hunter wrote:
>>>>>> On 16/07/2014 5:25 p.m., Jiri Olsa wrote:
>>>>>>> On Mon, Jul 14, 2014 at 01:02:44PM +0300, Adrian Hunter wrote:
>>>>>>>> This enables a PMU event to be specified in the form:
>>>>>>>>
>>>>>>>> 	pmu//
>>>>>>>>
>>>>>>>> which is effectively the same as:
>>>>>>>>
>>>>>>>> 	pmu/config=0/
>>>>>>>>
>>>>>>>> This patch is a precursor to defining
>>>>>>>> default config for a PMU.
>>>>>>>
>>>>>>> I understand the need for default config, but could you please elaborate
>>>>>>> why do we want to parse 'pmu//' as an event string string?
>>>>>>
>>>>>> Currently the parser requires the slashes to identify a PMU event
>>>>>> as opposed to a hardware or other kind of event.
>>>>>
>>>>> right, so why do we want to parse 'pmu//' as an event string? ;-)
>>>>
>>>> I am not sure what you mean.  Here I am using 'pmu' as a placeholder
>>>> for a real PMU name.  So actual event strings are 'intel_bts//' or
>>>> 'intel_pt//' or 'intel_pt/tsc=0,noretcomp=1/'
>>>
>>> so the consequence of default arguments is that you can
>>> specify event just by the pmu name, like:
>>>   -e intel_pt//
>>>
>>> which means (with default attributes):
>>>   -e intel_pt/tsc=1,noretcomp=0/
>>>
>>> I guess I wanted to hear more elaboration why is this better
>>> than the current way we have by defining an alias, like:
>>>
>>>   krava alias: "tsc=1,noretcomp=0"
>>>
>>>   -e intel_pt/krava/
>>>
>>> which gives the same result
>>
>> The default value must be provided by perf tools not the kernel e.g.
>> an older version of perf tools will not be aware of new hardware
>> features that the kernel may know about.  If the kernel enables
>> new features by default then the tool may fail.  Thus the default
>> value has to be under the control of the tools not the kernel, so
>> a sysfs alias will not work.
>>
> 
> I dont follow, could u provide some example?

Imagine that the 'tsc' term did not exist.  Intel PT trace data
would not contain TSC packets, and the decoder would not know how to
decode them.  Then imagine that a new version of the hardware adds
'tsc'.  It is such a useful feature that we want it by default, but
older versions of the tools don't know how to decode it, so the
kernel cannot turn it on by default.

> 
> why the tool needs to understand.. it will just take the alias
> and apply/use it? The alias follows the format logic, which tells
> how to apply values on perf_event_attr.. and the kernel knows best
> what's supported in its version..

It is similar to why the kernel does not select mmap2 by default.  The
kernel doesn't know whether the tool supports it.


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

* Re: [PATCH 20/41] perf tools: Let a user specify a PMU event without any config terms
  2014-09-02  5:39                 ` Adrian Hunter
@ 2014-09-02  9:17                   ` Jiri Olsa
  0 siblings, 0 replies; 122+ messages in thread
From: Jiri Olsa @ 2014-09-02  9:17 UTC (permalink / raw)
  To: Adrian Hunter
  Cc: Arnaldo Carvalho de Melo, Peter Zijlstra, linux-kernel,
	David Ahern, Frederic Weisbecker, Namhyung Kim, Paul Mackerras,
	Stephane Eranian

On Tue, Sep 02, 2014 at 08:39:56AM +0300, Adrian Hunter wrote:

SNIP

> >>>   -e intel_pt/tsc=1,noretcomp=0/
> >>>
> >>> I guess I wanted to hear more elaboration why is this better
> >>> than the current way we have by defining an alias, like:
> >>>
> >>>   krava alias: "tsc=1,noretcomp=0"
> >>>
> >>>   -e intel_pt/krava/
> >>>
> >>> which gives the same result
> >>
> >> The default value must be provided by perf tools not the kernel e.g.
> >> an older version of perf tools will not be aware of new hardware
> >> features that the kernel may know about.  If the kernel enables
> >> new features by default then the tool may fail.  Thus the default
> >> value has to be under the control of the tools not the kernel, so
> >> a sysfs alias will not work.
> >>
> > 
> > I dont follow, could u provide some example?
> 
> Imagine that the 'tsc' term did not exist.  Intel PT trace data
> would not contain TSC packets, and the decoder would not know how to
> decode them.  Then imagine that a new version of the hardware adds
> 'tsc'.  It is such a useful feature that we want it by default, but
> older versions of the tools don't know how to decode it, so the
> kernel cannot turn it on by default.
> 
> > 
> > why the tool needs to understand.. it will just take the alias
> > and apply/use it? The alias follows the format logic, which tells
> > how to apply values on perf_event_attr.. and the kernel knows best
> > what's supported in its version..
> 
> It is similar to why the kernel does not select mmap2 by default.  The
> kernel doesn't know whether the tool supports it.
> 

ook, could you please add some kind of this explanation to the changelog?

thanks,
jirka

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

end of thread, other threads:[~2014-09-02  9:44 UTC | newest]

Thread overview: 122+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-07-14 10:02 [PATCH 00/41] perf tools: Preparation for call graph from Intel BTS Adrian Hunter
2014-07-14 10:02 ` [PATCH 01/41] perf tools: Fix the value used for unknown pids Adrian Hunter
2014-07-18  4:23   ` [tip:perf/core] perf machine: " tip-bot for Adrian Hunter
2014-07-14 10:02 ` [PATCH 02/41] perf tools: Fix map groups of threads with " Adrian Hunter
2014-07-14 20:18   ` Arnaldo Carvalho de Melo
2014-07-15 11:33     ` Adrian Hunter
2014-07-15 19:33       ` Arnaldo Carvalho de Melo
2014-07-16  8:07         ` [PATCH V2 " Adrian Hunter
2014-07-18  4:26           ` [tip:perf/core] perf machine: " tip-bot for Adrian Hunter
2014-07-14 10:02 ` [PATCH 03/41] perf script: Display PERF_RECORD_MISC_COMM_EXEC flag Adrian Hunter
2014-07-18  4:23   ` [tip:perf/core] " tip-bot for Adrian Hunter
2014-07-14 10:02 ` [PATCH 04/41] perf record: Select comm_exec flag if supported Adrian Hunter
2014-07-18  4:23   ` [tip:perf/core] " tip-bot for Adrian Hunter
2014-07-14 10:02 ` [PATCH 05/41] perf tools: Identify which comms are from exec Adrian Hunter
2014-07-14 20:32   ` Arnaldo Carvalho de Melo
2014-07-15 11:43     ` Adrian Hunter
2014-07-23 14:07       ` Arnaldo Carvalho de Melo
2014-07-23 14:09         ` Arnaldo Carvalho de Melo
2014-07-23 16:46           ` Adrian Hunter
2014-07-23 16:53             ` Arnaldo Carvalho de Melo
2014-07-14 10:02 ` [PATCH 06/41] perf tools: Add machine__thread_exec_comm() Adrian Hunter
2014-07-14 10:02 ` [PATCH 07/41] perf tools: Fix missing kernel map load Adrian Hunter
2014-07-18  4:23   ` [tip:perf/core] " tip-bot for Adrian Hunter
2014-07-14 10:02 ` [PATCH 08/41] perf tools: Fix missing label symbols Adrian Hunter
2014-07-14 20:38   ` Arnaldo Carvalho de Melo
2014-07-15 12:11     ` Adrian Hunter
2014-07-14 10:02 ` [PATCH 09/41] perf tools: Fix missing GNU IFUNC symbols Adrian Hunter
2014-07-18  4:24   ` [tip:perf/core] perf symbols: " tip-bot for Adrian Hunter
2014-07-14 10:02 ` [PATCH 10/41] perf inject: Fix build id injection Adrian Hunter
2014-07-18  4:24   ` [tip:perf/core] " tip-bot for Adrian Hunter
2014-07-14 10:02 ` [PATCH 11/41] perf tools: Fix appending a callchain from a previous sample Adrian Hunter
2014-07-18  4:24   ` [tip:perf/core] perf callchain: " tip-bot for Adrian Hunter
2014-07-14 10:02 ` [PATCH 12/41] perf tools: Fix leak of 'struct thread' on error path Adrian Hunter
2014-07-14 20:43   ` Arnaldo Carvalho de Melo
2014-07-16  7:19     ` [PATCH V2 0/2] perf tools: Allow deletion of a thread with no map groups Adrian Hunter
2014-07-16  7:19       ` [PATCH 1/2] " Adrian Hunter
2014-07-18  4:27         ` [tip:perf/core] perf thread: " tip-bot for Adrian Hunter
2014-07-16  7:19       ` [PATCH V2 2/2] perf tools: Fix leak of 'struct thread' on error path Adrian Hunter
2014-07-18  4:27         ` [tip:perf/core] perf machine: " tip-bot for Adrian Hunter
2014-07-16 14:02   ` [PATCH 12/41] perf tools: " Jiri Olsa
2014-07-16 14:26     ` Adrian Hunter
2014-07-14 10:02 ` [PATCH 13/41] perf tools: Add machine__kernel_ip() Adrian Hunter
2014-07-16 14:15   ` Jiri Olsa
2014-07-16 14:22     ` Adrian Hunter
2014-08-11 12:23       ` Jiri Olsa
2014-08-11 12:36         ` Adrian Hunter
2014-08-11 12:43           ` Jiri Olsa
2014-08-11 12:46             ` Adrian Hunter
2014-08-11 12:55               ` Jiri Olsa
2014-07-14 10:02 ` [PATCH 14/41] perf buildid-cache: Apply force option to copying kcore Adrian Hunter
2014-07-18  4:24   ` [tip:perf/core] " tip-bot for Adrian Hunter
2014-07-14 10:02 ` [PATCH 15/41] perf script: Improve srcline display for BTS Adrian Hunter
2014-07-15 14:16   ` Arnaldo Carvalho de Melo
2014-07-15 17:51     ` Adrian Hunter
2014-07-16  2:08     ` David Ahern
2014-07-14 10:02 ` [PATCH 16/41] perf script: Do not print dangling '=>' " Adrian Hunter
2014-07-14 10:02 ` [PATCH 17/41] perf tools: Record whether a dso is 64-bit Adrian Hunter
2014-07-18  4:24   ` [tip:perf/core] perf symbols: " tip-bot for Adrian Hunter
2014-07-14 10:02 ` [PATCH 18/41] perf tools: Record whether a dso has data Adrian Hunter
2014-07-16 14:20   ` Jiri Olsa
2014-07-17  8:43     ` [PATCH 0/2] perf tools: Fix incorrect fd error comparison Adrian Hunter
2014-07-17  8:43       ` [PATCH 1/2] " Adrian Hunter
2014-07-22  7:51         ` Jiri Olsa
2014-07-28  8:21         ` [tip:perf/core] " tip-bot for Adrian Hunter
2014-07-17  8:43       ` [PATCH V2 2/2] perf tools: Record whether a dso has data Adrian Hunter
2014-07-17  8:58         ` [PATCH V3] " Adrian Hunter
2014-07-22  7:55           ` Jiri Olsa
2014-07-22 13:24             ` Adrian Hunter
2014-07-14 10:02 ` [PATCH 19/41] perf tools: Do not attempt to read data from kallsyms Adrian Hunter
2014-07-18  4:25   ` [tip:perf/core] perf symbols: " tip-bot for Adrian Hunter
2014-07-14 10:02 ` [PATCH 20/41] perf tools: Let a user specify a PMU event without any config terms Adrian Hunter
2014-07-16 14:25   ` Jiri Olsa
2014-07-16 15:04     ` Adrian Hunter
2014-07-16 18:22       ` Jiri Olsa
2014-08-29 18:48         ` Adrian Hunter
2014-08-30  8:53           ` Jiri Olsa
2014-09-01  6:27             ` Adrian Hunter
2014-09-01 19:11               ` Jiri Olsa
2014-09-02  5:39                 ` Adrian Hunter
2014-09-02  9:17                   ` Jiri Olsa
2014-09-01 15:51             ` Arnaldo Carvalho de Melo
2014-09-01 19:15               ` Jiri Olsa
2014-07-14 10:02 ` [PATCH 21/41] perf tools: Let default config be defined for a PMU Adrian Hunter
2014-07-14 10:02 ` [PATCH 22/41] perf tools: Add perf_pmu__scan_file() Adrian Hunter
2014-07-14 10:02 ` [PATCH 23/41] perf tools: Add dsos__hit_all() Adrian Hunter
2014-07-14 10:02 ` [PATCH 24/41] perf tools: Add cpu to struct thread Adrian Hunter
2014-07-15 14:24   ` Arnaldo Carvalho de Melo
2014-07-15 17:58     ` Adrian Hunter
2014-07-14 10:02 ` [PATCH 25/41] perf tools: Add ability to record the current tid for each cpu Adrian Hunter
2014-07-14 10:02 ` [PATCH 26/41] perf tools: Add ability to iterate over a dso's symbols Adrian Hunter
2014-07-18  4:25   ` [tip:perf/core] perf symbols: Add ability to iterate over a dso' s symbols tip-bot for Adrian Hunter
2014-07-14 10:02 ` [PATCH 27/41] perf session: Flag if the event stream is entirely in memory Adrian Hunter
2014-07-18  4:25   ` [tip:perf/core] " tip-bot for Adrian Hunter
2014-07-14 10:02 ` [PATCH 28/41] perf evlist: Pass mmap parameters in a struct Adrian Hunter
2014-07-18  4:25   ` [tip:perf/core] " tip-bot for Adrian Hunter
2014-07-14 10:02 ` [PATCH 29/41] perf tools: Add feature test for __sync_val_compare_and_swap Adrian Hunter
2014-07-18  4:26   ` [tip:perf/core] " tip-bot for Adrian Hunter
2014-07-14 10:02 ` [PATCH 30/41] perf tools: Add option macro OPT_CALLBACK_OPTARG Adrian Hunter
2014-07-18  4:26   ` [tip:perf/core] " tip-bot for Adrian Hunter
2014-07-14 10:02 ` [PATCH 31/41] perf evlist: Add perf_evlist__set_tracking_event() Adrian Hunter
2014-07-14 10:02 ` [PATCH 32/41] perf evsel: Add 'no_aux_samples' option Adrian Hunter
2014-07-18  4:26   ` [tip:perf/core] " tip-bot for Adrian Hunter
2014-07-14 10:02 ` [PATCH 33/41] perf evsel: Add 'immediate' option Adrian Hunter
2014-07-18  4:26   ` [tip:perf/core] " tip-bot for Adrian Hunter
2014-07-14 10:02 ` [PATCH 34/41] perf evlist: Add 'system_wide' option Adrian Hunter
2014-07-15 15:03   ` Arnaldo Carvalho de Melo
2014-07-15 18:05     ` Adrian Hunter
2014-08-11 13:12   ` Jiri Olsa
2014-08-12  5:52     ` Adrian Hunter
2014-07-14 10:02 ` [PATCH 35/41] perf tools: Add id index Adrian Hunter
2014-07-14 10:03 ` [PATCH 36/41] perf pmu: Let pmu's with no events show up on perf list Adrian Hunter
2014-07-14 10:03 ` [PATCH 37/41] perf session: Add ability to skip 4GiB or more Adrian Hunter
2014-07-14 10:03 ` [PATCH 38/41] perf session: Add perf_session__deliver_synth_event() Adrian Hunter
2014-07-15 15:17   ` Arnaldo Carvalho de Melo
2014-07-15 18:32     ` Adrian Hunter
2014-07-14 10:03 ` [PATCH 39/41] perf tools: Allow TSC conversion on any arch Adrian Hunter
2014-07-15 15:20   ` Arnaldo Carvalho de Melo
2014-07-15 16:17     ` Peter Zijlstra
2014-07-15 17:48     ` Adrian Hunter
2014-07-18  4:28   ` [tip:perf/core] " tip-bot for Adrian Hunter
2014-07-14 10:03 ` [PATCH 40/41] perf tools: Move rdtsc() function Adrian Hunter
2014-07-14 10:03 ` [PATCH 41/41] perf evlist: Add perf_evlist__enable_event_idx() Adrian Hunter

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.