2009-12-13 21:51:52

by Arnaldo Carvalho de Melo

[permalink] [raw]
Subject: [PATCH 1/6] perf session: Pass the perf_session to the event handling operations

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

They will need it to get the right threads list, etc.

Cc: Frédéric Weisbecker <[email protected]>
Cc: Mike Galbraith <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Paul Mackerras <[email protected]>
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
---
tools/perf/builtin-annotate.c | 2 +-
tools/perf/builtin-kmem.c | 2 +-
tools/perf/builtin-record.c | 11 +++++++----
tools/perf/builtin-report.c | 9 ++++-----
tools/perf/builtin-sched.c | 6 ++++--
tools/perf/builtin-timechart.c | 13 +++++--------
tools/perf/builtin-top.c | 28 +++++++++++++++++-----------
tools/perf/builtin-trace.c | 23 ++++++++++-------------
tools/perf/util/data_map.c | 27 ++++++++++++++-------------
tools/perf/util/data_map.h | 5 ++++-
tools/perf/util/event.c | 37 +++++++++++++++++++++++--------------
tools/perf/util/event.h | 19 +++++++++++++------
12 files changed, 103 insertions(+), 79 deletions(-)

diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index 21a78d3..2e418b9 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -132,7 +132,7 @@ static int hist_entry__add(struct addr_location *al, u64 count)
return 0;
}

-static int process_sample_event(event_t *event)
+static int process_sample_event(event_t *event, struct perf_session *session __used)
{
struct addr_location al;

diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c
index 2071d24..101b268 100644
--- a/tools/perf/builtin-kmem.c
+++ b/tools/perf/builtin-kmem.c
@@ -312,7 +312,7 @@ process_raw_event(event_t *raw_event __used, void *data,
}
}

-static int process_sample_event(event_t *event)
+static int process_sample_event(event_t *event, struct perf_session *session __used)
{
struct sample_data data;
struct thread *thread;
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 4decbd1..b7e15a1 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -123,7 +123,8 @@ static void write_event(event_t *buf, size_t size)
write_output(buf, size);
}

-static int process_synthesized_event(event_t *event)
+static int process_synthesized_event(event_t *event,
+ struct perf_session *self __used)
{
write_event(event, event->header.size);
return 0;
@@ -488,9 +489,10 @@ static int __cmd_record(int argc, const char **argv)
}

if (!system_wide)
- event__synthesize_thread(pid, process_synthesized_event);
+ event__synthesize_thread(pid, process_synthesized_event,
+ session);
else
- event__synthesize_threads(process_synthesized_event);
+ event__synthesize_threads(process_synthesized_event, session);

if (target_pid == -1 && argc) {
pid = fork();
@@ -510,7 +512,8 @@ static int __cmd_record(int argc, const char **argv)
*/
usleep(1000);
event__synthesize_thread(pid,
- process_synthesized_event);
+ process_synthesized_event,
+ session);
}

child_pid = pid;
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index e2ec49a..dcd8fed 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -53,8 +53,6 @@ static int exclude_other = 1;

static char callchain_default_opt[] = "fractal,0.5";

-static struct perf_session *session;
-
static u64 sample_type;

struct symbol_conf symbol_conf;
@@ -604,7 +602,7 @@ static int validate_chain(struct ip_callchain *chain, event_t *event)
return 0;
}

-static int process_sample_event(event_t *event)
+static int process_sample_event(event_t *event, struct perf_session *session __used)
{
struct sample_data data;
int cpumode;
@@ -683,7 +681,7 @@ static int process_sample_event(event_t *event)
return 0;
}

-static int process_comm_event(event_t *event)
+static int process_comm_event(event_t *event, struct perf_session *session __used)
{
struct thread *thread = threads__findnew(event->comm.pid);

@@ -698,7 +696,7 @@ static int process_comm_event(event_t *event)
return 0;
}

-static int process_read_event(event_t *event)
+static int process_read_event(event_t *event, struct perf_session *session __used)
{
struct perf_event_attr *attr;

@@ -766,6 +764,7 @@ static int __cmd_report(void)
{
struct thread *idle;
int ret;
+ struct perf_session *session;

session = perf_session__new(input_name, O_RDONLY, force);
if (session == NULL)
diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c
index 65021fe..48ab283 100644
--- a/tools/perf/builtin-sched.c
+++ b/tools/perf/builtin-sched.c
@@ -1594,7 +1594,8 @@ process_raw_event(event_t *raw_event __used, void *data,
process_sched_migrate_task_event(data, event, cpu, timestamp, thread);
}

-static int process_sample_event(event_t *event)
+static int process_sample_event(event_t *event,
+ struct perf_session *session __used)
{
struct sample_data data;
struct thread *thread;
@@ -1632,7 +1633,8 @@ static int process_sample_event(event_t *event)
return 0;
}

-static int process_lost_event(event_t *event __used)
+static int process_lost_event(event_t *event __used,
+ struct perf_session *session __used)
{
nr_lost_chunks++;
nr_lost_events += event->lost.lost;
diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c
index 759dd2b..db6caae 100644
--- a/tools/perf/builtin-timechart.c
+++ b/tools/perf/builtin-timechart.c
@@ -281,21 +281,19 @@ static int cpus_cstate_state[MAX_CPUS];
static u64 cpus_pstate_start_times[MAX_CPUS];
static u64 cpus_pstate_state[MAX_CPUS];

-static int
-process_comm_event(event_t *event)
+static int process_comm_event(event_t *event, struct perf_session *session __used)
{
pid_set_comm(event->comm.pid, event->comm.comm);
return 0;
}
-static int
-process_fork_event(event_t *event)
+
+static int process_fork_event(event_t *event, struct perf_session *session __used)
{
pid_fork(event->fork.pid, event->fork.ppid, event->fork.time);
return 0;
}

-static int
-process_exit_event(event_t *event)
+static int process_exit_event(event_t *event, struct perf_session *session __used)
{
pid_exit(event->fork.pid, event->fork.time);
return 0;
@@ -594,8 +592,7 @@ static u64 sample_time(event_t *event)
* We first queue all events, sorted backwards by insertion.
* The order will get flipped later.
*/
-static int
-queue_sample_event(event_t *event)
+static int queue_sample_event(event_t *event, struct perf_session *session __used)
{
struct sample_wrapper *copy, *prev;
int size;
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index e0a374d..b13f426 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -965,14 +965,14 @@ static void event__process_sample(const event_t *self, int counter)
}
}

-static int event__process(event_t *event)
+static int event__process(event_t *event, struct perf_session *session)
{
switch (event->header.type) {
case PERF_RECORD_COMM:
- event__process_comm(event);
+ event__process_comm(event, session);
break;
case PERF_RECORD_MMAP:
- event__process_mmap(event);
+ event__process_mmap(event, session);
break;
default:
break;
@@ -999,7 +999,8 @@ static unsigned int mmap_read_head(struct mmap_data *md)
return head;
}

-static void mmap_read_counter(struct mmap_data *md)
+static void perf_session__mmap_read_counter(struct perf_session *self,
+ struct mmap_data *md)
{
unsigned int head = mmap_read_head(md);
unsigned int old = md->prev;
@@ -1054,7 +1055,7 @@ static void mmap_read_counter(struct mmap_data *md)
if (event->header.type == PERF_RECORD_SAMPLE)
event__process_sample(event, md->counter);
else
- event__process(event);
+ event__process(event, self);
old += size;
}

@@ -1064,13 +1065,13 @@ static void mmap_read_counter(struct mmap_data *md)
static struct pollfd event_array[MAX_NR_CPUS * MAX_COUNTERS];
static struct mmap_data mmap_array[MAX_NR_CPUS][MAX_COUNTERS];

-static void mmap_read(void)
+static void perf_session__mmap_read(struct perf_session *self)
{
int i, counter;

for (i = 0; i < nr_cpus; i++) {
for (counter = 0; counter < nr_counters; counter++)
- mmap_read_counter(&mmap_array[i][counter]);
+ perf_session__mmap_read_counter(self, &mmap_array[i][counter]);
}
}

@@ -1155,11 +1156,16 @@ static int __cmd_top(void)
pthread_t thread;
int i, counter;
int ret;
+ /*
+ * XXX perf_session__new should allow passing a O_MMAP, so that all this
+ * mmap reading, etc is encapsulated in it.
+ */
+ struct perf_session *session = NULL;

if (target_pid != -1)
- event__synthesize_thread(target_pid, event__process);
+ event__synthesize_thread(target_pid, event__process, session);
else
- event__synthesize_threads(event__process);
+ event__synthesize_threads(event__process, session);

for (i = 0; i < nr_cpus; i++) {
group_fd = -1;
@@ -1170,7 +1176,7 @@ static int __cmd_top(void)
/* Wait for a minimal set of events before starting the snapshot */
poll(event_array, nr_poll, 100);

- mmap_read();
+ perf_session__mmap_read(session);

if (pthread_create(&thread, NULL, display_thread, NULL)) {
printf("Could not create display thread.\n");
@@ -1190,7 +1196,7 @@ static int __cmd_top(void)
while (1) {
int hits = samples;

- mmap_read();
+ perf_session__mmap_read(session);

if (hits == samples)
ret = poll(event_array, nr_poll, 100);
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index 0756664..3057e1d 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -62,10 +62,9 @@ static int cleanup_scripting(void)

static char const *input_name = "perf.data";

-static struct perf_session *session;
static u64 sample_type;

-static int process_sample_event(event_t *event)
+static int process_sample_event(event_t *event, struct perf_session *session __used)
{
struct sample_data data;
struct thread *thread;
@@ -125,20 +124,12 @@ static struct perf_file_handler file_handler = {
.sample_type_check = sample_type_check,
};

-static int __cmd_trace(void)
+static int __cmd_trace(struct perf_session *session)
{
- int err;
-
- session = perf_session__new(input_name, O_RDONLY, 0);
- if (session == NULL)
- return -ENOMEM;
-
register_idle_thread();
register_perf_file_handler(&file_handler);

- err = perf_session__process_events(session, 0, &event__cwdlen, &event__cwd);
- perf_session__delete(session);
- return err;
+ return perf_session__process_events(session, 0, &event__cwdlen, &event__cwd);
}

struct script_spec {
@@ -313,6 +304,7 @@ static const struct option options[] = {
int cmd_trace(int argc, const char **argv, const char *prefix __used)
{
int err;
+ struct perf_session *session;

symbol__init(0);

@@ -330,6 +322,10 @@ int cmd_trace(int argc, const char **argv, const char *prefix __used)

setup_pager();

+ session = perf_session__new(input_name, O_RDONLY, 0);
+ if (session == NULL)
+ return -ENOMEM;
+
if (generate_script_lang) {
struct stat perf_stat;

@@ -367,8 +363,9 @@ int cmd_trace(int argc, const char **argv, const char *prefix __used)
goto out;
}

- err = __cmd_trace();
+ err = __cmd_trace(session);

+ perf_session__delete(session);
cleanup_scripting();
out:
return err;
diff --git a/tools/perf/util/data_map.c b/tools/perf/util/data_map.c
index 6d46dda..22bcdfe 100644
--- a/tools/perf/util/data_map.c
+++ b/tools/perf/util/data_map.c
@@ -8,7 +8,8 @@ static struct perf_file_handler *curr_handler;
static unsigned long mmap_window = 32;
static char __cwd[PATH_MAX];

-static int process_event_stub(event_t *event __used)
+static int process_event_stub(event_t *event __used,
+ struct perf_session *session __used)
{
dump_printf(": unhandled!\n");
return 0;
@@ -61,8 +62,8 @@ void event__print_totals(void)
event__name[i], event__total[i]);
}

-static int
-process_event(event_t *event, unsigned long offset, unsigned long head)
+static int process_event(event_t *event, struct perf_session *session,
+ unsigned long offset, unsigned long head)
{
trace_event(event);

@@ -77,23 +78,23 @@ process_event(event_t *event, unsigned long offset, unsigned long head)

switch (event->header.type) {
case PERF_RECORD_SAMPLE:
- return curr_handler->process_sample_event(event);
+ return curr_handler->process_sample_event(event, session);
case PERF_RECORD_MMAP:
- return curr_handler->process_mmap_event(event);
+ return curr_handler->process_mmap_event(event, session);
case PERF_RECORD_COMM:
- return curr_handler->process_comm_event(event);
+ return curr_handler->process_comm_event(event, session);
case PERF_RECORD_FORK:
- return curr_handler->process_fork_event(event);
+ return curr_handler->process_fork_event(event, session);
case PERF_RECORD_EXIT:
- return curr_handler->process_exit_event(event);
+ return curr_handler->process_exit_event(event, session);
case PERF_RECORD_LOST:
- return curr_handler->process_lost_event(event);
+ return curr_handler->process_lost_event(event, session);
case PERF_RECORD_READ:
- return curr_handler->process_read_event(event);
+ return curr_handler->process_read_event(event, session);
case PERF_RECORD_THROTTLE:
- return curr_handler->process_throttle_event(event);
+ return curr_handler->process_throttle_event(event, session);
case PERF_RECORD_UNTHROTTLE:
- return curr_handler->process_unthrottle_event(event);
+ return curr_handler->process_unthrottle_event(event, session);
default:
curr_handler->total_unknown++;
return -1;
@@ -209,7 +210,7 @@ more:
(void *)(long)event->header.size,
event->header.type);

- if (!size || process_event(event, offset, head) < 0) {
+ if (!size || process_event(event, self, offset, head) < 0) {

dump_printf("%p [%p]: skipping unknown header type: %d\n",
(void *)(offset + head),
diff --git a/tools/perf/util/data_map.h b/tools/perf/util/data_map.h
index 98c5b82..6d4ae52 100644
--- a/tools/perf/util/data_map.h
+++ b/tools/perf/util/data_map.h
@@ -5,7 +5,10 @@
#include "header.h"
#include "session.h"

-typedef int (*event_type_handler_t)(event_t *);
+struct perf_session;
+
+typedef int (*event_type_handler_t)(event_t *self,
+ struct perf_session *session);

struct perf_file_handler {
event_type_handler_t process_sample_event;
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index ba0de90..e2c4895 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -5,7 +5,9 @@
#include "thread.h"

static pid_t event__synthesize_comm(pid_t pid, int full,
- int (*process)(event_t *event))
+ int (*process)(event_t *event,
+ struct perf_session *session),
+ struct perf_session *session)
{
event_t ev;
char filename[PATH_MAX];
@@ -54,7 +56,7 @@ out_race:
if (!full) {
ev.comm.tid = pid;

- process(&ev);
+ process(&ev, session);
goto out_fclose;
}

@@ -72,7 +74,7 @@ out_race:

ev.comm.tid = pid;

- process(&ev);
+ process(&ev, session);
}
closedir(tasks);

@@ -86,7 +88,9 @@ out_failure:
}

static int event__synthesize_mmap_events(pid_t pid, pid_t tgid,
- int (*process)(event_t *event))
+ int (*process)(event_t *event,
+ struct perf_session *session),
+ struct perf_session *session)
{
char filename[PATH_MAX];
FILE *fp;
@@ -141,7 +145,7 @@ static int event__synthesize_mmap_events(pid_t pid, pid_t tgid,
ev.mmap.pid = tgid;
ev.mmap.tid = pid;

- process(&ev);
+ process(&ev, session);
}
}

@@ -149,15 +153,20 @@ static int event__synthesize_mmap_events(pid_t pid, pid_t tgid,
return 0;
}

-int event__synthesize_thread(pid_t pid, int (*process)(event_t *event))
+int event__synthesize_thread(pid_t pid,
+ int (*process)(event_t *event,
+ struct perf_session *session),
+ struct perf_session *session)
{
- pid_t tgid = event__synthesize_comm(pid, 1, process);
+ pid_t tgid = event__synthesize_comm(pid, 1, process, session);
if (tgid == -1)
return -1;
- return event__synthesize_mmap_events(pid, tgid, process);
+ return event__synthesize_mmap_events(pid, tgid, process, session);
}

-void event__synthesize_threads(int (*process)(event_t *event))
+void event__synthesize_threads(int (*process)(event_t *event,
+ struct perf_session *session),
+ struct perf_session *session)
{
DIR *proc;
struct dirent dirent, *next;
@@ -171,7 +180,7 @@ void event__synthesize_threads(int (*process)(event_t *event))
if (*end) /* only interested in proper numerical dirents */
continue;

- event__synthesize_thread(pid, process);
+ event__synthesize_thread(pid, process, session);
}

closedir(proc);
@@ -182,7 +191,7 @@ int event__cwdlen;

struct events_stats event__stats;

-int event__process_comm(event_t *self)
+int event__process_comm(event_t *self, struct perf_session *session __used)
{
struct thread *thread = threads__findnew(self->comm.pid);

@@ -196,14 +205,14 @@ int event__process_comm(event_t *self)
return 0;
}

-int event__process_lost(event_t *self)
+int event__process_lost(event_t *self, struct perf_session *session __used)
{
dump_printf(": id:%Ld: lost:%Ld\n", self->lost.id, self->lost.lost);
event__stats.lost += self->lost.lost;
return 0;
}

-int event__process_mmap(event_t *self)
+int event__process_mmap(event_t *self, struct perf_session *session __used)
{
struct thread *thread = threads__findnew(self->mmap.pid);
struct map *map = map__new(&self->mmap, MAP__FUNCTION,
@@ -224,7 +233,7 @@ int event__process_mmap(event_t *self)
return 0;
}

-int event__process_task(event_t *self)
+int event__process_task(event_t *self, struct perf_session *session __used)
{
struct thread *thread = threads__findnew(self->fork.pid);
struct thread *parent = threads__findnew(self->fork.ppid);
diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h
index 51a96c2..6b6429b 100644
--- a/tools/perf/util/event.h
+++ b/tools/perf/util/event.h
@@ -156,18 +156,25 @@ struct symbol *map__find_symbol_by_name(struct map *self, const char *name,
void map__fixup_start(struct map *self);
void map__fixup_end(struct map *self);

-int event__synthesize_thread(pid_t pid, int (*process)(event_t *event));
-void event__synthesize_threads(int (*process)(event_t *event));
+struct perf_session;
+
+int event__synthesize_thread(pid_t pid,
+ int (*process)(event_t *event,
+ struct perf_session *session),
+ struct perf_session *session);
+void event__synthesize_threads(int (*process)(event_t *event,
+ struct perf_session *session),
+ struct perf_session *session);

extern char *event__cwd;
extern int event__cwdlen;
extern struct events_stats event__stats;
extern unsigned long event__total[PERF_RECORD_MAX];

-int event__process_comm(event_t *self);
-int event__process_lost(event_t *self);
-int event__process_mmap(event_t *self);
-int event__process_task(event_t *self);
+int event__process_comm(event_t *self, struct perf_session *session);
+int event__process_lost(event_t *self, struct perf_session *session);
+int event__process_mmap(event_t *self, struct perf_session *session);
+int event__process_task(event_t *self, struct perf_session *session);

struct addr_location;
int event__preprocess_sample(const event_t *self, struct addr_location *al,
--
1.6.2.5


2009-12-13 21:50:50

by Arnaldo Carvalho de Melo

[permalink] [raw]
Subject: [PATCH 2/6] perf session: Ditch register_perf_file_handler

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

Pass the event_ops to perf_session__process_events instead.

Also move the event_ops definition to session.h, starting to move things
around to their right place, trimming the many unneeded headers we have.

Cc: Frédéric Weisbecker <[email protected]>
Cc: Mike Galbraith <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Paul Mackerras <[email protected]>
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
---
tools/perf/Makefile | 1 -
tools/perf/builtin-annotate.c | 10 ++++----
tools/perf/builtin-buildid-list.c | 1 -
tools/perf/builtin-kmem.c | 8 ++----
tools/perf/builtin-report.c | 7 +----
tools/perf/builtin-sched.c | 7 ++---
tools/perf/builtin-timechart.c | 9 +++----
tools/perf/builtin-trace.c | 8 ++----
tools/perf/util/data_map.c | 41 ++++++++++++++++--------------------
tools/perf/util/data_map.h | 32 ----------------------------
tools/perf/util/header.c | 2 +-
tools/perf/util/session.c | 3 +-
tools/perf/util/session.h | 26 ++++++++++++++++++++++-
13 files changed, 66 insertions(+), 89 deletions(-)
delete mode 100644 tools/perf/util/data_map.h

diff --git a/tools/perf/Makefile b/tools/perf/Makefile
index 4069996..a4cb792 100644
--- a/tools/perf/Makefile
+++ b/tools/perf/Makefile
@@ -370,7 +370,6 @@ LIB_H += util/values.h
LIB_H += util/sort.h
LIB_H += util/hist.h
LIB_H += util/thread.h
-LIB_H += util/data_map.h
LIB_H += util/probe-finder.h
LIB_H += util/probe-event.h

diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index 2e418b9..43e3bb3 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -26,7 +26,6 @@
#include "util/sort.h"
#include "util/hist.h"
#include "util/session.h"
-#include "util/data_map.h"

static char const *input_name = "perf.data";

@@ -454,7 +453,7 @@ static void find_annotations(void)
}
}

-static struct perf_file_handler file_handler = {
+static struct perf_event_ops event_ops = {
.process_sample_event = process_sample_event,
.process_mmap_event = event__process_mmap,
.process_comm_event = event__process_comm,
@@ -463,7 +462,8 @@ static struct perf_file_handler file_handler = {

static int __cmd_annotate(void)
{
- struct perf_session *session = perf_session__new(input_name, O_RDONLY, force);
+ struct perf_session *session = perf_session__new(input_name, O_RDONLY,
+ force);
struct thread *idle;
int ret;

@@ -471,9 +471,9 @@ static int __cmd_annotate(void)
return -ENOMEM;

idle = register_idle_thread();
- register_perf_file_handler(&file_handler);

- ret = perf_session__process_events(session, 0, &event__cwdlen, &event__cwd);
+ ret = perf_session__process_events(session, &event_ops, 0,
+ &event__cwdlen, &event__cwd);
if (ret)
goto out_delete;

diff --git a/tools/perf/builtin-buildid-list.c b/tools/perf/builtin-buildid-list.c
index bfd16a1..2629f76 100644
--- a/tools/perf/builtin-buildid-list.c
+++ b/tools/perf/builtin-buildid-list.c
@@ -9,7 +9,6 @@
#include "builtin.h"
#include "perf.h"
#include "util/cache.h"
-#include "util/data_map.h"
#include "util/debug.h"
#include "util/parse-options.h"
#include "util/session.h"
diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c
index 101b268..6f74bd8 100644
--- a/tools/perf/builtin-kmem.c
+++ b/tools/perf/builtin-kmem.c
@@ -12,7 +12,6 @@
#include "util/trace-event.h"

#include "util/debug.h"
-#include "util/data_map.h"

#include <linux/rbtree.h>

@@ -359,7 +358,7 @@ static int sample_type_check(u64 type)
return 0;
}

-static struct perf_file_handler file_handler = {
+static struct perf_event_ops event_ops = {
.process_sample_event = process_sample_event,
.process_comm_event = event__process_comm,
.sample_type_check = sample_type_check,
@@ -374,9 +373,8 @@ static int read_events(void)
return -ENOMEM;

register_idle_thread();
- register_perf_file_handler(&file_handler);
-
- err = perf_session__process_events(session, 0, &event__cwdlen, &event__cwd);
+ err = perf_session__process_events(session, &event_ops, 0,
+ &event__cwdlen, &event__cwd);
perf_session__delete(session);
return err;
}
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index dcd8fed..c203eaf 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -27,7 +27,6 @@
#include "util/parse-options.h"
#include "util/parse-events.h"

-#include "util/data_map.h"
#include "util/thread.h"
#include "util/sort.h"
#include "util/hist.h"
@@ -748,7 +747,7 @@ static int sample_type_check(u64 type)
return 0;
}

-static struct perf_file_handler file_handler = {
+static struct perf_event_ops event_ops = {
.process_sample_event = process_sample_event,
.process_mmap_event = event__process_mmap,
.process_comm_event = process_comm_event,
@@ -776,9 +775,7 @@ static int __cmd_report(void)
if (show_threads)
perf_read_values_init(&show_threads_values);

- register_perf_file_handler(&file_handler);
-
- ret = perf_session__process_events(session, full_paths,
+ ret = perf_session__process_events(session, &event_ops, full_paths,
&event__cwdlen, &event__cwd);
if (ret)
goto out_delete;
diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c
index 48ab283..b5b4472 100644
--- a/tools/perf/builtin-sched.c
+++ b/tools/perf/builtin-sched.c
@@ -12,7 +12,6 @@
#include "util/trace-event.h"

#include "util/debug.h"
-#include "util/data_map.h"

#include <sys/prctl.h>

@@ -1656,7 +1655,7 @@ static int sample_type_check(u64 type)
return 0;
}

-static struct perf_file_handler file_handler = {
+static struct perf_event_ops event_ops = {
.process_sample_event = process_sample_event,
.process_comm_event = event__process_comm,
.process_lost_event = process_lost_event,
@@ -1672,9 +1671,9 @@ static int read_events(void)
return -ENOMEM;

register_idle_thread();
- register_perf_file_handler(&file_handler);

- err = perf_session__process_events(session, 0, &event__cwdlen, &event__cwd);
+ err = perf_session__process_events(session, &event_ops, 0,
+ &event__cwdlen, &event__cwd);
perf_session__delete(session);
return err;
}
diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c
index db6caae..4b95cec 100644
--- a/tools/perf/builtin-timechart.c
+++ b/tools/perf/builtin-timechart.c
@@ -30,7 +30,7 @@
#include "util/parse-options.h"
#include "util/parse-events.h"
#include "util/event.h"
-#include "util/data_map.h"
+#include "util/session.h"
#include "util/svghelper.h"

static char const *input_name = "perf.data";
@@ -1046,7 +1046,7 @@ static int sample_type_check(u64 type)
return 0;
}

-static struct perf_file_handler file_handler = {
+static struct perf_event_ops event_ops = {
.process_comm_event = process_comm_event,
.process_fork_event = process_fork_event,
.process_exit_event = process_exit_event,
@@ -1062,9 +1062,8 @@ static int __cmd_timechart(void)
if (session == NULL)
return -ENOMEM;

- register_perf_file_handler(&file_handler);
-
- ret = perf_session__process_events(session, 0, &event__cwdlen, &event__cwd);
+ ret = perf_session__process_events(session, &event_ops, 0,
+ &event__cwdlen, &event__cwd);
if (ret)
goto out_delete;

diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index 3057e1d..c404dec 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -57,7 +57,6 @@ static int cleanup_scripting(void)
#include "util/debug.h"

#include "util/trace-event.h"
-#include "util/data_map.h"
#include "util/exec_cmd.h"

static char const *input_name = "perf.data";
@@ -118,7 +117,7 @@ static int sample_type_check(u64 type)
return 0;
}

-static struct perf_file_handler file_handler = {
+static struct perf_event_ops event_ops = {
.process_sample_event = process_sample_event,
.process_comm_event = event__process_comm,
.sample_type_check = sample_type_check,
@@ -127,9 +126,8 @@ static struct perf_file_handler file_handler = {
static int __cmd_trace(struct perf_session *session)
{
register_idle_thread();
- register_perf_file_handler(&file_handler);
-
- return perf_session__process_events(session, 0, &event__cwdlen, &event__cwd);
+ return perf_session__process_events(session, &event_ops, 0,
+ &event__cwdlen, &event__cwd);
}

struct script_spec {
diff --git a/tools/perf/util/data_map.c b/tools/perf/util/data_map.c
index 22bcdfe..ba5bcfa 100644
--- a/tools/perf/util/data_map.c
+++ b/tools/perf/util/data_map.c
@@ -1,10 +1,8 @@
-#include "data_map.h"
#include "symbol.h"
#include "util.h"
#include "debug.h"
+#include "session.h"

-
-static struct perf_file_handler *curr_handler;
static unsigned long mmap_window = 32;
static char __cwd[PATH_MAX];

@@ -15,7 +13,7 @@ static int process_event_stub(event_t *event __used,
return 0;
}

-void register_perf_file_handler(struct perf_file_handler *handler)
+static void perf_event_ops__fill_defaults(struct perf_event_ops *handler)
{
if (!handler->process_sample_event)
handler->process_sample_event = process_event_stub;
@@ -35,8 +33,6 @@ void register_perf_file_handler(struct perf_file_handler *handler)
handler->process_throttle_event = process_event_stub;
if (!handler->process_unthrottle_event)
handler->process_unthrottle_event = process_event_stub;
-
- curr_handler = handler;
}

static const char *event__name[] = {
@@ -63,6 +59,7 @@ void event__print_totals(void)
}

static int process_event(event_t *event, struct perf_session *session,
+ struct perf_event_ops *ops,
unsigned long offset, unsigned long head)
{
trace_event(event);
@@ -78,25 +75,25 @@ static int process_event(event_t *event, struct perf_session *session,

switch (event->header.type) {
case PERF_RECORD_SAMPLE:
- return curr_handler->process_sample_event(event, session);
+ return ops->process_sample_event(event, session);
case PERF_RECORD_MMAP:
- return curr_handler->process_mmap_event(event, session);
+ return ops->process_mmap_event(event, session);
case PERF_RECORD_COMM:
- return curr_handler->process_comm_event(event, session);
+ return ops->process_comm_event(event, session);
case PERF_RECORD_FORK:
- return curr_handler->process_fork_event(event, session);
+ return ops->process_fork_event(event, session);
case PERF_RECORD_EXIT:
- return curr_handler->process_exit_event(event, session);
+ return ops->process_exit_event(event, session);
case PERF_RECORD_LOST:
- return curr_handler->process_lost_event(event, session);
+ return ops->process_lost_event(event, session);
case PERF_RECORD_READ:
- return curr_handler->process_read_event(event, session);
+ return ops->process_read_event(event, session);
case PERF_RECORD_THROTTLE:
- return curr_handler->process_throttle_event(event, session);
+ return ops->process_throttle_event(event, session);
case PERF_RECORD_UNTHROTTLE:
- return curr_handler->process_unthrottle_event(event, session);
+ return ops->process_unthrottle_event(event, session);
default:
- curr_handler->total_unknown++;
+ ops->total_unknown++;
return -1;
}
}
@@ -131,6 +128,7 @@ out:
}

int perf_session__process_events(struct perf_session *self,
+ struct perf_event_ops *ops,
int full_paths, int *cwdlen, char **cwd)
{
int err;
@@ -142,10 +140,7 @@ int perf_session__process_events(struct perf_session *self,
uint32_t size;
char *buf;

- if (curr_handler == NULL) {
- pr_debug("Forgot to register perf file handler\n");
- return -EINVAL;
- }
+ perf_event_ops__fill_defaults(ops);

page_size = getpagesize();

@@ -153,8 +148,8 @@ int perf_session__process_events(struct perf_session *self,
sample_type = perf_header__sample_type(&self->header);

err = -EINVAL;
- if (curr_handler->sample_type_check &&
- curr_handler->sample_type_check(sample_type) < 0)
+ if (ops->sample_type_check &&
+ ops->sample_type_check(sample_type) < 0)
goto out_err;

if (!full_paths) {
@@ -210,7 +205,7 @@ more:
(void *)(long)event->header.size,
event->header.type);

- if (!size || process_event(event, self, offset, head) < 0) {
+ if (!size || process_event(event, self, ops, offset, head) < 0) {

dump_printf("%p [%p]: skipping unknown header type: %d\n",
(void *)(offset + head),
diff --git a/tools/perf/util/data_map.h b/tools/perf/util/data_map.h
deleted file mode 100644
index 6d4ae52..0000000
--- a/tools/perf/util/data_map.h
+++ /dev/null
@@ -1,32 +0,0 @@
-#ifndef __PERF_DATAMAP_H
-#define __PERF_DATAMAP_H
-
-#include "event.h"
-#include "header.h"
-#include "session.h"
-
-struct perf_session;
-
-typedef int (*event_type_handler_t)(event_t *self,
- struct perf_session *session);
-
-struct perf_file_handler {
- event_type_handler_t process_sample_event;
- event_type_handler_t process_mmap_event;
- event_type_handler_t process_comm_event;
- event_type_handler_t process_fork_event;
- event_type_handler_t process_exit_event;
- event_type_handler_t process_lost_event;
- event_type_handler_t process_read_event;
- event_type_handler_t process_throttle_event;
- event_type_handler_t process_unthrottle_event;
- int (*sample_type_check)(u64 sample_type);
- unsigned long total_unknown;
-};
-
-void register_perf_file_handler(struct perf_file_handler *handler);
-int perf_session__process_events(struct perf_session *self,
- int full_paths, int *cwdlen, char **cwd);
-int perf_header__read_build_ids(int input, u64 offset, u64 file_size);
-
-#endif
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index f2e8d87..8a0bca5 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -8,8 +8,8 @@
#include "header.h"
#include "../perf.h"
#include "trace-event.h"
+#include "session.h"
#include "symbol.h"
-#include "data_map.h"
#include "debug.h"

/*
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 707ce1c..3976686 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -48,7 +48,8 @@ out_close:
return -1;
}

-struct perf_session *perf_session__new(const char *filename, int mode, bool force)
+struct perf_session *perf_session__new(const char *filename, int mode,
+ bool force)
{
size_t len = strlen(filename) + 1;
struct perf_session *self = zalloc(sizeof(*self) + len);
diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h
index f3699c8..7a4c32c 100644
--- a/tools/perf/util/session.h
+++ b/tools/perf/util/session.h
@@ -1,6 +1,7 @@
#ifndef __PERF_SESSION_H
#define __PERF_SESSION_H

+#include "event.h"
#include "header.h"

struct perf_session {
@@ -10,7 +11,30 @@ struct perf_session {
char filename[0];
};

-struct perf_session *perf_session__new(const char *filename, int mode, bool force);
+typedef int (*event_op)(event_t *self, struct perf_session *session);
+
+struct perf_event_ops {
+ event_op process_sample_event;
+ event_op process_mmap_event;
+ event_op process_comm_event;
+ event_op process_fork_event;
+ event_op process_exit_event;
+ event_op process_lost_event;
+ event_op process_read_event;
+ event_op process_throttle_event;
+ event_op process_unthrottle_event;
+ int (*sample_type_check)(u64 sample_type);
+ unsigned long total_unknown;
+};
+
+struct perf_session *perf_session__new(const char *filename, int mode,
+ bool force);
void perf_session__delete(struct perf_session *self);

+int perf_session__process_events(struct perf_session *self,
+ struct perf_event_ops *event_ops,
+ int full_paths, int *cwdlen, char **cwd);
+
+int perf_header__read_build_ids(int input, u64 offset, u64 file_size);
+
#endif /* __PERF_SESSION_H */
--
1.6.2.5

2009-12-13 21:50:52

by Arnaldo Carvalho de Melo

[permalink] [raw]
Subject: [PATCH 3/6] perf session: Register the idle thread in perf_session__process_events

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

No need for all tools to register it and then immediately call
perf_session__process_events.

Cc: Frédéric Weisbecker <[email protected]>
Cc: Mike Galbraith <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Paul Mackerras <[email protected]>
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
---
tools/perf/builtin-annotate.c | 3 ---
tools/perf/builtin-kmem.c | 1 -
tools/perf/builtin-report.c | 4 ----
tools/perf/builtin-sched.c | 2 --
tools/perf/builtin-trace.c | 1 -
tools/perf/util/data_map.c | 16 ++++++++++++++++
tools/perf/util/thread.c | 12 ------------
tools/perf/util/thread.h | 1 -
8 files changed, 16 insertions(+), 24 deletions(-)

diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index 43e3bb3..93d765a 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -464,14 +464,11 @@ static int __cmd_annotate(void)
{
struct perf_session *session = perf_session__new(input_name, O_RDONLY,
force);
- struct thread *idle;
int ret;

if (session == NULL)
return -ENOMEM;

- idle = register_idle_thread();
-
ret = perf_session__process_events(session, &event_ops, 0,
&event__cwdlen, &event__cwd);
if (ret)
diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c
index 6f74bd8..37a8499 100644
--- a/tools/perf/builtin-kmem.c
+++ b/tools/perf/builtin-kmem.c
@@ -372,7 +372,6 @@ static int read_events(void)
if (session == NULL)
return -ENOMEM;

- register_idle_thread();
err = perf_session__process_events(session, &event_ops, 0,
&event__cwdlen, &event__cwd);
perf_session__delete(session);
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index c203eaf..4b37ac4 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -761,7 +761,6 @@ static struct perf_event_ops event_ops = {

static int __cmd_report(void)
{
- struct thread *idle;
int ret;
struct perf_session *session;

@@ -769,9 +768,6 @@ static int __cmd_report(void)
if (session == NULL)
return -ENOMEM;

- idle = register_idle_thread();
- thread__comm_adjust(idle);
-
if (show_threads)
perf_read_values_init(&show_threads_values);

diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c
index b5b4472..847ed51 100644
--- a/tools/perf/builtin-sched.c
+++ b/tools/perf/builtin-sched.c
@@ -1670,8 +1670,6 @@ static int read_events(void)
if (session == NULL)
return -ENOMEM;

- register_idle_thread();
-
err = perf_session__process_events(session, &event_ops, 0,
&event__cwdlen, &event__cwd);
perf_session__delete(session);
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index c404dec..40cb896 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -125,7 +125,6 @@ static struct perf_event_ops event_ops = {

static int __cmd_trace(struct perf_session *session)
{
- register_idle_thread();
return perf_session__process_events(session, &event_ops, 0,
&event__cwdlen, &event__cwd);
}
diff --git a/tools/perf/util/data_map.c b/tools/perf/util/data_map.c
index ba5bcfa..36e3bfe 100644
--- a/tools/perf/util/data_map.c
+++ b/tools/perf/util/data_map.c
@@ -1,6 +1,7 @@
#include "symbol.h"
#include "util.h"
#include "debug.h"
+#include "thread.h"
#include "session.h"

static unsigned long mmap_window = 32;
@@ -127,6 +128,18 @@ out:
return err;
}

+static struct thread *perf_session__register_idle_thread(struct perf_session *self __used)
+{
+ struct thread *thread = threads__findnew(0);
+
+ if (!thread || thread__set_comm(thread, "swapper")) {
+ pr_err("problem inserting idle task.\n");
+ thread = NULL;
+ }
+
+ return thread;
+}
+
int perf_session__process_events(struct perf_session *self,
struct perf_event_ops *ops,
int full_paths, int *cwdlen, char **cwd)
@@ -140,6 +153,9 @@ int perf_session__process_events(struct perf_session *self,
uint32_t size;
char *buf;

+ if (perf_session__register_idle_thread(self) == NULL)
+ return -ENOMEM;
+
perf_event_ops__fill_defaults(ops);

page_size = getpagesize();
diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c
index b68a00e..5c0ab14 100644
--- a/tools/perf/util/thread.c
+++ b/tools/perf/util/thread.c
@@ -161,18 +161,6 @@ struct thread *threads__findnew(pid_t pid)
return th;
}

-struct thread *register_idle_thread(void)
-{
- struct thread *thread = threads__findnew(0);
-
- if (!thread || thread__set_comm(thread, "swapper")) {
- fprintf(stderr, "problem inserting idle task.\n");
- exit(-1);
- }
-
- return thread;
-}
-
static void map_groups__remove_overlappings(struct map_groups *self,
struct map *map)
{
diff --git a/tools/perf/util/thread.h b/tools/perf/util/thread.h
index 1751802..2e35e1f 100644
--- a/tools/perf/util/thread.h
+++ b/tools/perf/util/thread.h
@@ -24,7 +24,6 @@ void map_groups__init(struct map_groups *self);
int thread__set_comm(struct thread *self, const char *comm);
int thread__comm_len(struct thread *self);
struct thread *threads__findnew(pid_t pid);
-struct thread *register_idle_thread(void);
void thread__insert_map(struct thread *self, struct map *map);
int thread__fork(struct thread *self, struct thread *parent);
size_t map_groups__fprintf_maps(struct map_groups *self, FILE *fp);
--
1.6.2.5

2009-12-13 21:51:30

by Arnaldo Carvalho de Melo

[permalink] [raw]
Subject: [PATCH 4/6] perf session: Reduce the number of parms to perf_session__process_events

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

By having the cwd/cwdlen in the perf_session struct and full_paths in
perf_event_ops.

Now its just a matter of passing the ops.

Cc: Frédéric Weisbecker <[email protected]>
Cc: Mike Galbraith <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Paul Mackerras <[email protected]>
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
---
tools/perf/builtin-annotate.c | 3 +--
tools/perf/builtin-kmem.c | 3 +--
tools/perf/builtin-report.c | 6 ++----
tools/perf/builtin-sched.c | 3 +--
tools/perf/builtin-timechart.c | 3 +--
tools/perf/builtin-trace.c | 3 +--
tools/perf/util/data_map.c | 32 ++++++++++++++++----------------
tools/perf/util/event.c | 8 +++-----
tools/perf/util/session.c | 4 ++++
tools/perf/util/session.h | 7 +++++--
10 files changed, 35 insertions(+), 37 deletions(-)

diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index 93d765a..a931b13 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -469,8 +469,7 @@ static int __cmd_annotate(void)
if (session == NULL)
return -ENOMEM;

- ret = perf_session__process_events(session, &event_ops, 0,
- &event__cwdlen, &event__cwd);
+ ret = perf_session__process_events(session, &event_ops);
if (ret)
goto out_delete;

diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c
index 37a8499..237155f 100644
--- a/tools/perf/builtin-kmem.c
+++ b/tools/perf/builtin-kmem.c
@@ -372,8 +372,7 @@ static int read_events(void)
if (session == NULL)
return -ENOMEM;

- err = perf_session__process_events(session, &event_ops, 0,
- &event__cwdlen, &event__cwd);
+ err = perf_session__process_events(session, &event_ops);
perf_session__delete(session);
return err;
}
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index 4b37ac4..26b9478 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -39,7 +39,6 @@ static struct strlist *dso_list, *comm_list, *sym_list;

static int force;

-static int full_paths;
static int show_nr_samples;

static int show_threads;
@@ -771,8 +770,7 @@ static int __cmd_report(void)
if (show_threads)
perf_read_values_init(&show_threads_values);

- ret = perf_session__process_events(session, &event_ops, full_paths,
- &event__cwdlen, &event__cwd);
+ ret = perf_session__process_events(session, &event_ops);
if (ret)
goto out_delete;

@@ -877,7 +875,7 @@ static const struct option options[] = {
"pretty printing style key: normal raw"),
OPT_STRING('s', "sort", &sort_order, "key[,key2...]",
"sort by key(s): pid, comm, dso, symbol, parent"),
- OPT_BOOLEAN('P', "full-paths", &full_paths,
+ OPT_BOOLEAN('P', "full-paths", &event_ops.full_paths,
"Don't shorten the pathnames taking into account the cwd"),
OPT_STRING('p', "parent", &parent_pattern, "regex",
"regex filter to identify parent, see: '--sort parent'"),
diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c
index 847ed51..1e4e508 100644
--- a/tools/perf/builtin-sched.c
+++ b/tools/perf/builtin-sched.c
@@ -1670,8 +1670,7 @@ static int read_events(void)
if (session == NULL)
return -ENOMEM;

- err = perf_session__process_events(session, &event_ops, 0,
- &event__cwdlen, &event__cwd);
+ err = perf_session__process_events(session, &event_ops);
perf_session__delete(session);
return err;
}
diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c
index 4b95cec..b5211fa 100644
--- a/tools/perf/builtin-timechart.c
+++ b/tools/perf/builtin-timechart.c
@@ -1062,8 +1062,7 @@ static int __cmd_timechart(void)
if (session == NULL)
return -ENOMEM;

- ret = perf_session__process_events(session, &event_ops, 0,
- &event__cwdlen, &event__cwd);
+ ret = perf_session__process_events(session, &event_ops);
if (ret)
goto out_delete;

diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index 40cb896..b7eb3fc 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -125,8 +125,7 @@ static struct perf_event_ops event_ops = {

static int __cmd_trace(struct perf_session *session)
{
- return perf_session__process_events(session, &event_ops, 0,
- &event__cwdlen, &event__cwd);
+ return perf_session__process_events(session, &event_ops);
}

struct script_spec {
diff --git a/tools/perf/util/data_map.c b/tools/perf/util/data_map.c
index 36e3bfe..ba2eb2c 100644
--- a/tools/perf/util/data_map.c
+++ b/tools/perf/util/data_map.c
@@ -4,9 +4,6 @@
#include "thread.h"
#include "session.h"

-static unsigned long mmap_window = 32;
-static char __cwd[PATH_MAX];
-
static int process_event_stub(event_t *event __used,
struct perf_session *session __used)
{
@@ -141,8 +138,7 @@ static struct thread *perf_session__register_idle_thread(struct perf_session *se
}

int perf_session__process_events(struct perf_session *self,
- struct perf_event_ops *ops,
- int full_paths, int *cwdlen, char **cwd)
+ struct perf_event_ops *ops)
{
int err;
unsigned long head, shift;
@@ -168,17 +164,21 @@ int perf_session__process_events(struct perf_session *self,
ops->sample_type_check(sample_type) < 0)
goto out_err;

- if (!full_paths) {
- if (getcwd(__cwd, sizeof(__cwd)) == NULL) {
- pr_err("failed to get the current directory\n");
+ if (!ops->full_paths) {
+ char bf[PATH_MAX];
+
+ if (getcwd(bf, sizeof(bf)) == NULL) {
err = -errno;
+out_getcwd_err:
+ pr_err("failed to get the current directory\n");
goto out_err;
}
- *cwd = __cwd;
- *cwdlen = strlen(*cwd);
- } else {
- *cwd = NULL;
- *cwdlen = 0;
+ self->cwd = strdup(bf);
+ if (self->cwd == NULL) {
+ err = -ENOMEM;
+ goto out_getcwd_err;
+ }
+ self->cwdlen = strlen(self->cwd);
}

shift = page_size * (head / page_size);
@@ -186,7 +186,7 @@ int perf_session__process_events(struct perf_session *self,
head -= shift;

remap:
- buf = mmap(NULL, page_size * mmap_window, PROT_READ,
+ buf = mmap(NULL, page_size * self->mmap_window, PROT_READ,
MAP_SHARED, self->fd, offset);
if (buf == MAP_FAILED) {
pr_err("failed to mmap file\n");
@@ -201,12 +201,12 @@ more:
if (!size)
size = 8;

- if (head + event->header.size >= page_size * mmap_window) {
+ if (head + event->header.size >= page_size * self->mmap_window) {
int munmap_ret;

shift = page_size * (head / page_size);

- munmap_ret = munmap(buf, page_size * mmap_window);
+ munmap_ret = munmap(buf, page_size * self->mmap_window);
assert(munmap_ret == 0);

offset += shift;
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index e2c4895..40d8d84 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -1,6 +1,7 @@
#include <linux/types.h>
#include "event.h"
#include "debug.h"
+#include "session.h"
#include "string.h"
#include "thread.h"

@@ -186,9 +187,6 @@ void event__synthesize_threads(int (*process)(event_t *event,
closedir(proc);
}

-char *event__cwd;
-int event__cwdlen;
-
struct events_stats event__stats;

int event__process_comm(event_t *self, struct perf_session *session __used)
@@ -212,11 +210,11 @@ int event__process_lost(event_t *self, struct perf_session *session __used)
return 0;
}

-int event__process_mmap(event_t *self, struct perf_session *session __used)
+int event__process_mmap(event_t *self, struct perf_session *session)
{
struct thread *thread = threads__findnew(self->mmap.pid);
struct map *map = map__new(&self->mmap, MAP__FUNCTION,
- event__cwd, event__cwdlen);
+ session->cwd, session->cwdlen);

dump_printf(" %d/%d: [%p(%p) @ %p]: %s\n",
self->mmap.pid, self->mmap.tid,
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 3976686..534a877 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -61,6 +61,9 @@ struct perf_session *perf_session__new(const char *filename, int mode,
goto out_delete;

memcpy(self->filename, filename, len);
+ self->mmap_window = 32;
+ self->cwd = NULL;
+ self->cwdlen = 0;

if (mode == O_RDONLY && perf_session__open(self, force) < 0) {
perf_session__delete(self);
@@ -77,5 +80,6 @@ void perf_session__delete(struct perf_session *self)
{
perf_header__exit(&self->header);
close(self->fd);
+ free(self->cwd);
free(self);
}
diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h
index 7a4c32c..1e0da9c 100644
--- a/tools/perf/util/session.h
+++ b/tools/perf/util/session.h
@@ -7,7 +7,10 @@
struct perf_session {
struct perf_header header;
unsigned long size;
+ unsigned long mmap_window;
int fd;
+ int cwdlen;
+ char *cwd;
char filename[0];
};

@@ -25,6 +28,7 @@ struct perf_event_ops {
event_op process_unthrottle_event;
int (*sample_type_check)(u64 sample_type);
unsigned long total_unknown;
+ bool full_paths;
};

struct perf_session *perf_session__new(const char *filename, int mode,
@@ -32,8 +36,7 @@ struct perf_session *perf_session__new(const char *filename, int mode,
void perf_session__delete(struct perf_session *self);

int perf_session__process_events(struct perf_session *self,
- struct perf_event_ops *event_ops,
- int full_paths, int *cwdlen, char **cwd);
+ struct perf_event_ops *event_ops);

int perf_header__read_build_ids(int input, u64 offset, u64 file_size);

--
1.6.2.5

2009-12-13 21:51:26

by Arnaldo Carvalho de Melo

[permalink] [raw]
Subject: [PATCH 5/6] perf session: Move the global threads list to perf_session

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

So that we can process two perf.data files.

We still need to add a O_MMAP mode for perf_session so that we can do
all the mmap stuff in it.

Cc: Frédéric Weisbecker <[email protected]>
Cc: Mike Galbraith <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Paul Mackerras <[email protected]>
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
---
tools/perf/builtin-annotate.c | 6 ++--
tools/perf/builtin-kmem.c | 4 +-
tools/perf/builtin-report.c | 10 +++---
tools/perf/builtin-sched.c | 68 ++++++++++++++++++++++++----------------
tools/perf/builtin-top.c | 19 +++++++----
tools/perf/builtin-trace.c | 4 +-
tools/perf/util/data_map.c | 4 +-
tools/perf/util/event.c | 18 +++++-----
tools/perf/util/event.h | 4 +-
tools/perf/util/session.c | 4 ++-
tools/perf/util/session.h | 5 +++
tools/perf/util/thread.c | 22 ++++++-------
tools/perf/util/thread.h | 4 +-
13 files changed, 98 insertions(+), 74 deletions(-)

diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index a931b13..795f865 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -131,14 +131,14 @@ static int hist_entry__add(struct addr_location *al, u64 count)
return 0;
}

-static int process_sample_event(event_t *event, struct perf_session *session __used)
+static int process_sample_event(event_t *event, struct perf_session *session)
{
struct addr_location al;

dump_printf("(IP, %d): %d: %p\n", event->header.misc,
event->ip.pid, (void *)(long)event->ip.ip);

- if (event__preprocess_sample(event, &al, symbol_filter) < 0) {
+ if (event__preprocess_sample(event, session, &al, symbol_filter) < 0) {
fprintf(stderr, "problem processing %d event, skipping it.\n",
event->header.type);
return -1;
@@ -479,7 +479,7 @@ static int __cmd_annotate(void)
}

if (verbose > 3)
- threads__fprintf(stdout);
+ perf_session__fprintf(session, stdout);

if (verbose > 2)
dsos__fprintf(stdout);
diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c
index 237155f..de19495 100644
--- a/tools/perf/builtin-kmem.c
+++ b/tools/perf/builtin-kmem.c
@@ -311,7 +311,7 @@ process_raw_event(event_t *raw_event __used, void *data,
}
}

-static int process_sample_event(event_t *event, struct perf_session *session __used)
+static int process_sample_event(event_t *event, struct perf_session *session)
{
struct sample_data data;
struct thread *thread;
@@ -329,7 +329,7 @@ static int process_sample_event(event_t *event, struct perf_session *session __u
(void *)(long)data.ip,
(long long)data.period);

- thread = threads__findnew(event->ip.pid);
+ thread = perf_session__findnew(session, event->ip.pid);
if (thread == NULL) {
pr_debug("problem processing %d event, skipping it.\n",
event->header.type);
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index 26b9478..efa8147 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -600,7 +600,7 @@ static int validate_chain(struct ip_callchain *chain, event_t *event)
return 0;
}

-static int process_sample_event(event_t *event, struct perf_session *session __used)
+static int process_sample_event(event_t *event, struct perf_session *session)
{
struct sample_data data;
int cpumode;
@@ -636,7 +636,7 @@ static int process_sample_event(event_t *event, struct perf_session *session __u
}
}

- thread = threads__findnew(data.pid);
+ thread = perf_session__findnew(session, data.pid);
if (thread == NULL) {
pr_debug("problem processing %d event, skipping it.\n",
event->header.type);
@@ -679,9 +679,9 @@ static int process_sample_event(event_t *event, struct perf_session *session __u
return 0;
}

-static int process_comm_event(event_t *event, struct perf_session *session __used)
+static int process_comm_event(event_t *event, struct perf_session *session)
{
- struct thread *thread = threads__findnew(event->comm.pid);
+ struct thread *thread = perf_session__findnew(session, event->comm.pid);

dump_printf(": %s:%d\n", event->comm.comm, event->comm.pid);

@@ -780,7 +780,7 @@ static int __cmd_report(void)
}

if (verbose > 3)
- threads__fprintf(stdout);
+ perf_session__fprintf(session, stdout);

if (verbose > 2)
dsos__fprintf(stdout);
diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c
index 1e4e508..8d58d9e 100644
--- a/tools/perf/builtin-sched.c
+++ b/tools/perf/builtin-sched.c
@@ -730,18 +730,21 @@ struct trace_migrate_task_event {

struct trace_sched_handler {
void (*switch_event)(struct trace_switch_event *,
+ struct perf_session *,
struct event *,
int cpu,
u64 timestamp,
struct thread *thread);

void (*runtime_event)(struct trace_runtime_event *,
+ struct perf_session *,
struct event *,
int cpu,
u64 timestamp,
struct thread *thread);

void (*wakeup_event)(struct trace_wakeup_event *,
+ struct perf_session *,
struct event *,
int cpu,
u64 timestamp,
@@ -754,6 +757,7 @@ struct trace_sched_handler {
struct thread *thread);

void (*migrate_task_event)(struct trace_migrate_task_event *,
+ struct perf_session *session,
struct event *,
int cpu,
u64 timestamp,
@@ -763,6 +767,7 @@ struct trace_sched_handler {

static void
replay_wakeup_event(struct trace_wakeup_event *wakeup_event,
+ struct perf_session *session __used,
struct event *event,
int cpu __used,
u64 timestamp __used,
@@ -789,6 +794,7 @@ static u64 cpu_last_switched[MAX_CPUS];

static void
replay_switch_event(struct trace_switch_event *switch_event,
+ struct perf_session *session __used,
struct event *event,
int cpu,
u64 timestamp,
@@ -1022,6 +1028,7 @@ add_sched_in_event(struct work_atoms *atoms, u64 timestamp)

static void
latency_switch_event(struct trace_switch_event *switch_event,
+ struct perf_session *session,
struct event *event __used,
int cpu,
u64 timestamp,
@@ -1045,8 +1052,8 @@ latency_switch_event(struct trace_switch_event *switch_event,
die("hm, delta: %Ld < 0 ?\n", delta);


- sched_out = threads__findnew(switch_event->prev_pid);
- sched_in = threads__findnew(switch_event->next_pid);
+ sched_out = perf_session__findnew(session, switch_event->prev_pid);
+ sched_in = perf_session__findnew(session, switch_event->next_pid);

out_events = thread_atoms_search(&atom_root, sched_out, &cmp_pid);
if (!out_events) {
@@ -1074,12 +1081,13 @@ latency_switch_event(struct trace_switch_event *switch_event,

static void
latency_runtime_event(struct trace_runtime_event *runtime_event,
+ struct perf_session *session,
struct event *event __used,
int cpu,
u64 timestamp,
struct thread *this_thread __used)
{
- struct thread *thread = threads__findnew(runtime_event->pid);
+ struct thread *thread = perf_session__findnew(session, runtime_event->pid);
struct work_atoms *atoms = thread_atoms_search(&atom_root, thread, &cmp_pid);

BUG_ON(cpu >= MAX_CPUS || cpu < 0);
@@ -1096,6 +1104,7 @@ latency_runtime_event(struct trace_runtime_event *runtime_event,

static void
latency_wakeup_event(struct trace_wakeup_event *wakeup_event,
+ struct perf_session *session,
struct event *__event __used,
int cpu __used,
u64 timestamp,
@@ -1109,7 +1118,7 @@ latency_wakeup_event(struct trace_wakeup_event *wakeup_event,
if (!wakeup_event->success)
return;

- wakee = threads__findnew(wakeup_event->pid);
+ wakee = perf_session__findnew(session, wakeup_event->pid);
atoms = thread_atoms_search(&atom_root, wakee, &cmp_pid);
if (!atoms) {
thread_atoms_insert(wakee);
@@ -1143,6 +1152,7 @@ latency_wakeup_event(struct trace_wakeup_event *wakeup_event,

static void
latency_migrate_task_event(struct trace_migrate_task_event *migrate_task_event,
+ struct perf_session *session,
struct event *__event __used,
int cpu __used,
u64 timestamp,
@@ -1158,7 +1168,7 @@ latency_migrate_task_event(struct trace_migrate_task_event *migrate_task_event,
if (profile_cpu == -1)
return;

- migrant = threads__findnew(migrate_task_event->pid);
+ migrant = perf_session__findnew(session, migrate_task_event->pid);
atoms = thread_atoms_search(&atom_root, migrant, &cmp_pid);
if (!atoms) {
thread_atoms_insert(migrant);
@@ -1353,7 +1363,7 @@ static void sort_lat(void)
static struct trace_sched_handler *trace_handler;

static void
-process_sched_wakeup_event(void *data,
+process_sched_wakeup_event(void *data, struct perf_session *session,
struct event *event,
int cpu __used,
u64 timestamp __used,
@@ -1370,7 +1380,8 @@ process_sched_wakeup_event(void *data,
FILL_FIELD(wakeup_event, cpu, event, data);

if (trace_handler->wakeup_event)
- trace_handler->wakeup_event(&wakeup_event, event, cpu, timestamp, thread);
+ trace_handler->wakeup_event(&wakeup_event, session, event,
+ cpu, timestamp, thread);
}

/*
@@ -1388,6 +1399,7 @@ static char next_shortname2 = '0';

static void
map_switch_event(struct trace_switch_event *switch_event,
+ struct perf_session *session,
struct event *event __used,
int this_cpu,
u64 timestamp,
@@ -1415,8 +1427,8 @@ map_switch_event(struct trace_switch_event *switch_event,
die("hm, delta: %Ld < 0 ?\n", delta);


- sched_out = threads__findnew(switch_event->prev_pid);
- sched_in = threads__findnew(switch_event->next_pid);
+ sched_out = perf_session__findnew(session, switch_event->prev_pid);
+ sched_in = perf_session__findnew(session, switch_event->next_pid);

curr_thread[this_cpu] = sched_in;

@@ -1466,7 +1478,7 @@ map_switch_event(struct trace_switch_event *switch_event,


static void
-process_sched_switch_event(void *data,
+process_sched_switch_event(void *data, struct perf_session *session,
struct event *event,
int this_cpu,
u64 timestamp __used,
@@ -1493,13 +1505,14 @@ process_sched_switch_event(void *data,
nr_context_switch_bugs++;
}
if (trace_handler->switch_event)
- trace_handler->switch_event(&switch_event, event, this_cpu, timestamp, thread);
+ trace_handler->switch_event(&switch_event, session, event,
+ this_cpu, timestamp, thread);

curr_pid[this_cpu] = switch_event.next_pid;
}

static void
-process_sched_runtime_event(void *data,
+process_sched_runtime_event(void *data, struct perf_session *session,
struct event *event,
int cpu __used,
u64 timestamp __used,
@@ -1513,7 +1526,7 @@ process_sched_runtime_event(void *data,
FILL_FIELD(runtime_event, vruntime, event, data);

if (trace_handler->runtime_event)
- trace_handler->runtime_event(&runtime_event, event, cpu, timestamp, thread);
+ trace_handler->runtime_event(&runtime_event, session, event, cpu, timestamp, thread);
}

static void
@@ -1533,7 +1546,8 @@ process_sched_fork_event(void *data,
FILL_FIELD(fork_event, child_pid, event, data);

if (trace_handler->fork_event)
- trace_handler->fork_event(&fork_event, event, cpu, timestamp, thread);
+ trace_handler->fork_event(&fork_event, event,
+ cpu, timestamp, thread);
}

static void
@@ -1547,7 +1561,7 @@ process_sched_exit_event(struct event *event,
}

static void
-process_sched_migrate_task_event(void *data,
+process_sched_migrate_task_event(void *data, struct perf_session *session,
struct event *event,
int cpu __used,
u64 timestamp __used,
@@ -1563,12 +1577,13 @@ process_sched_migrate_task_event(void *data,
FILL_FIELD(migrate_task_event, cpu, event, data);

if (trace_handler->migrate_task_event)
- trace_handler->migrate_task_event(&migrate_task_event, event, cpu, timestamp, thread);
+ trace_handler->migrate_task_event(&migrate_task_event, session,
+ event, cpu, timestamp, thread);
}

static void
-process_raw_event(event_t *raw_event __used, void *data,
- int cpu, u64 timestamp, struct thread *thread)
+process_raw_event(event_t *raw_event __used, struct perf_session *session,
+ void *data, int cpu, u64 timestamp, struct thread *thread)
{
struct event *event;
int type;
@@ -1578,23 +1593,22 @@ process_raw_event(event_t *raw_event __used, void *data,
event = trace_find_event(type);

if (!strcmp(event->name, "sched_switch"))
- process_sched_switch_event(data, event, cpu, timestamp, thread);
+ process_sched_switch_event(data, session, event, cpu, timestamp, thread);
if (!strcmp(event->name, "sched_stat_runtime"))
- process_sched_runtime_event(data, event, cpu, timestamp, thread);
+ process_sched_runtime_event(data, session, event, cpu, timestamp, thread);
if (!strcmp(event->name, "sched_wakeup"))
- process_sched_wakeup_event(data, event, cpu, timestamp, thread);
+ process_sched_wakeup_event(data, session, event, cpu, timestamp, thread);
if (!strcmp(event->name, "sched_wakeup_new"))
- process_sched_wakeup_event(data, event, cpu, timestamp, thread);
+ process_sched_wakeup_event(data, session, event, cpu, timestamp, thread);
if (!strcmp(event->name, "sched_process_fork"))
process_sched_fork_event(data, event, cpu, timestamp, thread);
if (!strcmp(event->name, "sched_process_exit"))
process_sched_exit_event(event, cpu, timestamp, thread);
if (!strcmp(event->name, "sched_migrate_task"))
- process_sched_migrate_task_event(data, event, cpu, timestamp, thread);
+ process_sched_migrate_task_event(data, session, event, cpu, timestamp, thread);
}

-static int process_sample_event(event_t *event,
- struct perf_session *session __used)
+static int process_sample_event(event_t *event, struct perf_session *session)
{
struct sample_data data;
struct thread *thread;
@@ -1615,7 +1629,7 @@ static int process_sample_event(event_t *event,
(void *)(long)data.ip,
(long long)data.period);

- thread = threads__findnew(data.pid);
+ thread = perf_session__findnew(session, data.pid);
if (thread == NULL) {
pr_debug("problem processing %d event, skipping it.\n",
event->header.type);
@@ -1627,7 +1641,7 @@ static int process_sample_event(event_t *event,
if (profile_cpu != -1 && profile_cpu != (int)data.cpu)
return 0;

- process_raw_event(event, data.raw_data, data.cpu, data.time, thread);
+ process_raw_event(event, session, data.raw_data, data.cpu, data.time, thread);

return 0;
}
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index b13f426..0f7a4da 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -20,8 +20,9 @@

#include "perf.h"

-#include "util/symbol.h"
#include "util/color.h"
+#include "util/session.h"
+#include "util/symbol.h"
#include "util/thread.h"
#include "util/util.h"
#include <linux/rbtree.h>
@@ -926,7 +927,8 @@ static int symbol_filter(struct map *map, struct symbol *sym)
return 0;
}

-static void event__process_sample(const event_t *self, int counter)
+static void event__process_sample(const event_t *self,
+ struct perf_session *session, int counter)
{
u64 ip = self->ip.ip;
struct sym_entry *syme;
@@ -946,7 +948,7 @@ static void event__process_sample(const event_t *self, int counter)
return;
}

- if (event__preprocess_sample(self, &al, symbol_filter) < 0 ||
+ if (event__preprocess_sample(self, session, &al, symbol_filter) < 0 ||
al.sym == NULL)
return;

@@ -1053,7 +1055,7 @@ static void perf_session__mmap_read_counter(struct perf_session *self,
}

if (event->header.type == PERF_RECORD_SAMPLE)
- event__process_sample(event, md->counter);
+ event__process_sample(event, self, md->counter);
else
event__process(event, self);
old += size;
@@ -1157,10 +1159,13 @@ static int __cmd_top(void)
int i, counter;
int ret;
/*
- * XXX perf_session__new should allow passing a O_MMAP, so that all this
- * mmap reading, etc is encapsulated in it.
+ * FIXME: perf_session__new should allow passing a O_MMAP, so that all this
+ * mmap reading, etc is encapsulated in it. Use O_WRONLY for now.
*/
- struct perf_session *session = NULL;
+ struct perf_session *session = perf_session__new(NULL, O_WRONLY, false);
+
+ if (session == NULL)
+ return -ENOMEM;

if (target_pid != -1)
event__synthesize_thread(target_pid, event__process, session);
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index b7eb3fc..d765323 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -63,7 +63,7 @@ static char const *input_name = "perf.data";

static u64 sample_type;

-static int process_sample_event(event_t *event, struct perf_session *session __used)
+static int process_sample_event(event_t *event, struct perf_session *session)
{
struct sample_data data;
struct thread *thread;
@@ -81,7 +81,7 @@ static int process_sample_event(event_t *event, struct perf_session *session __u
(void *)(long)data.ip,
(long long)data.period);

- thread = threads__findnew(event->ip.pid);
+ thread = perf_session__findnew(session, event->ip.pid);
if (thread == NULL) {
pr_debug("problem processing %d event, skipping it.\n",
event->header.type);
diff --git a/tools/perf/util/data_map.c b/tools/perf/util/data_map.c
index ba2eb2c..44dea21 100644
--- a/tools/perf/util/data_map.c
+++ b/tools/perf/util/data_map.c
@@ -125,9 +125,9 @@ out:
return err;
}

-static struct thread *perf_session__register_idle_thread(struct perf_session *self __used)
+static struct thread *perf_session__register_idle_thread(struct perf_session *self)
{
- struct thread *thread = threads__findnew(0);
+ struct thread *thread = perf_session__findnew(self, 0);

if (!thread || thread__set_comm(thread, "swapper")) {
pr_err("problem inserting idle task.\n");
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index 40d8d84..2d09c29 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -189,9 +189,9 @@ void event__synthesize_threads(int (*process)(event_t *event,

struct events_stats event__stats;

-int event__process_comm(event_t *self, struct perf_session *session __used)
+int event__process_comm(event_t *self, struct perf_session *session)
{
- struct thread *thread = threads__findnew(self->comm.pid);
+ struct thread *thread = perf_session__findnew(session, self->comm.pid);

dump_printf(": %s:%d\n", self->comm.comm, self->comm.pid);

@@ -212,7 +212,7 @@ int event__process_lost(event_t *self, struct perf_session *session __used)

int event__process_mmap(event_t *self, struct perf_session *session)
{
- struct thread *thread = threads__findnew(self->mmap.pid);
+ struct thread *thread = perf_session__findnew(session, self->mmap.pid);
struct map *map = map__new(&self->mmap, MAP__FUNCTION,
session->cwd, session->cwdlen);

@@ -231,10 +231,10 @@ int event__process_mmap(event_t *self, struct perf_session *session)
return 0;
}

-int event__process_task(event_t *self, struct perf_session *session __used)
+int event__process_task(event_t *self, struct perf_session *session)
{
- struct thread *thread = threads__findnew(self->fork.pid);
- struct thread *parent = threads__findnew(self->fork.ppid);
+ struct thread *thread = perf_session__findnew(session, self->fork.pid);
+ struct thread *parent = perf_session__findnew(session, self->fork.ppid);

dump_printf("(%d:%d):(%d:%d)\n", self->fork.pid, self->fork.tid,
self->fork.ppid, self->fork.ptid);
@@ -300,11 +300,11 @@ try_again:
}
}

-int event__preprocess_sample(const event_t *self, struct addr_location *al,
- symbol_filter_t filter)
+int event__preprocess_sample(const event_t *self, struct perf_session *session,
+ struct addr_location *al, symbol_filter_t filter)
{
u8 cpumode = self->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
- struct thread *thread = threads__findnew(self->ip.pid);
+ struct thread *thread = perf_session__findnew(session, self->ip.pid);

if (thread == NULL)
return -1;
diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h
index 6b6429b..bb09025 100644
--- a/tools/perf/util/event.h
+++ b/tools/perf/util/event.h
@@ -177,8 +177,8 @@ int event__process_mmap(event_t *self, struct perf_session *session);
int event__process_task(event_t *self, struct perf_session *session);

struct addr_location;
-int event__preprocess_sample(const event_t *self, struct addr_location *al,
- symbol_filter_t filter);
+int event__preprocess_sample(const event_t *self, struct perf_session *session,
+ struct addr_location *al, symbol_filter_t filter);
int event__parse_sample(event_t *event, u64 type, struct sample_data *data);

#endif /* __PERF_RECORD_H */
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 534a877..09836a5 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -51,7 +51,7 @@ out_close:
struct perf_session *perf_session__new(const char *filename, int mode,
bool force)
{
- size_t len = strlen(filename) + 1;
+ size_t len = filename ? strlen(filename) + 1 : 0;
struct perf_session *self = zalloc(sizeof(*self) + len);

if (self == NULL)
@@ -61,6 +61,8 @@ struct perf_session *perf_session__new(const char *filename, int mode,
goto out_delete;

memcpy(self->filename, filename, len);
+ self->threads = RB_ROOT;
+ self->last_match = NULL;
self->mmap_window = 32;
self->cwd = NULL;
self->cwdlen = 0;
diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h
index 1e0da9c..1dbef7c 100644
--- a/tools/perf/util/session.h
+++ b/tools/perf/util/session.h
@@ -3,11 +3,16 @@

#include "event.h"
#include "header.h"
+#include <linux/rbtree.h>
+
+struct thread;

struct perf_session {
struct perf_header header;
unsigned long size;
unsigned long mmap_window;
+ struct rb_root threads;
+ struct thread *last_match;
int fd;
int cwdlen;
char *cwd;
diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c
index 5c0ab14..634b7f7 100644
--- a/tools/perf/util/thread.c
+++ b/tools/perf/util/thread.c
@@ -2,13 +2,11 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
+#include "session.h"
#include "thread.h"
#include "util.h"
#include "debug.h"

-static struct rb_root threads;
-static struct thread *last_match;
-
void map_groups__init(struct map_groups *self)
{
int i;
@@ -122,9 +120,9 @@ static size_t thread__fprintf(struct thread *self, FILE *fp)
map_groups__fprintf(&self->mg, fp);
}

-struct thread *threads__findnew(pid_t pid)
+struct thread *perf_session__findnew(struct perf_session *self, pid_t pid)
{
- struct rb_node **p = &threads.rb_node;
+ struct rb_node **p = &self->threads.rb_node;
struct rb_node *parent = NULL;
struct thread *th;

@@ -133,15 +131,15 @@ struct thread *threads__findnew(pid_t pid)
* so most of the time we dont have to look up
* the full rbtree:
*/
- if (last_match && last_match->pid == pid)
- return last_match;
+ if (self->last_match && self->last_match->pid == pid)
+ return self->last_match;

while (*p != NULL) {
parent = *p;
th = rb_entry(parent, struct thread, rb_node);

if (th->pid == pid) {
- last_match = th;
+ self->last_match = th;
return th;
}

@@ -154,8 +152,8 @@ struct thread *threads__findnew(pid_t pid)
th = thread__new(pid);
if (th != NULL) {
rb_link_node(&th->rb_node, parent, p);
- rb_insert_color(&th->rb_node, &threads);
- last_match = th;
+ rb_insert_color(&th->rb_node, &self->threads);
+ self->last_match = th;
}

return th;
@@ -269,12 +267,12 @@ int thread__fork(struct thread *self, struct thread *parent)
return 0;
}

-size_t threads__fprintf(FILE *fp)
+size_t perf_session__fprintf(struct perf_session *self, FILE *fp)
{
size_t ret = 0;
struct rb_node *nd;

- for (nd = rb_first(&threads); nd; nd = rb_next(nd)) {
+ for (nd = rb_first(&self->threads); nd; nd = rb_next(nd)) {
struct thread *pos = rb_entry(nd, struct thread, rb_node);

ret += thread__fprintf(pos, fp);
diff --git a/tools/perf/util/thread.h b/tools/perf/util/thread.h
index 2e35e1f..e93abf2 100644
--- a/tools/perf/util/thread.h
+++ b/tools/perf/util/thread.h
@@ -23,11 +23,11 @@ struct thread {
void map_groups__init(struct map_groups *self);
int thread__set_comm(struct thread *self, const char *comm);
int thread__comm_len(struct thread *self);
-struct thread *threads__findnew(pid_t pid);
+struct thread *perf_session__findnew(struct perf_session *self, pid_t pid);
void thread__insert_map(struct thread *self, struct map *map);
int thread__fork(struct thread *self, struct thread *parent);
size_t map_groups__fprintf_maps(struct map_groups *self, FILE *fp);
-size_t threads__fprintf(FILE *fp);
+size_t perf_session__fprintf(struct perf_session *self, FILE *fp);

void maps__insert(struct rb_root *maps, struct map *map);
struct map *maps__find(struct rb_root *maps, u64 addr);
--
1.6.2.5

2009-12-13 21:50:54

by Arnaldo Carvalho de Melo

[permalink] [raw]
Subject: [PATCH 6/6] perf session: Move kmaps to perf_session

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

There is still some more work to do to disentangle map creation from DSO
loading, but this happens only for the kernel, and for the early
adopters of perf diff, where this disentanglement matters most, we'll be
testing different kernels, so no problem here.

Further clarification: right now we create the kernel maps for the
various modules and discontiguous kernel text maps when loading the DSO,
we should do it as a two step process, first creating the maps, for
multiple mappings with the same DSO store, then doing the dso load just
once, for the first hit on one of the maps sharing this DSO backing
store.

Cc: Frédéric Weisbecker <[email protected]>
Cc: Mike Galbraith <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Paul Mackerras <[email protected]>
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
---
tools/perf/builtin-annotate.c | 2 +-
tools/perf/builtin-buildid-list.c | 4 +-
tools/perf/builtin-kmem.c | 41 ++++++++---------
tools/perf/builtin-record.c | 2 +-
tools/perf/builtin-report.c | 14 +++---
tools/perf/builtin-sched.c | 4 +-
tools/perf/builtin-timechart.c | 3 +-
tools/perf/builtin-top.c | 4 +-
tools/perf/builtin-trace.c | 2 +-
tools/perf/util/event.c | 13 +++---
tools/perf/util/event.h | 10 +++--
tools/perf/util/map.c | 14 +++---
tools/perf/util/session.c | 19 +++++---
tools/perf/util/session.h | 6 ++-
tools/perf/util/symbol.c | 89 ++++++++++++++++++-------------------
tools/perf/util/symbol.h | 11 +++--
tools/perf/util/thread.c | 3 +-
tools/perf/util/thread.h | 11 +++--
18 files changed, 134 insertions(+), 118 deletions(-)

diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index 795f865..e44c54c 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -463,7 +463,7 @@ static struct perf_event_ops event_ops = {
static int __cmd_annotate(void)
{
struct perf_session *session = perf_session__new(input_name, O_RDONLY,
- force);
+ force, &symbol_conf);
int ret;

if (session == NULL)
diff --git a/tools/perf/builtin-buildid-list.c b/tools/perf/builtin-buildid-list.c
index 2629f76..7c36e4b 100644
--- a/tools/perf/builtin-buildid-list.c
+++ b/tools/perf/builtin-buildid-list.c
@@ -54,8 +54,8 @@ static int perf_file_section__process_buildids(struct perf_file_section *self,
static int __cmd_buildid_list(void)
{
int err = -1;
- struct perf_session *session = perf_session__new(input_name, O_RDONLY, force);
-
+ struct perf_session *session = perf_session__new(input_name, O_RDONLY,
+ force, NULL);
if (session == NULL)
return -1;

diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c
index de19495..e79ecbc 100644
--- a/tools/perf/builtin-kmem.c
+++ b/tools/perf/builtin-kmem.c
@@ -364,19 +364,6 @@ static struct perf_event_ops event_ops = {
.sample_type_check = sample_type_check,
};

-static int read_events(void)
-{
- int err;
- struct perf_session *session = perf_session__new(input_name, O_RDONLY, 0);
-
- if (session == NULL)
- return -ENOMEM;
-
- err = perf_session__process_events(session, &event_ops);
- perf_session__delete(session);
- return err;
-}
-
static double fragmentation(unsigned long n_req, unsigned long n_alloc)
{
if (n_alloc == 0)
@@ -385,7 +372,8 @@ static double fragmentation(unsigned long n_req, unsigned long n_alloc)
return 100.0 - (100.0 * n_req / n_alloc);
}

-static void __print_result(struct rb_root *root, int n_lines, int is_caller)
+static void __print_result(struct rb_root *root, struct perf_session *session,
+ int n_lines, int is_caller)
{
struct rb_node *next;

@@ -406,7 +394,7 @@ static void __print_result(struct rb_root *root, int n_lines, int is_caller)
if (is_caller) {
addr = data->call_site;
if (!raw_ip)
- sym = map_groups__find_function(kmaps, addr, NULL);
+ sym = map_groups__find_function(&session->kmaps, session, addr, NULL);
} else
addr = data->ptr;

@@ -447,12 +435,12 @@ static void print_summary(void)
printf("Cross CPU allocations: %lu/%lu\n", nr_cross_allocs, nr_allocs);
}

-static void print_result(void)
+static void print_result(struct perf_session *session)
{
if (caller_flag)
- __print_result(&root_caller_sorted, caller_lines, 1);
+ __print_result(&root_caller_sorted, session, caller_lines, 1);
if (alloc_flag)
- __print_result(&root_alloc_sorted, alloc_lines, 0);
+ __print_result(&root_alloc_sorted, session, alloc_lines, 0);
print_summary();
}

@@ -520,12 +508,21 @@ static void sort_result(void)

static int __cmd_kmem(void)
{
+ int err;
+ struct perf_session *session = perf_session__new(input_name, O_RDONLY,
+ 0, NULL);
+ if (session == NULL)
+ return -ENOMEM;
+
setup_pager();
- read_events();
+ err = perf_session__process_events(session, &event_ops);
+ if (err != 0)
+ goto out_delete;
sort_result();
- print_result();
-
- return 0;
+ print_result(session);
+out_delete:
+ perf_session__delete(session);
+ return err;
}

static const char * const kmem_usage[] = {
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index b7e15a1..a66a58d 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -442,7 +442,7 @@ static int __cmd_record(int argc, const char **argv)
exit(-1);
}

- session = perf_session__new(output_name, O_WRONLY, force);
+ session = perf_session__new(output_name, O_WRONLY, force, NULL);
if (session == NULL) {
pr_err("Not enough memory for reading perf file header\n");
return -1;
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index efa8147..3487224 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -414,6 +414,7 @@ static int call__match(struct symbol *sym)
}

static struct symbol **resolve_callchain(struct thread *thread,
+ struct perf_session *session,
struct ip_callchain *chain,
struct symbol **parent)
{
@@ -447,8 +448,8 @@ static struct symbol **resolve_callchain(struct thread *thread,
continue;
}

- thread__find_addr_location(thread, cpumode, MAP__FUNCTION,
- ip, &al, NULL);
+ thread__find_addr_location(thread, session, cpumode,
+ MAP__FUNCTION, ip, &al, NULL);
if (al.sym != NULL) {
if (sort__has_parent && !*parent &&
call__match(al.sym))
@@ -467,6 +468,7 @@ static struct symbol **resolve_callchain(struct thread *thread,
*/

static int hist_entry__add(struct addr_location *al,
+ struct perf_session *session,
struct ip_callchain *chain, u64 count)
{
struct symbol **syms = NULL, *parent = NULL;
@@ -474,7 +476,7 @@ static int hist_entry__add(struct addr_location *al,
struct hist_entry *he;

if ((sort__has_parent || callchain) && chain)
- syms = resolve_callchain(al->thread, chain, &parent);
+ syms = resolve_callchain(al->thread, session, chain, &parent);

he = __hist_entry__add(al, parent, count, &hit);
if (he == NULL)
@@ -650,7 +652,7 @@ static int process_sample_event(event_t *event, struct perf_session *session)

cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;

- thread__find_addr_location(thread, cpumode,
+ thread__find_addr_location(thread, session, cpumode,
MAP__FUNCTION, data.ip, &al, NULL);
/*
* We have to do this here as we may have a dso with no symbol hit that
@@ -669,7 +671,7 @@ static int process_sample_event(event_t *event, struct perf_session *session)
if (sym_list && al.sym && !strlist__has_entry(sym_list, al.sym->name))
return 0;

- if (hist_entry__add(&al, data.callchain, data.period)) {
+ if (hist_entry__add(&al, session, data.callchain, data.period)) {
pr_debug("problem incrementing symbol count, skipping event\n");
return -1;
}
@@ -763,7 +765,7 @@ static int __cmd_report(void)
int ret;
struct perf_session *session;

- session = perf_session__new(input_name, O_RDONLY, force);
+ session = perf_session__new(input_name, O_RDONLY, force, &symbol_conf);
if (session == NULL)
return -ENOMEM;

diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c
index 8d58d9e..bce05df 100644
--- a/tools/perf/builtin-sched.c
+++ b/tools/perf/builtin-sched.c
@@ -1679,8 +1679,8 @@ static struct perf_event_ops event_ops = {
static int read_events(void)
{
int err;
- struct perf_session *session = perf_session__new(input_name, O_RDONLY, 0);
-
+ struct perf_session *session = perf_session__new(input_name, O_RDONLY,
+ 0, NULL);
if (session == NULL)
return -ENOMEM;

diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c
index b5211fa..2701853 100644
--- a/tools/perf/builtin-timechart.c
+++ b/tools/perf/builtin-timechart.c
@@ -1056,7 +1056,8 @@ static struct perf_event_ops event_ops = {

static int __cmd_timechart(void)
{
- struct perf_session *session = perf_session__new(input_name, O_RDONLY, 0);
+ struct perf_session *session = perf_session__new(input_name, O_RDONLY,
+ 0, NULL);
int ret;

if (session == NULL)
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index 0f7a4da..3b212bb 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -1162,8 +1162,8 @@ static int __cmd_top(void)
* FIXME: perf_session__new should allow passing a O_MMAP, so that all this
* mmap reading, etc is encapsulated in it. Use O_WRONLY for now.
*/
- struct perf_session *session = perf_session__new(NULL, O_WRONLY, false);
-
+ struct perf_session *session = perf_session__new(NULL, O_WRONLY, false,
+ &symbol_conf);
if (session == NULL)
return -ENOMEM;

diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index d765323..9d89ae4 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -318,7 +318,7 @@ int cmd_trace(int argc, const char **argv, const char *prefix __used)

setup_pager();

- session = perf_session__new(input_name, O_RDONLY, 0);
+ session = perf_session__new(input_name, O_RDONLY, 0, NULL);
if (session == NULL)
return -ENOMEM;

diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index 2d09c29..222efb1 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -256,7 +256,8 @@ int event__process_task(event_t *self, struct perf_session *session)
return 0;
}

-void thread__find_addr_location(struct thread *self, u8 cpumode,
+void thread__find_addr_location(struct thread *self,
+ struct perf_session *session, u8 cpumode,
enum map_type type, u64 addr,
struct addr_location *al,
symbol_filter_t filter)
@@ -268,7 +269,7 @@ void thread__find_addr_location(struct thread *self, u8 cpumode,

if (cpumode & PERF_RECORD_MISC_KERNEL) {
al->level = 'k';
- mg = kmaps;
+ mg = &session->kmaps;
} else if (cpumode & PERF_RECORD_MISC_USER)
al->level = '.';
else {
@@ -289,14 +290,14 @@ 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 && mg != kmaps) {
- mg = kmaps;
+ if ((long long)al->addr < 0 && mg != &session->kmaps) {
+ mg = &session->kmaps;
goto try_again;
}
al->sym = NULL;
} else {
al->addr = al->map->map_ip(al->map, al->addr);
- al->sym = map__find_symbol(al->map, al->addr, filter);
+ al->sym = map__find_symbol(al->map, session, al->addr, filter);
}
}

@@ -311,7 +312,7 @@ int event__preprocess_sample(const event_t *self, struct perf_session *session,

dump_printf(" ... thread: %s:%d\n", thread->comm, thread->pid);

- thread__find_addr_location(thread, cpumode, MAP__FUNCTION,
+ thread__find_addr_location(thread, session, cpumode, MAP__FUNCTION,
self->ip.ip, al, filter);
dump_printf(" ...... dso: %s\n",
al->map ? al->map->dso->long_name :
diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h
index bb09025..035ecf3 100644
--- a/tools/perf/util/event.h
+++ b/tools/perf/util/event.h
@@ -149,15 +149,17 @@ void map__delete(struct map *self);
struct map *map__clone(struct map *self);
int map__overlap(struct map *l, struct map *r);
size_t map__fprintf(struct map *self, FILE *fp);
-struct symbol *map__find_symbol(struct map *self, u64 addr,
- symbol_filter_t filter);
+
+struct perf_session;
+
+struct symbol *map__find_symbol(struct map *self, struct perf_session *session,
+ u64 addr, symbol_filter_t filter);
struct symbol *map__find_symbol_by_name(struct map *self, const char *name,
+ struct perf_session *session,
symbol_filter_t filter);
void map__fixup_start(struct map *self);
void map__fixup_end(struct map *self);

-struct perf_session;
-
int event__synthesize_thread(pid_t pid,
int (*process)(event_t *event,
struct perf_session *session),
diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c
index 76bdca6..8b3dd46 100644
--- a/tools/perf/util/map.c
+++ b/tools/perf/util/map.c
@@ -104,10 +104,11 @@ void map__fixup_end(struct map *self)

#define DSO__DELETED "(deleted)"

-static int map__load(struct map *self, symbol_filter_t filter)
+static int map__load(struct map *self, struct perf_session *session,
+ symbol_filter_t filter)
{
const char *name = self->dso->long_name;
- int nr = dso__load(self->dso, self, filter);
+ int nr = dso__load(self->dso, self, session, filter);

if (nr < 0) {
if (self->dso->has_build_id) {
@@ -143,19 +144,20 @@ static int map__load(struct map *self, symbol_filter_t filter)
return 0;
}

-struct symbol *map__find_symbol(struct map *self, u64 addr,
- symbol_filter_t filter)
+struct symbol *map__find_symbol(struct map *self, struct perf_session *session,
+ u64 addr, symbol_filter_t filter)
{
- if (!dso__loaded(self->dso, self->type) && map__load(self, filter) < 0)
+ if (!dso__loaded(self->dso, self->type) && map__load(self, session, filter) < 0)
return NULL;

return dso__find_symbol(self->dso, self->type, addr);
}

struct symbol *map__find_symbol_by_name(struct map *self, const char *name,
+ struct perf_session *session,
symbol_filter_t filter)
{
- if (!dso__loaded(self->dso, self->type) && map__load(self, filter) < 0)
+ if (!dso__loaded(self->dso, self->type) && map__load(self, session, filter) < 0)
return NULL;

if (!dso__sorted_by_name(self->dso, self->type))
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 09836a5..fe87a2f 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -49,7 +49,7 @@ out_close:
}

struct perf_session *perf_session__new(const char *filename, int mode,
- bool force)
+ bool force, struct symbol_conf *conf)
{
size_t len = filename ? strlen(filename) + 1 : 0;
struct perf_session *self = zalloc(sizeof(*self) + len);
@@ -58,7 +58,7 @@ struct perf_session *perf_session__new(const char *filename, int mode,
goto out;

if (perf_header__init(&self->header) < 0)
- goto out_delete;
+ goto out_free;

memcpy(self->filename, filename, len);
self->threads = RB_ROOT;
@@ -66,16 +66,21 @@ struct perf_session *perf_session__new(const char *filename, int mode,
self->mmap_window = 32;
self->cwd = NULL;
self->cwdlen = 0;
+ map_groups__init(&self->kmaps);

- if (mode == O_RDONLY && perf_session__open(self, force) < 0) {
- perf_session__delete(self);
- self = NULL;
- }
+ if (perf_session__create_kernel_maps(self, conf) < 0)
+ goto out_delete;
+
+ if (mode == O_RDONLY && perf_session__open(self, force) < 0)
+ goto out_delete;
out:
return self;
-out_delete:
+out_free:
free(self);
return NULL;
+out_delete:
+ perf_session__delete(self);
+ return NULL;
}

void perf_session__delete(struct perf_session *self)
diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h
index 1dbef7c..20b2c9c 100644
--- a/tools/perf/util/session.h
+++ b/tools/perf/util/session.h
@@ -3,19 +3,23 @@

#include "event.h"
#include "header.h"
+#include "thread.h"
#include <linux/rbtree.h>

struct thread;
+struct symbol_conf;

struct perf_session {
struct perf_header header;
unsigned long size;
unsigned long mmap_window;
+ struct map_groups kmaps;
struct rb_root threads;
struct thread *last_match;
int fd;
int cwdlen;
char *cwd;
+ bool use_modules;
char filename[0];
};

@@ -37,7 +41,7 @@ struct perf_event_ops {
};

struct perf_session *perf_session__new(const char *filename, int mode,
- bool force);
+ bool force, struct symbol_conf *conf);
void perf_session__delete(struct perf_session *self);

int perf_session__process_events(struct perf_session *self,
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index d3d9fed..185b9ee 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -1,5 +1,6 @@
#include "util.h"
#include "../perf.h"
+#include "session.h"
#include "string.h"
#include "symbol.h"
#include "thread.h"
@@ -31,7 +32,7 @@ enum dso_origin {
static void dsos__add(struct list_head *head, struct dso *dso);
static struct map *map__new2(u64 start, struct dso *dso, enum map_type type);
static int dso__load_kernel_sym(struct dso *self, struct map *map,
- struct map_groups *mg, symbol_filter_t filter);
+ struct perf_session *session, symbol_filter_t filter);
unsigned int symbol__priv_size;
static int vmlinux_path__nr_entries;
static char **vmlinux_path;
@@ -41,9 +42,6 @@ static struct symbol_conf symbol_conf__defaults = {
.try_vmlinux_path = true,
};

-static struct map_groups kmaps_mem;
-struct map_groups *kmaps = &kmaps_mem;
-
bool dso__loaded(const struct dso *self, enum map_type type)
{
return self->loaded & (1 << type);
@@ -456,7 +454,7 @@ out_failure:
* the original ELF section names vmlinux have.
*/
static int dso__split_kallsyms(struct dso *self, struct map *map,
- struct map_groups *mg, symbol_filter_t filter)
+ struct perf_session *session, symbol_filter_t filter)
{
struct map *curr_map = map;
struct symbol *pos;
@@ -473,13 +471,13 @@ static int dso__split_kallsyms(struct dso *self, struct map *map,

module = strchr(pos->name, '\t');
if (module) {
- if (!mg->use_modules)
+ if (!session->use_modules)
goto discard_symbol;

*module++ = '\0';

if (strcmp(self->name, module)) {
- curr_map = map_groups__find_by_name(mg, map->type, module);
+ curr_map = map_groups__find_by_name(&session->kmaps, map->type, module);
if (curr_map == NULL) {
pr_debug("/proc/{kallsyms,modules} "
"inconsistency!\n");
@@ -510,7 +508,7 @@ static int dso__split_kallsyms(struct dso *self, struct map *map,
}

curr_map->map_ip = curr_map->unmap_ip = identity__map_ip;
- map_groups__insert(mg, curr_map);
+ map_groups__insert(&session->kmaps, curr_map);
++kernel_range;
}

@@ -531,7 +529,7 @@ discard_symbol: rb_erase(&pos->rb_node, root);


static int dso__load_kallsyms(struct dso *self, struct map *map,
- struct map_groups *mg, symbol_filter_t filter)
+ struct perf_session *session, symbol_filter_t filter)
{
if (dso__load_all_kallsyms(self, map) < 0)
return -1;
@@ -539,14 +537,7 @@ static int dso__load_kallsyms(struct dso *self, struct map *map,
symbols__fixup_end(&self->symbols[map->type]);
self->origin = DSO__ORIG_KERNEL;

- return dso__split_kallsyms(self, map, mg, filter);
-}
-
-size_t kernel_maps__fprintf(FILE *fp)
-{
- size_t printed = fprintf(fp, "Kernel maps:\n");
- printed += map_groups__fprintf_maps(kmaps, fp);
- return printed + fprintf(fp, "END kernel maps\n");
+ return dso__split_kallsyms(self, map, session, filter);
}

static int dso__load_perf_map(struct dso *self, struct map *map,
@@ -873,7 +864,7 @@ static bool elf_sec__is_a(GElf_Shdr *self, Elf_Data *secstrs, enum map_type type
}

static int dso__load_sym(struct dso *self, struct map *map,
- struct map_groups *mg, const char *name, int fd,
+ struct perf_session *session, const char *name, int fd,
symbol_filter_t filter, int kernel, int kmodule)
{
struct map *curr_map = map;
@@ -977,7 +968,7 @@ static int dso__load_sym(struct dso *self, struct map *map,
snprintf(dso_name, sizeof(dso_name),
"%s%s", self->short_name, section_name);

- curr_map = map_groups__find_by_name(mg, map->type, dso_name);
+ curr_map = map_groups__find_by_name(&session->kmaps, map->type, dso_name);
if (curr_map == NULL) {
u64 start = sym.st_value;

@@ -996,7 +987,7 @@ static int dso__load_sym(struct dso *self, struct map *map,
curr_map->map_ip = identity__map_ip;
curr_map->unmap_ip = identity__map_ip;
curr_dso->origin = DSO__ORIG_KERNEL;
- map_groups__insert(kmaps, curr_map);
+ map_groups__insert(&session->kmaps, curr_map);
dsos__add(&dsos__kernel, curr_dso);
} else
curr_dso = curr_map->dso;
@@ -1211,7 +1202,8 @@ char dso__symtab_origin(const struct dso *self)
return origin[self->origin];
}

-int dso__load(struct dso *self, struct map *map, symbol_filter_t filter)
+int dso__load(struct dso *self, struct map *map, struct perf_session *session,
+ symbol_filter_t filter)
{
int size = PATH_MAX;
char *name;
@@ -1222,7 +1214,7 @@ int dso__load(struct dso *self, struct map *map, symbol_filter_t filter)
dso__set_loaded(self, map->type);

if (self->kernel)
- return dso__load_kernel_sym(self, map, kmaps, filter);
+ return dso__load_kernel_sym(self, map, session, filter);

name = malloc(size);
if (!name)
@@ -1323,7 +1315,7 @@ struct map *map_groups__find_by_name(struct map_groups *self,
return NULL;
}

-static int dsos__set_modules_path_dir(char *dirname)
+static int perf_session__set_modules_path_dir(struct perf_session *self, char *dirname)
{
struct dirent *dent;
DIR *dir = opendir(dirname);
@@ -1343,7 +1335,7 @@ static int dsos__set_modules_path_dir(char *dirname)

snprintf(path, sizeof(path), "%s/%s",
dirname, dent->d_name);
- if (dsos__set_modules_path_dir(path) < 0)
+ if (perf_session__set_modules_path_dir(self, path) < 0)
goto failure;
} else {
char *dot = strrchr(dent->d_name, '.'),
@@ -1357,7 +1349,7 @@ static int dsos__set_modules_path_dir(char *dirname)
(int)(dot - dent->d_name), dent->d_name);

strxfrchar(dso_name, '-', '_');
- map = map_groups__find_by_name(kmaps, MAP__FUNCTION, dso_name);
+ map = map_groups__find_by_name(&self->kmaps, MAP__FUNCTION, dso_name);
if (map == NULL)
continue;

@@ -1377,7 +1369,7 @@ failure:
return -1;
}

-static int dsos__set_modules_path(void)
+static int perf_session__set_modules_path(struct perf_session *self)
{
struct utsname uts;
char modules_path[PATH_MAX];
@@ -1388,7 +1380,7 @@ static int dsos__set_modules_path(void)
snprintf(modules_path, sizeof(modules_path), "/lib/modules/%s/kernel",
uts.release);

- return dsos__set_modules_path_dir(modules_path);
+ return perf_session__set_modules_path_dir(self, modules_path);
}

/*
@@ -1410,7 +1402,7 @@ static struct map *map__new2(u64 start, struct dso *dso, enum map_type type)
return self;
}

-static int map_groups__create_module_maps(struct map_groups *self)
+static int perf_session__create_module_maps(struct perf_session *self)
{
char *line = NULL;
size_t n;
@@ -1467,14 +1459,14 @@ static int map_groups__create_module_maps(struct map_groups *self)
dso->has_build_id = true;

dso->origin = DSO__ORIG_KMODULE;
- map_groups__insert(self, map);
+ map_groups__insert(&self->kmaps, map);
dsos__add(&dsos__kernel, dso);
}

free(line);
fclose(file);

- return dsos__set_modules_path();
+ return perf_session__set_modules_path(self);

out_delete_line:
free(line);
@@ -1483,7 +1475,7 @@ out_failure:
}

static int dso__load_vmlinux(struct dso *self, struct map *map,
- struct map_groups *mg,
+ struct perf_session *session,
const char *vmlinux, symbol_filter_t filter)
{
int err = -1, fd;
@@ -1517,14 +1509,14 @@ static int dso__load_vmlinux(struct dso *self, struct map *map,
return -1;

dso__set_loaded(self, map->type);
- err = dso__load_sym(self, map, mg, self->long_name, fd, filter, 1, 0);
+ err = dso__load_sym(self, map, session, self->long_name, fd, filter, 1, 0);
close(fd);

return err;
}

static int dso__load_kernel_sym(struct dso *self, struct map *map,
- struct map_groups *mg, symbol_filter_t filter)
+ struct perf_session *session, symbol_filter_t filter)
{
int err;
bool is_kallsyms;
@@ -1534,7 +1526,7 @@ static int dso__load_kernel_sym(struct dso *self, struct map *map,
pr_debug("Looking at the vmlinux_path (%d entries long)\n",
vmlinux_path__nr_entries);
for (i = 0; i < vmlinux_path__nr_entries; ++i) {
- err = dso__load_vmlinux(self, map, mg,
+ err = dso__load_vmlinux(self, map, session,
vmlinux_path[i], filter);
if (err > 0) {
pr_debug("Using %s for symbols\n",
@@ -1550,12 +1542,12 @@ static int dso__load_kernel_sym(struct dso *self, struct map *map,
if (is_kallsyms)
goto do_kallsyms;

- err = dso__load_vmlinux(self, map, mg, self->long_name, filter);
+ err = dso__load_vmlinux(self, map, session, self->long_name, filter);
if (err <= 0) {
pr_info("The file %s cannot be used, "
"trying to use /proc/kallsyms...", self->long_name);
do_kallsyms:
- err = dso__load_kallsyms(self, map, mg, filter);
+ err = dso__load_kallsyms(self, map, session, filter);
if (err > 0 && !is_kallsyms)
dso__set_long_name(self, strdup("[kernel.kallsyms]"));
}
@@ -1757,23 +1749,30 @@ int symbol__init(struct symbol_conf *conf)
if (pconf->sort_by_name)
symbol__priv_size += (sizeof(struct symbol_name_rb_node) -
sizeof(struct symbol));
- map_groups__init(kmaps);

if (pconf->try_vmlinux_path && vmlinux_path__init() < 0)
return -1;

- if (map_groups__create_kernel_maps(kmaps, pconf->vmlinux_name) < 0) {
- vmlinux_path__exit();
+ return 0;
+}
+
+int perf_session__create_kernel_maps(struct perf_session *self,
+ struct symbol_conf *conf)
+{
+ const struct symbol_conf *pconf = conf ?: &symbol_conf__defaults;
+
+ if (map_groups__create_kernel_maps(&self->kmaps,
+ pconf->vmlinux_name) < 0)
return -1;
- }

- kmaps->use_modules = pconf->use_modules;
- if (pconf->use_modules && map_groups__create_module_maps(kmaps) < 0)
- pr_debug("Failed to load list of modules in use, "
- "continuing...\n");
+ self->use_modules = pconf->use_modules;
+
+ if (pconf->use_modules && perf_session__create_module_maps(self) < 0)
+ pr_debug("Failed to load list of modules for session %s, "
+ "continuing...\n", self->filename);
/*
* Now that we have all the maps created, just set the ->end of them:
*/
- map_groups__fixup_end(kmaps);
+ map_groups__fixup_end(&self->kmaps);
return 0;
}
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index cf99f88..941ef33 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -98,8 +98,11 @@ bool dso__sorted_by_name(const struct dso *self, enum map_type type);

void dso__sort_by_name(struct dso *self, enum map_type type);

+struct perf_session;
+
struct dso *dsos__findnew(const char *name);
-int dso__load(struct dso *self, struct map *map, symbol_filter_t filter);
+int dso__load(struct dso *self, struct map *map, struct perf_session *session,
+ symbol_filter_t filter);
void dsos__fprintf(FILE *fp);
size_t dsos__fprintf_buildid(FILE *fp);

@@ -116,12 +119,10 @@ int sysfs__read_build_id(const char *filename, void *bf, size_t size);
bool dsos__read_build_ids(void);
int build_id__sprintf(u8 *self, int len, char *bf);

-size_t kernel_maps__fprintf(FILE *fp);
-
int symbol__init(struct symbol_conf *conf);
+int perf_session__create_kernel_maps(struct perf_session *self,
+ struct symbol_conf *conf);

-struct map_groups;
-struct map_groups *kmaps;
extern struct list_head dsos__user, dsos__kernel;
extern struct dso *vdso;
#endif /* __PERF_SYMBOL */
diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c
index 634b7f7..4a08dcf 100644
--- a/tools/perf/util/thread.c
+++ b/tools/perf/util/thread.c
@@ -282,13 +282,14 @@ size_t perf_session__fprintf(struct perf_session *self, FILE *fp)
}

struct symbol *map_groups__find_symbol(struct map_groups *self,
+ struct perf_session *session,
enum map_type type, u64 addr,
symbol_filter_t filter)
{
struct map *map = map_groups__find(self, type, addr);

if (map != NULL)
- return map__find_symbol(map, map->map_ip(map, addr), filter);
+ return map__find_symbol(map, session, map->map_ip(map, addr), filter);

return NULL;
}
diff --git a/tools/perf/util/thread.h b/tools/perf/util/thread.h
index e93abf2..c206f72 100644
--- a/tools/perf/util/thread.h
+++ b/tools/perf/util/thread.h
@@ -8,7 +8,6 @@
struct map_groups {
struct rb_root maps[MAP__NR_TYPES];
struct list_head removed_maps[MAP__NR_TYPES];
- bool use_modules;
};

struct thread {
@@ -49,19 +48,21 @@ static inline struct map *thread__find_map(struct thread *self,
return self ? map_groups__find(&self->mg, type, addr) : NULL;
}

-void thread__find_addr_location(struct thread *self, u8 cpumode,
+void thread__find_addr_location(struct thread *self,
+ struct perf_session *session, u8 cpumode,
enum map_type type, u64 addr,
struct addr_location *al,
symbol_filter_t filter);
struct symbol *map_groups__find_symbol(struct map_groups *self,
+ struct perf_session *session,
enum map_type type, u64 addr,
symbol_filter_t filter);

static inline struct symbol *
-map_groups__find_function(struct map_groups *self, u64 addr,
- symbol_filter_t filter)
+map_groups__find_function(struct map_groups *self, struct perf_session *session,
+ u64 addr, symbol_filter_t filter)
{
- return map_groups__find_symbol(self, MAP__FUNCTION, addr, filter);
+ return map_groups__find_symbol(self, session, MAP__FUNCTION, addr, filter);
}

struct map *map_groups__find_by_name(struct map_groups *self,
--
1.6.2.5