]> git.openfabrics.org - ~shefty/rdma-dev.git/blobdiff - tools/perf/util/session.c
Merge branch 'perf/urgent' into perf/core
[~shefty/rdma-dev.git] / tools / perf / util / session.c
index 0f4555ce90635a767f4a609b917905b5f58bdd0a..d9318d8a9ba1aabd00520c29119e36e5fb5e677f 100644 (file)
@@ -10,6 +10,7 @@
 #include "evlist.h"
 #include "evsel.h"
 #include "session.h"
+#include "tool.h"
 #include "sort.h"
 #include "util.h"
 #include "cpumap.h"
@@ -78,39 +79,13 @@ out_close:
        return -1;
 }
 
-static void perf_session__id_header_size(struct perf_session *session)
-{
-       struct perf_sample *data;
-       u64 sample_type = session->sample_type;
-       u16 size = 0;
-
-       if (!session->sample_id_all)
-               goto out;
-
-       if (sample_type & PERF_SAMPLE_TID)
-               size += sizeof(data->tid) * 2;
-
-       if (sample_type & PERF_SAMPLE_TIME)
-               size += sizeof(data->time);
-
-       if (sample_type & PERF_SAMPLE_ID)
-               size += sizeof(data->id);
-
-       if (sample_type & PERF_SAMPLE_STREAM_ID)
-               size += sizeof(data->stream_id);
-
-       if (sample_type & PERF_SAMPLE_CPU)
-               size += sizeof(data->cpu) * 2;
-out:
-       session->id_hdr_size = size;
-}
-
 void perf_session__update_sample_type(struct perf_session *self)
 {
        self->sample_type = perf_evlist__sample_type(self->evlist);
        self->sample_size = __perf_evsel__sample_size(self->sample_type);
        self->sample_id_all = perf_evlist__sample_id_all(self->evlist);
-       perf_session__id_header_size(self);
+       self->id_hdr_size = perf_evlist__id_hdr_size(self->evlist);
+       self->host_machine.id_hdr_size = self->id_hdr_size;
 }
 
 int perf_session__create_kernel_maps(struct perf_session *self)
@@ -130,7 +105,7 @@ static void perf_session__destroy_kernel_maps(struct perf_session *self)
 
 struct perf_session *perf_session__new(const char *filename, int mode,
                                       bool force, bool repipe,
-                                      struct perf_event_ops *ops)
+                                      struct perf_tool *tool)
 {
        size_t len = filename ? strlen(filename) + 1 : 0;
        struct perf_session *self = zalloc(sizeof(*self) + len);
@@ -139,9 +114,6 @@ struct perf_session *perf_session__new(const char *filename, int mode,
                goto out;
 
        memcpy(self->filename, filename, len);
-       self->threads = RB_ROOT;
-       INIT_LIST_HEAD(&self->dead_threads);
-       self->last_match = NULL;
        /*
         * On 64bit we can mmap the data file in one go. No need for tiny mmap
         * slices. On 32bit we use 32MB.
@@ -171,10 +143,10 @@ struct perf_session *perf_session__new(const char *filename, int mode,
                        goto out_delete;
        }
 
-       if (ops && ops->ordering_requires_timestamps &&
-           ops->ordered_samples && !self->sample_id_all) {
+       if (tool && tool->ordering_requires_timestamps &&
+           tool->ordered_samples && !self->sample_id_all) {
                dump_printf("WARNING: No sample_id_all support, falling back to unordered processing\n");
-               ops->ordered_samples = false;
+               tool->ordered_samples = false;
        }
 
 out:
@@ -184,17 +156,22 @@ out_delete:
        return NULL;
 }
 
-static void perf_session__delete_dead_threads(struct perf_session *self)
+static void machine__delete_dead_threads(struct machine *machine)
 {
        struct thread *n, *t;
 
-       list_for_each_entry_safe(t, n, &self->dead_threads, node) {
+       list_for_each_entry_safe(t, n, &machine->dead_threads, node) {
                list_del(&t->node);
                thread__delete(t);
        }
 }
 
-static void perf_session__delete_threads(struct perf_session *self)
+static void perf_session__delete_dead_threads(struct perf_session *session)
+{
+       machine__delete_dead_threads(&session->host_machine);
+}
+
+static void machine__delete_threads(struct machine *self)
 {
        struct rb_node *nd = rb_first(&self->threads);
 
@@ -207,6 +184,11 @@ static void perf_session__delete_threads(struct perf_session *self)
        }
 }
 
+static void perf_session__delete_threads(struct perf_session *session)
+{
+       machine__delete_threads(&session->host_machine);
+}
+
 void perf_session__delete(struct perf_session *self)
 {
        perf_session__destroy_kernel_maps(self);
@@ -217,7 +199,7 @@ void perf_session__delete(struct perf_session *self)
        free(self);
 }
 
-void perf_session__remove_thread(struct perf_session *self, struct thread *th)
+void machine__remove_thread(struct machine *self, struct thread *th)
 {
        self->last_match = NULL;
        rb_erase(&th->rb_node, &self->threads);
@@ -236,16 +218,16 @@ static bool symbol__match_parent_regex(struct symbol *sym)
        return 0;
 }
 
-int perf_session__resolve_callchain(struct perf_session *self,
-                                   struct thread *thread,
-                                   struct ip_callchain *chain,
-                                   struct symbol **parent)
+int machine__resolve_callchain(struct machine *self, struct perf_evsel *evsel,
+                              struct thread *thread,
+                              struct ip_callchain *chain,
+                              struct symbol **parent)
 {
        u8 cpumode = PERF_RECORD_MISC_USER;
        unsigned int i;
        int err;
 
-       callchain_cursor_reset(&self->callchain_cursor);
+       callchain_cursor_reset(&evsel->hists.callchain_cursor);
 
        for (i = 0; i < chain->nr; i++) {
                u64 ip;
@@ -272,7 +254,7 @@ int perf_session__resolve_callchain(struct perf_session *self,
 
                al.filtered = false;
                thread__find_addr_location(thread, self, cpumode,
-                               MAP__FUNCTION, thread->pid, ip, &al, NULL);
+                                          MAP__FUNCTION, ip, &al, NULL);
                if (al.sym != NULL) {
                        if (sort__has_parent && !*parent &&
                            symbol__match_parent_regex(al.sym))
@@ -281,7 +263,7 @@ int perf_session__resolve_callchain(struct perf_session *self,
                                break;
                }
 
-               err = callchain_cursor_append(&self->callchain_cursor,
+               err = callchain_cursor_append(&evsel->hists.callchain_cursor,
                                              ip, al.map, al.sym);
                if (err)
                        return err;
@@ -290,75 +272,91 @@ int perf_session__resolve_callchain(struct perf_session *self,
        return 0;
 }
 
-static int process_event_synth_stub(union perf_event *event __used,
-                                   struct perf_session *session __used)
+static int process_event_synth_tracing_data_stub(union perf_event *event __used,
+                                                struct perf_session *session __used)
+{
+       dump_printf(": unhandled!\n");
+       return 0;
+}
+
+static int process_event_synth_attr_stub(union perf_event *event __used,
+                                        struct perf_evlist **pevlist __used)
 {
        dump_printf(": unhandled!\n");
        return 0;
 }
 
-static int process_event_sample_stub(union perf_event *event __used,
+static int process_event_sample_stub(struct perf_tool *tool __used,
+                                    union perf_event *event __used,
                                     struct perf_sample *sample __used,
                                     struct perf_evsel *evsel __used,
-                                    struct perf_session *session __used)
+                                    struct machine *machine __used)
 {
        dump_printf(": unhandled!\n");
        return 0;
 }
 
-static int process_event_stub(union perf_event *event __used,
+static int process_event_stub(struct perf_tool *tool __used,
+                             union perf_event *event __used,
                              struct perf_sample *sample __used,
-                             struct perf_session *session __used)
+                             struct machine *machine __used)
+{
+       dump_printf(": unhandled!\n");
+       return 0;
+}
+
+static int process_finished_round_stub(struct perf_tool *tool __used,
+                                      union perf_event *event __used,
+                                      struct perf_session *perf_session __used)
 {
        dump_printf(": unhandled!\n");
        return 0;
 }
 
-static int process_finished_round_stub(union perf_event *event __used,
-                                      struct perf_session *session __used,
-                                      struct perf_event_ops *ops __used)
+static int process_event_type_stub(struct perf_tool *tool __used,
+                                  union perf_event *event __used)
 {
        dump_printf(": unhandled!\n");
        return 0;
 }
 
-static int process_finished_round(union perf_event *event,
-                                 struct perf_session *session,
-                                 struct perf_event_ops *ops);
+static int process_finished_round(struct perf_tool *tool,
+                                 union perf_event *event,
+                                 struct perf_session *session);
 
-static void perf_event_ops__fill_defaults(struct perf_event_ops *handler)
+static void perf_tool__fill_defaults(struct perf_tool *tool)
 {
-       if (handler->sample == NULL)
-               handler->sample = process_event_sample_stub;
-       if (handler->mmap == NULL)
-               handler->mmap = process_event_stub;
-       if (handler->comm == NULL)
-               handler->comm = process_event_stub;
-       if (handler->fork == NULL)
-               handler->fork = process_event_stub;
-       if (handler->exit == NULL)
-               handler->exit = process_event_stub;
-       if (handler->lost == NULL)
-               handler->lost = perf_event__process_lost;
-       if (handler->read == NULL)
-               handler->read = process_event_stub;
-       if (handler->throttle == NULL)
-               handler->throttle = process_event_stub;
-       if (handler->unthrottle == NULL)
-               handler->unthrottle = process_event_stub;
-       if (handler->attr == NULL)
-               handler->attr = process_event_synth_stub;
-       if (handler->event_type == NULL)
-               handler->event_type = process_event_synth_stub;
-       if (handler->tracing_data == NULL)
-               handler->tracing_data = process_event_synth_stub;
-       if (handler->build_id == NULL)
-               handler->build_id = process_event_synth_stub;
-       if (handler->finished_round == NULL) {
-               if (handler->ordered_samples)
-                       handler->finished_round = process_finished_round;
+       if (tool->sample == NULL)
+               tool->sample = process_event_sample_stub;
+       if (tool->mmap == NULL)
+               tool->mmap = process_event_stub;
+       if (tool->comm == NULL)
+               tool->comm = process_event_stub;
+       if (tool->fork == NULL)
+               tool->fork = process_event_stub;
+       if (tool->exit == NULL)
+               tool->exit = process_event_stub;
+       if (tool->lost == NULL)
+               tool->lost = perf_event__process_lost;
+       if (tool->read == NULL)
+               tool->read = process_event_sample_stub;
+       if (tool->throttle == NULL)
+               tool->throttle = process_event_stub;
+       if (tool->unthrottle == NULL)
+               tool->unthrottle = process_event_stub;
+       if (tool->attr == NULL)
+               tool->attr = process_event_synth_attr_stub;
+       if (tool->event_type == NULL)
+               tool->event_type = process_event_type_stub;
+       if (tool->tracing_data == NULL)
+               tool->tracing_data = process_event_synth_tracing_data_stub;
+       if (tool->build_id == NULL)
+               tool->build_id = process_finished_round_stub;
+       if (tool->finished_round == NULL) {
+               if (tool->ordered_samples)
+                       tool->finished_round = process_finished_round;
                else
-                       handler->finished_round = process_finished_round_stub;
+                       tool->finished_round = process_finished_round_stub;
        }
 }
 
@@ -490,11 +488,11 @@ static void perf_session_free_sample_buffers(struct perf_session *session)
 static int perf_session_deliver_event(struct perf_session *session,
                                      union perf_event *event,
                                      struct perf_sample *sample,
-                                     struct perf_event_ops *ops,
+                                     struct perf_tool *tool,
                                      u64 file_offset);
 
 static void flush_sample_queue(struct perf_session *s,
-                              struct perf_event_ops *ops)
+                              struct perf_tool *tool)
 {
        struct ordered_samples *os = &s->ordered_samples;
        struct list_head *head = &os->samples;
@@ -505,7 +503,7 @@ static void flush_sample_queue(struct perf_session *s,
        unsigned idx = 0, progress_next = os->nr_samples / 16;
        int ret;
 
-       if (!ops->ordered_samples || !limit)
+       if (!tool->ordered_samples || !limit)
                return;
 
        list_for_each_entry_safe(iter, tmp, head, list) {
@@ -516,7 +514,7 @@ static void flush_sample_queue(struct perf_session *s,
                if (ret)
                        pr_err("Can't parse sample, err = %d\n", ret);
                else
-                       perf_session_deliver_event(s, iter->event, &sample, ops,
+                       perf_session_deliver_event(s, iter->event, &sample, tool,
                                                   iter->file_offset);
 
                os->last_flush = iter->timestamp;
@@ -578,11 +576,11 @@ static void flush_sample_queue(struct perf_session *s,
  *      Flush every events below timestamp 7
  *      etc...
  */
-static int process_finished_round(union perf_event *event __used,
-                                 struct perf_session *session,
-                                 struct perf_event_ops *ops)
+static int process_finished_round(struct perf_tool *tool,
+                                 union perf_event *event __used,
+                                 struct perf_session *session)
 {
-       flush_sample_queue(session, ops);
+       flush_sample_queue(session, tool);
        session->ordered_samples.next_flush = session->ordered_samples.max_timestamp;
 
        return 0;
@@ -737,13 +735,26 @@ static void dump_sample(struct perf_session *session, union perf_event *event,
                callchain__printf(sample);
 }
 
+static struct machine *
+       perf_session__find_machine_for_cpumode(struct perf_session *session,
+                                              union perf_event *event)
+{
+       const u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
+
+       if (cpumode == PERF_RECORD_MISC_GUEST_KERNEL && perf_guest)
+               return perf_session__find_machine(session, event->ip.pid);
+
+       return perf_session__find_host_machine(session);
+}
+
 static int perf_session_deliver_event(struct perf_session *session,
                                      union perf_event *event,
                                      struct perf_sample *sample,
-                                     struct perf_event_ops *ops,
+                                     struct perf_tool *tool,
                                      u64 file_offset)
 {
        struct perf_evsel *evsel;
+       struct machine *machine;
 
        dump_event(session, event, file_offset, sample);
 
@@ -765,6 +776,8 @@ static int perf_session_deliver_event(struct perf_session *session,
                hists__inc_nr_events(&evsel->hists, event->header.type);
        }
 
+       machine = perf_session__find_machine_for_cpumode(session, event);
+
        switch (event->header.type) {
        case PERF_RECORD_SAMPLE:
                dump_sample(session, event, sample);
@@ -772,23 +785,25 @@ static int perf_session_deliver_event(struct perf_session *session,
                        ++session->hists.stats.nr_unknown_id;
                        return -1;
                }
-               return ops->sample(event, sample, evsel, session);
+               return tool->sample(tool, event, sample, evsel, machine);
        case PERF_RECORD_MMAP:
-               return ops->mmap(event, sample, session);
+               return tool->mmap(tool, event, sample, machine);
        case PERF_RECORD_COMM:
-               return ops->comm(event, sample, session);
+               return tool->comm(tool, event, sample, machine);
        case PERF_RECORD_FORK:
-               return ops->fork(event, sample, session);
+               return tool->fork(tool, event, sample, machine);
        case PERF_RECORD_EXIT:
-               return ops->exit(event, sample, session);
+               return tool->exit(tool, event, sample, machine);
        case PERF_RECORD_LOST:
-               return ops->lost(event, sample, session);
+               if (tool->lost == perf_event__process_lost)
+                       session->hists.stats.total_lost += event->lost.lost;
+               return tool->lost(tool, event, sample, machine);
        case PERF_RECORD_READ:
-               return ops->read(event, sample, session);
+               return tool->read(tool, event, sample, evsel, machine);
        case PERF_RECORD_THROTTLE:
-               return ops->throttle(event, sample, session);
+               return tool->throttle(tool, event, sample, machine);
        case PERF_RECORD_UNTHROTTLE:
-               return ops->unthrottle(event, sample, session);
+               return tool->unthrottle(tool, event, sample, machine);
        default:
                ++session->hists.stats.nr_unknown_events;
                return -1;
@@ -812,24 +827,29 @@ static int perf_session__preprocess_sample(struct perf_session *session,
 }
 
 static int perf_session__process_user_event(struct perf_session *session, union perf_event *event,
-                                           struct perf_event_ops *ops, u64 file_offset)
+                                           struct perf_tool *tool, u64 file_offset)
 {
+       int err;
+
        dump_event(session, event, file_offset, NULL);
 
        /* These events are processed right away */
        switch (event->header.type) {
        case PERF_RECORD_HEADER_ATTR:
-               return ops->attr(event, session);
+               err = tool->attr(event, &session->evlist);
+               if (err == 0)
+                       perf_session__update_sample_type(session);
+               return err;
        case PERF_RECORD_HEADER_EVENT_TYPE:
-               return ops->event_type(event, session);
+               return tool->event_type(tool, event);
        case PERF_RECORD_HEADER_TRACING_DATA:
                /* setup for reading amidst mmap */
                lseek(session->fd, file_offset, SEEK_SET);
-               return ops->tracing_data(event, session);
+               return tool->tracing_data(event, session);
        case PERF_RECORD_HEADER_BUILD_ID:
-               return ops->build_id(event, session);
+               return tool->build_id(tool, event, session);
        case PERF_RECORD_FINISHED_ROUND:
-               return ops->finished_round(event, session, ops);
+               return tool->finished_round(tool, event, session);
        default:
                return -EINVAL;
        }
@@ -837,7 +857,7 @@ static int perf_session__process_user_event(struct perf_session *session, union
 
 static int perf_session__process_event(struct perf_session *session,
                                       union perf_event *event,
-                                      struct perf_event_ops *ops,
+                                      struct perf_tool *tool,
                                       u64 file_offset)
 {
        struct perf_sample sample;
@@ -853,7 +873,7 @@ static int perf_session__process_event(struct perf_session *session,
        hists__inc_nr_events(&session->hists, event->header.type);
 
        if (event->header.type >= PERF_RECORD_USER_TYPE_START)
-               return perf_session__process_user_event(session, event, ops, file_offset);
+               return perf_session__process_user_event(session, event, tool, file_offset);
 
        /*
         * For all kernel events we get the sample data
@@ -866,14 +886,14 @@ static int perf_session__process_event(struct perf_session *session,
        if (perf_session__preprocess_sample(session, event, &sample))
                return 0;
 
-       if (ops->ordered_samples) {
+       if (tool->ordered_samples) {
                ret = perf_session_queue_event(session, event, &sample,
                                               file_offset);
                if (ret != -ETIME)
                        return ret;
        }
 
-       return perf_session_deliver_event(session, event, &sample, ops,
+       return perf_session_deliver_event(session, event, &sample, tool,
                                          file_offset);
 }
 
@@ -884,6 +904,11 @@ void perf_event_header__bswap(struct perf_event_header *self)
        self->size = bswap_16(self->size);
 }
 
+struct thread *perf_session__findnew(struct perf_session *session, pid_t pid)
+{
+       return machine__findnew_thread(&session->host_machine, pid);
+}
+
 static struct thread *perf_session__register_idle_thread(struct perf_session *self)
 {
        struct thread *thread = perf_session__findnew(self, 0);
@@ -897,9 +922,9 @@ static struct thread *perf_session__register_idle_thread(struct perf_session *se
 }
 
 static void perf_session__warn_about_errors(const struct perf_session *session,
-                                           const struct perf_event_ops *ops)
+                                           const struct perf_tool *tool)
 {
-       if (ops->lost == perf_event__process_lost &&
+       if (tool->lost == perf_event__process_lost &&
            session->hists.stats.nr_events[PERF_RECORD_LOST] != 0) {
                ui__warning("Processed %d events and lost %d chunks!\n\n"
                            "Check IO/CPU overload!\n\n",
@@ -934,7 +959,7 @@ static void perf_session__warn_about_errors(const struct perf_session *session,
 volatile int session_done;
 
 static int __perf_session__process_pipe_events(struct perf_session *self,
-                                              struct perf_event_ops *ops)
+                                              struct perf_tool *tool)
 {
        union perf_event event;
        uint32_t size;
@@ -943,7 +968,7 @@ static int __perf_session__process_pipe_events(struct perf_session *self,
        int err;
        void *p;
 
-       perf_event_ops__fill_defaults(ops);
+       perf_tool__fill_defaults(tool);
 
        head = 0;
 more:
@@ -980,7 +1005,7 @@ more:
        }
 
        if (size == 0 ||
-           (skip = perf_session__process_event(self, &event, ops, head)) < 0) {
+           (skip = perf_session__process_event(self, &event, tool, head)) < 0) {
                dump_printf("%#" PRIx64 " [%#x]: skipping unknown header type: %d\n",
                            head, event.header.size, event.header.type);
                /*
@@ -1003,7 +1028,7 @@ more:
 done:
        err = 0;
 out_err:
-       perf_session__warn_about_errors(self, ops);
+       perf_session__warn_about_errors(self, tool);
        perf_session_free_sample_buffers(self);
        return err;
 }
@@ -1034,7 +1059,7 @@ fetch_mmaped_event(struct perf_session *session,
 
 int __perf_session__process_events(struct perf_session *session,
                                   u64 data_offset, u64 data_size,
-                                  u64 file_size, struct perf_event_ops *ops)
+                                  u64 file_size, struct perf_tool *tool)
 {
        u64 head, page_offset, file_offset, file_pos, progress_next;
        int err, mmap_prot, mmap_flags, map_idx = 0;
@@ -1043,7 +1068,7 @@ int __perf_session__process_events(struct perf_session *session,
        union perf_event *event;
        uint32_t size;
 
-       perf_event_ops__fill_defaults(ops);
+       perf_tool__fill_defaults(tool);
 
        page_size = sysconf(_SC_PAGESIZE);
 
@@ -1098,7 +1123,7 @@ more:
        size = event->header.size;
 
        if (size == 0 ||
-           perf_session__process_event(session, event, ops, file_pos) < 0) {
+           perf_session__process_event(session, event, tool, file_pos) < 0) {
                dump_printf("%#" PRIx64 " [%#x]: skipping unknown header type: %d\n",
                            file_offset + head, event->header.size,
                            event->header.type);
@@ -1127,15 +1152,15 @@ more:
        err = 0;
        /* do the final flush for ordered samples */
        session->ordered_samples.next_flush = ULLONG_MAX;
-       flush_sample_queue(session, ops);
+       flush_sample_queue(session, tool);
 out_err:
-       perf_session__warn_about_errors(session, ops);
+       perf_session__warn_about_errors(session, tool);
        perf_session_free_sample_buffers(session);
        return err;
 }
 
 int perf_session__process_events(struct perf_session *self,
-                                struct perf_event_ops *ops)
+                                struct perf_tool *tool)
 {
        int err;
 
@@ -1146,9 +1171,9 @@ int perf_session__process_events(struct perf_session *self,
                err = __perf_session__process_events(self,
                                                     self->header.data_offset,
                                                     self->header.data_size,
-                                                    self->size, ops);
+                                                    self->size, tool);
        else
-               err = __perf_session__process_pipe_events(self, ops);
+               err = __perf_session__process_pipe_events(self, tool);
 
        return err;
 }
@@ -1163,9 +1188,8 @@ bool perf_session__has_traces(struct perf_session *self, const char *msg)
        return true;
 }
 
-int perf_session__set_kallsyms_ref_reloc_sym(struct map **maps,
-                                            const char *symbol_name,
-                                            u64 addr)
+int maps__set_kallsyms_ref_reloc_sym(struct map **maps,
+                                    const char *symbol_name, u64 addr)
 {
        char *bracket;
        enum map_type i;
@@ -1224,6 +1248,27 @@ size_t perf_session__fprintf_nr_events(struct perf_session *session, FILE *fp)
        return ret;
 }
 
+size_t perf_session__fprintf(struct perf_session *session, FILE *fp)
+{
+       /*
+        * FIXME: Here we have to actually print all the machines in this
+        * session, not just the host...
+        */
+       return machine__fprintf(&session->host_machine, fp);
+}
+
+void perf_session__remove_thread(struct perf_session *session,
+                                struct thread *th)
+{
+       /*
+        * FIXME: This one makes no sense, we need to remove the thread from
+        * the machine it belongs to, perf_session can have many machines, so
+        * doing it always on ->host_machine is wrong.  Fix when auditing all
+        * the 'perf kvm' code.
+        */
+       machine__remove_thread(&session->host_machine, th);
+}
+
 struct perf_evsel *perf_session__find_first_evtype(struct perf_session *session,
                                              unsigned int type)
 {
@@ -1236,17 +1281,16 @@ struct perf_evsel *perf_session__find_first_evtype(struct perf_session *session,
        return NULL;
 }
 
-void perf_session__print_ip(union perf_event *event,
-                           struct perf_sample *sample,
-                           struct perf_session *session,
-                           int print_sym, int print_dso)
+void perf_event__print_ip(union perf_event *event, struct perf_sample *sample,
+                         struct machine *machine, struct perf_evsel *evsel,
+                         int print_sym, int print_dso)
 {
        struct addr_location al;
        const char *symname, *dsoname;
-       struct callchain_cursor *cursor = &session->callchain_cursor;
+       struct callchain_cursor *cursor = &evsel->hists.callchain_cursor;
        struct callchain_cursor_node *node;
 
-       if (perf_event__preprocess_sample(event, session, &al, sample,
+       if (perf_event__preprocess_sample(event, machine, &al, sample,
                                          NULL) < 0) {
                error("problem processing %d event, skipping it.\n",
                        event->header.type);
@@ -1255,7 +1299,7 @@ void perf_session__print_ip(union perf_event *event,
 
        if (symbol_conf.use_callchain && sample->callchain) {
 
-               if (perf_session__resolve_callchain(session, al.thread,
+               if (machine__resolve_callchain(machine, evsel, al.thread,
                                                sample->callchain, NULL) != 0) {
                        if (verbose)
                                error("Failed to resolve callchain. Skipping\n");