提交 aaa9fa38 编写于 作者: I Ingo Molnar

Merge tag 'perf-core-for-mingo' of...

Merge tag 'perf-core-for-mingo' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core

Pull perf/core improvements and fixes from Arnaldo Carvalho de Melo:

User visible changes:

 - Fix 'perf script' pipe mode segfault, by always initializing ordered_events in
   perf_session__new(). (Arnaldo Carvalho de Melo)

 - Fix ppid for synthesized fork events. (David Ahern)

 - Fix kernel symbol resolution of callchains in S/390 by remembering the
   cpumode. (David Hildenbrand)

Infrastructure changes:

 - Disable libbabeltrace check by default in the build system. (Jiri Olsa)
Signed-off-by: NArnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: NIngo Molnar <mingo@kernel.org>
...@@ -69,7 +69,7 @@ include config/utilities.mak ...@@ -69,7 +69,7 @@ include config/utilities.mak
# #
# Define NO_ZLIB if you do not want to support compressed kernel modules # Define NO_ZLIB if you do not want to support compressed kernel modules
# #
# Define NO_LIBBABELTRACE if you do not want libbabeltrace support # Define LIBBABELTRACE if you DO want libbabeltrace support
# for CTF data format. # for CTF data format.
# #
# Define NO_LZMA if you do not want to support compressed (xz) kernel modules # Define NO_LZMA if you do not want to support compressed (xz) kernel modules
......
...@@ -95,7 +95,7 @@ ifndef NO_LIBELF ...@@ -95,7 +95,7 @@ ifndef NO_LIBELF
FEATURE_CHECK_LDFLAGS-libdw-dwarf-unwind := $(LIBDW_LDFLAGS) -ldw FEATURE_CHECK_LDFLAGS-libdw-dwarf-unwind := $(LIBDW_LDFLAGS) -ldw
endif endif
ifndef NO_LIBBABELTRACE ifdef LIBBABELTRACE
# for linking with debug library, run like: # for linking with debug library, run like:
# make DEBUG=1 LIBBABELTRACE_DIR=/opt/libbabeltrace/ # make DEBUG=1 LIBBABELTRACE_DIR=/opt/libbabeltrace/
ifdef LIBBABELTRACE_DIR ifdef LIBBABELTRACE_DIR
...@@ -598,7 +598,7 @@ else ...@@ -598,7 +598,7 @@ else
NO_PERF_READ_VDSOX32 := 1 NO_PERF_READ_VDSOX32 := 1
endif endif
ifndef NO_LIBBABELTRACE ifdef LIBBABELTRACE
$(call feature_check,libbabeltrace) $(call feature_check,libbabeltrace)
ifeq ($(feature-libbabeltrace), 1) ifeq ($(feature-libbabeltrace), 1)
CFLAGS += -DHAVE_LIBBABELTRACE_SUPPORT $(LIBBABELTRACE_CFLAGS) CFLAGS += -DHAVE_LIBBABELTRACE_SUPPORT $(LIBBABELTRACE_CFLAGS)
...@@ -607,7 +607,6 @@ ifndef NO_LIBBABELTRACE ...@@ -607,7 +607,6 @@ ifndef NO_LIBBABELTRACE
$(call detected,CONFIG_LIBBABELTRACE) $(call detected,CONFIG_LIBBABELTRACE)
else else
msg := $(warning No libbabeltrace found, disables 'perf data' CTF format support, please install libbabeltrace-dev[el]/libbabeltrace-ctf-dev); msg := $(warning No libbabeltrace found, disables 'perf data' CTF format support, please install libbabeltrace-dev[el]/libbabeltrace-ctf-dev);
NO_LIBBABELTRACE := 1
endif endif
endif endif
......
...@@ -49,70 +49,103 @@ static struct perf_sample synth_sample = { ...@@ -49,70 +49,103 @@ static struct perf_sample synth_sample = {
.period = 1, .period = 1,
}; };
static pid_t perf_event__get_comm_tgid(pid_t pid, char *comm, size_t len) /*
* Assumes that the first 4095 bytes of /proc/pid/stat contains
* the comm, tgid and ppid.
*/
static int perf_event__get_comm_ids(pid_t pid, char *comm, size_t len,
pid_t *tgid, pid_t *ppid)
{ {
char filename[PATH_MAX]; char filename[PATH_MAX];
char bf[BUFSIZ]; char bf[4096];
FILE *fp; int fd;
size_t size = 0; size_t size = 0, n;
pid_t tgid = -1; char *nl, *name, *tgids, *ppids;
*tgid = -1;
*ppid = -1;
snprintf(filename, sizeof(filename), "/proc/%d/status", pid); snprintf(filename, sizeof(filename), "/proc/%d/status", pid);
fp = fopen(filename, "r"); fd = open(filename, O_RDONLY);
if (fp == NULL) { if (fd < 0) {
pr_debug("couldn't open %s\n", filename); pr_debug("couldn't open %s\n", filename);
return 0; return -1;
} }
while (!comm[0] || (tgid < 0)) { n = read(fd, bf, sizeof(bf) - 1);
if (fgets(bf, sizeof(bf), fp) == NULL) { close(fd);
pr_warning("couldn't get COMM and pgid, malformed %s\n", if (n <= 0) {
filename); pr_warning("Couldn't get COMM, tigd and ppid for pid %d\n",
break; pid);
} return -1;
}
bf[n] = '\0';
if (memcmp(bf, "Name:", 5) == 0) { name = strstr(bf, "Name:");
char *name = bf + 5; tgids = strstr(bf, "Tgid:");
while (*name && isspace(*name)) ppids = strstr(bf, "PPid:");
++name;
size = strlen(name) - 1; if (name) {
if (size >= len) name += 5; /* strlen("Name:") */
size = len - 1;
memcpy(comm, name, size); while (*name && isspace(*name))
comm[size] = '\0'; ++name;
} else if (memcmp(bf, "Tgid:", 5) == 0) { nl = strchr(name, '\n');
char *tgids = bf + 5; if (nl)
while (*tgids && isspace(*tgids)) *nl = '\0';
++tgids;
tgid = atoi(tgids); size = strlen(name);
} if (size >= len)
size = len - 1;
memcpy(comm, name, size);
comm[size] = '\0';
} else {
pr_debug("Name: string not found for pid %d\n", pid);
} }
fclose(fp); if (tgids) {
tgids += 5; /* strlen("Tgid:") */
*tgid = atoi(tgids);
} else {
pr_debug("Tgid: string not found for pid %d\n", pid);
}
return tgid; if (ppids) {
ppids += 5; /* strlen("PPid:") */
*ppid = atoi(ppids);
} else {
pr_debug("PPid: string not found for pid %d\n", pid);
}
return 0;
} }
static pid_t perf_event__prepare_comm(union perf_event *event, pid_t pid, static int perf_event__prepare_comm(union perf_event *event, pid_t pid,
struct machine *machine) struct machine *machine,
pid_t *tgid, pid_t *ppid)
{ {
size_t size; size_t size;
pid_t tgid;
*ppid = -1;
memset(&event->comm, 0, sizeof(event->comm)); memset(&event->comm, 0, sizeof(event->comm));
if (machine__is_host(machine)) if (machine__is_host(machine)) {
tgid = perf_event__get_comm_tgid(pid, event->comm.comm, if (perf_event__get_comm_ids(pid, event->comm.comm,
sizeof(event->comm.comm)); sizeof(event->comm.comm),
else tgid, ppid) != 0) {
tgid = machine->pid; return -1;
}
} else {
*tgid = machine->pid;
}
if (tgid < 0) if (*tgid < 0)
goto out; return -1;
event->comm.pid = tgid; event->comm.pid = *tgid;
event->comm.header.type = PERF_RECORD_COMM; event->comm.header.type = PERF_RECORD_COMM;
size = strlen(event->comm.comm) + 1; size = strlen(event->comm.comm) + 1;
...@@ -122,8 +155,8 @@ static pid_t perf_event__prepare_comm(union perf_event *event, pid_t pid, ...@@ -122,8 +155,8 @@ static pid_t perf_event__prepare_comm(union perf_event *event, pid_t pid,
(sizeof(event->comm.comm) - size) + (sizeof(event->comm.comm) - size) +
machine->id_hdr_size); machine->id_hdr_size);
event->comm.tid = pid; event->comm.tid = pid;
out:
return tgid; return 0;
} }
static pid_t perf_event__synthesize_comm(struct perf_tool *tool, static pid_t perf_event__synthesize_comm(struct perf_tool *tool,
...@@ -131,27 +164,27 @@ static pid_t perf_event__synthesize_comm(struct perf_tool *tool, ...@@ -131,27 +164,27 @@ static pid_t perf_event__synthesize_comm(struct perf_tool *tool,
perf_event__handler_t process, perf_event__handler_t process,
struct machine *machine) struct machine *machine)
{ {
pid_t tgid = perf_event__prepare_comm(event, pid, machine); pid_t tgid, ppid;
if (tgid == -1) if (perf_event__prepare_comm(event, pid, machine, &tgid, &ppid) != 0)
goto out; return -1;
if (process(tool, event, &synth_sample, machine) != 0) if (process(tool, event, &synth_sample, machine) != 0)
return -1; return -1;
out:
return tgid; return tgid;
} }
static int perf_event__synthesize_fork(struct perf_tool *tool, static int perf_event__synthesize_fork(struct perf_tool *tool,
union perf_event *event, pid_t pid, union perf_event *event,
pid_t tgid, perf_event__handler_t process, pid_t pid, pid_t tgid, pid_t ppid,
perf_event__handler_t process,
struct machine *machine) struct machine *machine)
{ {
memset(&event->fork, 0, sizeof(event->fork) + machine->id_hdr_size); memset(&event->fork, 0, sizeof(event->fork) + machine->id_hdr_size);
event->fork.ppid = tgid; event->fork.ppid = ppid;
event->fork.ptid = tgid; event->fork.ptid = ppid;
event->fork.pid = tgid; event->fork.pid = tgid;
event->fork.tid = pid; event->fork.tid = pid;
event->fork.header.type = PERF_RECORD_FORK; event->fork.header.type = PERF_RECORD_FORK;
...@@ -343,7 +376,7 @@ static int __event__synthesize_thread(union perf_event *comm_event, ...@@ -343,7 +376,7 @@ static int __event__synthesize_thread(union perf_event *comm_event,
char filename[PATH_MAX]; char filename[PATH_MAX];
DIR *tasks; DIR *tasks;
struct dirent dirent, *next; struct dirent dirent, *next;
pid_t tgid; pid_t tgid, ppid;
/* special case: only send one comm event using passed in pid */ /* special case: only send one comm event using passed in pid */
if (!full) { if (!full) {
...@@ -378,12 +411,12 @@ static int __event__synthesize_thread(union perf_event *comm_event, ...@@ -378,12 +411,12 @@ static int __event__synthesize_thread(union perf_event *comm_event,
if (*end) if (*end)
continue; continue;
tgid = perf_event__prepare_comm(comm_event, _pid, machine); if (perf_event__prepare_comm(comm_event, _pid, machine,
if (tgid == -1) &tgid, &ppid) != 0)
return -1; return -1;
if (perf_event__synthesize_fork(tool, fork_event, _pid, tgid, if (perf_event__synthesize_fork(tool, fork_event, _pid, tgid,
process, machine) < 0) ppid, process, machine) < 0)
return -1; return -1;
/* /*
* Send the prepared comm event * Send the prepared comm event
......
...@@ -242,7 +242,6 @@ struct events_stats { ...@@ -242,7 +242,6 @@ struct events_stats {
u32 nr_invalid_chains; u32 nr_invalid_chains;
u32 nr_unknown_id; u32 nr_unknown_id;
u32 nr_unprocessable_samples; u32 nr_unprocessable_samples;
u32 nr_unordered_events;
}; };
struct attr_event { struct attr_event {
......
...@@ -1408,29 +1408,27 @@ struct mem_info *sample__resolve_mem(struct perf_sample *sample, ...@@ -1408,29 +1408,27 @@ struct mem_info *sample__resolve_mem(struct perf_sample *sample,
static int add_callchain_ip(struct thread *thread, static int add_callchain_ip(struct thread *thread,
struct symbol **parent, struct symbol **parent,
struct addr_location *root_al, struct addr_location *root_al,
bool branch_history, u8 *cpumode,
u64 ip) u64 ip)
{ {
struct addr_location al; struct addr_location al;
al.filtered = 0; al.filtered = 0;
al.sym = NULL; al.sym = NULL;
if (branch_history) if (!cpumode) {
thread__find_cpumode_addr_location(thread, MAP__FUNCTION, thread__find_cpumode_addr_location(thread, MAP__FUNCTION,
ip, &al); ip, &al);
else { } else {
u8 cpumode = PERF_RECORD_MISC_USER;
if (ip >= PERF_CONTEXT_MAX) { if (ip >= PERF_CONTEXT_MAX) {
switch (ip) { switch (ip) {
case PERF_CONTEXT_HV: case PERF_CONTEXT_HV:
cpumode = PERF_RECORD_MISC_HYPERVISOR; *cpumode = PERF_RECORD_MISC_HYPERVISOR;
break; break;
case PERF_CONTEXT_KERNEL: case PERF_CONTEXT_KERNEL:
cpumode = PERF_RECORD_MISC_KERNEL; *cpumode = PERF_RECORD_MISC_KERNEL;
break; break;
case PERF_CONTEXT_USER: case PERF_CONTEXT_USER:
cpumode = PERF_RECORD_MISC_USER; *cpumode = PERF_RECORD_MISC_USER;
break; break;
default: default:
pr_debug("invalid callchain context: " pr_debug("invalid callchain context: "
...@@ -1444,8 +1442,8 @@ static int add_callchain_ip(struct thread *thread, ...@@ -1444,8 +1442,8 @@ static int add_callchain_ip(struct thread *thread,
} }
return 0; return 0;
} }
thread__find_addr_location(thread, cpumode, MAP__FUNCTION, thread__find_addr_location(thread, *cpumode, MAP__FUNCTION,
ip, &al); ip, &al);
} }
if (al.sym != NULL) { if (al.sym != NULL) {
...@@ -1538,6 +1536,7 @@ static int resolve_lbr_callchain_sample(struct thread *thread, ...@@ -1538,6 +1536,7 @@ static int resolve_lbr_callchain_sample(struct thread *thread,
{ {
struct ip_callchain *chain = sample->callchain; struct ip_callchain *chain = sample->callchain;
int chain_nr = min(max_stack, (int)chain->nr); int chain_nr = min(max_stack, (int)chain->nr);
u8 cpumode = PERF_RECORD_MISC_USER;
int i, j, err; int i, j, err;
u64 ip; u64 ip;
...@@ -1584,7 +1583,7 @@ static int resolve_lbr_callchain_sample(struct thread *thread, ...@@ -1584,7 +1583,7 @@ static int resolve_lbr_callchain_sample(struct thread *thread,
ip = lbr_stack->entries[0].to; ip = lbr_stack->entries[0].to;
} }
err = add_callchain_ip(thread, parent, root_al, false, ip); err = add_callchain_ip(thread, parent, root_al, &cpumode, ip);
if (err) if (err)
return (err < 0) ? err : 0; return (err < 0) ? err : 0;
} }
...@@ -1604,6 +1603,7 @@ static int thread__resolve_callchain_sample(struct thread *thread, ...@@ -1604,6 +1603,7 @@ static int thread__resolve_callchain_sample(struct thread *thread,
struct branch_stack *branch = sample->branch_stack; struct branch_stack *branch = sample->branch_stack;
struct ip_callchain *chain = sample->callchain; struct ip_callchain *chain = sample->callchain;
int chain_nr = min(max_stack, (int)chain->nr); int chain_nr = min(max_stack, (int)chain->nr);
u8 cpumode = PERF_RECORD_MISC_USER;
int i, j, err; int i, j, err;
int skip_idx = -1; int skip_idx = -1;
int first_call = 0; int first_call = 0;
...@@ -1669,10 +1669,10 @@ static int thread__resolve_callchain_sample(struct thread *thread, ...@@ -1669,10 +1669,10 @@ static int thread__resolve_callchain_sample(struct thread *thread,
for (i = 0; i < nr; i++) { for (i = 0; i < nr; i++) {
err = add_callchain_ip(thread, parent, root_al, err = add_callchain_ip(thread, parent, root_al,
true, be[i].to); NULL, be[i].to);
if (!err) if (!err)
err = add_callchain_ip(thread, parent, root_al, err = add_callchain_ip(thread, parent, root_al,
true, be[i].from); NULL, be[i].from);
if (err == -EINVAL) if (err == -EINVAL)
break; break;
if (err) if (err)
...@@ -1701,7 +1701,7 @@ static int thread__resolve_callchain_sample(struct thread *thread, ...@@ -1701,7 +1701,7 @@ static int thread__resolve_callchain_sample(struct thread *thread,
#endif #endif
ip = chain->ips[j]; ip = chain->ips[j];
err = add_callchain_ip(thread, parent, root_al, false, ip); err = add_callchain_ip(thread, parent, root_al, &cpumode, ip);
if (err) if (err)
return (err < 0) ? err : 0; return (err < 0) ? err : 0;
......
...@@ -2,7 +2,6 @@ ...@@ -2,7 +2,6 @@
#include <linux/compiler.h> #include <linux/compiler.h>
#include <linux/string.h> #include <linux/string.h>
#include "ordered-events.h" #include "ordered-events.h"
#include "evlist.h"
#include "session.h" #include "session.h"
#include "asm/bug.h" #include "asm/bug.h"
#include "debug.h" #include "debug.h"
...@@ -167,7 +166,7 @@ int ordered_events__queue(struct ordered_events *oe, union perf_event *event, ...@@ -167,7 +166,7 @@ int ordered_events__queue(struct ordered_events *oe, union perf_event *event,
pr_oe_time(oe->last_flush, "last flush, last_flush_type %d\n", pr_oe_time(oe->last_flush, "last flush, last_flush_type %d\n",
oe->last_flush_type); oe->last_flush_type);
oe->evlist->stats.nr_unordered_events++; oe->nr_unordered_events++;
} }
oevent = ordered_events__new_event(oe, timestamp, event); oevent = ordered_events__new_event(oe, timestamp, event);
...@@ -187,7 +186,6 @@ static int __ordered_events__flush(struct ordered_events *oe) ...@@ -187,7 +186,6 @@ static int __ordered_events__flush(struct ordered_events *oe)
{ {
struct list_head *head = &oe->events; struct list_head *head = &oe->events;
struct ordered_event *tmp, *iter; struct ordered_event *tmp, *iter;
struct perf_sample sample;
u64 limit = oe->next_flush; u64 limit = oe->next_flush;
u64 last_ts = oe->last ? oe->last->timestamp : 0ULL; u64 last_ts = oe->last ? oe->last->timestamp : 0ULL;
bool show_progress = limit == ULLONG_MAX; bool show_progress = limit == ULLONG_MAX;
...@@ -206,15 +204,9 @@ static int __ordered_events__flush(struct ordered_events *oe) ...@@ -206,15 +204,9 @@ static int __ordered_events__flush(struct ordered_events *oe)
if (iter->timestamp > limit) if (iter->timestamp > limit)
break; break;
ret = oe->deliver(oe, iter);
ret = perf_evlist__parse_sample(oe->evlist, iter->event, &sample);
if (ret) if (ret)
pr_err("Can't parse sample, err = %d\n", ret); return ret;
else {
ret = oe->deliver(oe, iter, &sample);
if (ret)
return ret;
}
ordered_events__delete(oe, iter); ordered_events__delete(oe, iter);
oe->last_flush = iter->timestamp; oe->last_flush = iter->timestamp;
...@@ -292,18 +284,13 @@ int ordered_events__flush(struct ordered_events *oe, enum oe_flush how) ...@@ -292,18 +284,13 @@ int ordered_events__flush(struct ordered_events *oe, enum oe_flush how)
return err; return err;
} }
void ordered_events__init(struct ordered_events *oe, struct machines *machines, void ordered_events__init(struct ordered_events *oe, ordered_events__deliver_t deliver)
struct perf_evlist *evlist, struct perf_tool *tool,
ordered_events__deliver_t deliver)
{ {
INIT_LIST_HEAD(&oe->events); INIT_LIST_HEAD(&oe->events);
INIT_LIST_HEAD(&oe->cache); INIT_LIST_HEAD(&oe->cache);
INIT_LIST_HEAD(&oe->to_free); INIT_LIST_HEAD(&oe->to_free);
oe->max_alloc_size = (u64) -1; oe->max_alloc_size = (u64) -1;
oe->cur_alloc_size = 0; oe->cur_alloc_size = 0;
oe->evlist = evlist;
oe->machines = machines;
oe->tool = tool;
oe->deliver = deliver; oe->deliver = deliver;
} }
......
...@@ -3,10 +3,7 @@ ...@@ -3,10 +3,7 @@
#include <linux/types.h> #include <linux/types.h>
struct perf_tool;
struct perf_evlist;
struct perf_sample; struct perf_sample;
struct machines;
struct ordered_event { struct ordered_event {
u64 timestamp; u64 timestamp;
...@@ -25,8 +22,7 @@ enum oe_flush { ...@@ -25,8 +22,7 @@ enum oe_flush {
struct ordered_events; struct ordered_events;
typedef int (*ordered_events__deliver_t)(struct ordered_events *oe, typedef int (*ordered_events__deliver_t)(struct ordered_events *oe,
struct ordered_event *event, struct ordered_event *event);
struct perf_sample *sample);
struct ordered_events { struct ordered_events {
u64 last_flush; u64 last_flush;
...@@ -39,13 +35,11 @@ struct ordered_events { ...@@ -39,13 +35,11 @@ struct ordered_events {
struct list_head to_free; struct list_head to_free;
struct ordered_event *buffer; struct ordered_event *buffer;
struct ordered_event *last; struct ordered_event *last;
struct machines *machines;
struct perf_evlist *evlist;
struct perf_tool *tool;
ordered_events__deliver_t deliver; ordered_events__deliver_t deliver;
int buffer_idx; int buffer_idx;
unsigned int nr_events; unsigned int nr_events;
enum oe_flush last_flush_type; enum oe_flush last_flush_type;
u32 nr_unordered_events;
bool copy_on_queue; bool copy_on_queue;
}; };
...@@ -53,9 +47,7 @@ int ordered_events__queue(struct ordered_events *oe, union perf_event *event, ...@@ -53,9 +47,7 @@ int ordered_events__queue(struct ordered_events *oe, union perf_event *event,
struct perf_sample *sample, u64 file_offset); struct perf_sample *sample, u64 file_offset);
void ordered_events__delete(struct ordered_events *oe, struct ordered_event *event); void ordered_events__delete(struct ordered_events *oe, struct ordered_event *event);
int ordered_events__flush(struct ordered_events *oe, enum oe_flush how); int ordered_events__flush(struct ordered_events *oe, enum oe_flush how);
void ordered_events__init(struct ordered_events *oe, struct machines *machines, void ordered_events__init(struct ordered_events *oe, ordered_events__deliver_t deliver);
struct perf_evlist *evlsit, struct perf_tool *tool,
ordered_events__deliver_t deliver);
void ordered_events__free(struct ordered_events *oe); void ordered_events__free(struct ordered_events *oe);
static inline static inline
......
...@@ -93,11 +93,20 @@ static void perf_session__set_comm_exec(struct perf_session *session) ...@@ -93,11 +93,20 @@ static void perf_session__set_comm_exec(struct perf_session *session)
} }
static int ordered_events__deliver_event(struct ordered_events *oe, static int ordered_events__deliver_event(struct ordered_events *oe,
struct ordered_event *event, struct ordered_event *event)
struct perf_sample *sample)
{ {
return machines__deliver_event(oe->machines, oe->evlist, event->event, struct perf_sample sample;
sample, oe->tool, event->file_offset); struct perf_session *session = container_of(oe, struct perf_session,
ordered_events);
int ret = perf_evlist__parse_sample(session->evlist, event->event, &sample);
if (ret) {
pr_err("Can't parse sample, err = %d\n", ret);
return ret;
}
return machines__deliver_event(&session->machines, session->evlist, event->event,
&sample, session->tool, event->file_offset);
} }
struct perf_session *perf_session__new(struct perf_data_file *file, struct perf_session *perf_session__new(struct perf_data_file *file,
...@@ -109,7 +118,9 @@ struct perf_session *perf_session__new(struct perf_data_file *file, ...@@ -109,7 +118,9 @@ struct perf_session *perf_session__new(struct perf_data_file *file,
goto out; goto out;
session->repipe = repipe; session->repipe = repipe;
session->tool = tool;
machines__init(&session->machines); machines__init(&session->machines);
ordered_events__init(&session->ordered_events, ordered_events__deliver_event);
if (file) { if (file) {
if (perf_data_file__open(file)) if (perf_data_file__open(file))
...@@ -139,9 +150,6 @@ struct perf_session *perf_session__new(struct perf_data_file *file, ...@@ -139,9 +150,6 @@ struct perf_session *perf_session__new(struct perf_data_file *file,
tool->ordered_events && !perf_evlist__sample_id_all(session->evlist)) { tool->ordered_events && !perf_evlist__sample_id_all(session->evlist)) {
dump_printf("WARNING: No sample_id_all support, falling back to unordered processing\n"); dump_printf("WARNING: No sample_id_all support, falling back to unordered processing\n");
tool->ordered_events = false; tool->ordered_events = false;
} else {
ordered_events__init(&session->ordered_events, &session->machines,
session->evlist, tool, ordered_events__deliver_event);
} }
return session; return session;
...@@ -941,7 +949,7 @@ static s64 perf_session__process_user_event(struct perf_session *session, ...@@ -941,7 +949,7 @@ static s64 perf_session__process_user_event(struct perf_session *session,
u64 file_offset) u64 file_offset)
{ {
struct ordered_events *oe = &session->ordered_events; struct ordered_events *oe = &session->ordered_events;
struct perf_tool *tool = oe->tool; struct perf_tool *tool = session->tool;
int fd = perf_data_file__fd(session->file); int fd = perf_data_file__fd(session->file);
int err; int err;
...@@ -982,7 +990,7 @@ int perf_session__deliver_synth_event(struct perf_session *session, ...@@ -982,7 +990,7 @@ int perf_session__deliver_synth_event(struct perf_session *session,
struct perf_sample *sample) struct perf_sample *sample)
{ {
struct perf_evlist *evlist = session->evlist; struct perf_evlist *evlist = session->evlist;
struct perf_tool *tool = session->ordered_events.tool; struct perf_tool *tool = session->tool;
events_stats__inc(&evlist->stats, event->header.type); events_stats__inc(&evlist->stats, event->header.type);
...@@ -1060,7 +1068,7 @@ static s64 perf_session__process_event(struct perf_session *session, ...@@ -1060,7 +1068,7 @@ static s64 perf_session__process_event(struct perf_session *session,
union perf_event *event, u64 file_offset) union perf_event *event, u64 file_offset)
{ {
struct perf_evlist *evlist = session->evlist; struct perf_evlist *evlist = session->evlist;
struct perf_tool *tool = session->ordered_events.tool; struct perf_tool *tool = session->tool;
struct perf_sample sample; struct perf_sample sample;
int ret; int ret;
...@@ -1117,10 +1125,12 @@ static struct thread *perf_session__register_idle_thread(struct perf_session *se ...@@ -1117,10 +1125,12 @@ static struct thread *perf_session__register_idle_thread(struct perf_session *se
return thread; return thread;
} }
static void perf_tool__warn_about_errors(const struct perf_tool *tool, static void perf_session__warn_about_errors(const struct perf_session *session)
const struct events_stats *stats)
{ {
if (tool->lost == perf_event__process_lost && const struct events_stats *stats = &session->evlist->stats;
const struct ordered_events *oe = &session->ordered_events;
if (session->tool->lost == perf_event__process_lost &&
stats->nr_events[PERF_RECORD_LOST] != 0) { stats->nr_events[PERF_RECORD_LOST] != 0) {
ui__warning("Processed %d events and lost %d chunks!\n\n" ui__warning("Processed %d events and lost %d chunks!\n\n"
"Check IO/CPU overload!\n\n", "Check IO/CPU overload!\n\n",
...@@ -1156,8 +1166,8 @@ static void perf_tool__warn_about_errors(const struct perf_tool *tool, ...@@ -1156,8 +1166,8 @@ static void perf_tool__warn_about_errors(const struct perf_tool *tool,
stats->nr_unprocessable_samples); stats->nr_unprocessable_samples);
} }
if (stats->nr_unordered_events != 0) if (oe->nr_unordered_events != 0)
ui__warning("%u out of order events recorded.\n", stats->nr_unordered_events); ui__warning("%u out of order events recorded.\n", oe->nr_unordered_events);
} }
volatile int session_done; volatile int session_done;
...@@ -1165,7 +1175,7 @@ volatile int session_done; ...@@ -1165,7 +1175,7 @@ volatile int session_done;
static int __perf_session__process_pipe_events(struct perf_session *session) static int __perf_session__process_pipe_events(struct perf_session *session)
{ {
struct ordered_events *oe = &session->ordered_events; struct ordered_events *oe = &session->ordered_events;
struct perf_tool *tool = oe->tool; struct perf_tool *tool = session->tool;
int fd = perf_data_file__fd(session->file); int fd = perf_data_file__fd(session->file);
union perf_event *event; union perf_event *event;
uint32_t size, cur_size = 0; uint32_t size, cur_size = 0;
...@@ -1248,7 +1258,7 @@ static int __perf_session__process_pipe_events(struct perf_session *session) ...@@ -1248,7 +1258,7 @@ static int __perf_session__process_pipe_events(struct perf_session *session)
err = ordered_events__flush(oe, OE_FLUSH__FINAL); err = ordered_events__flush(oe, OE_FLUSH__FINAL);
out_err: out_err:
free(buf); free(buf);
perf_tool__warn_about_errors(tool, &session->evlist->stats); perf_session__warn_about_errors(session);
ordered_events__free(&session->ordered_events); ordered_events__free(&session->ordered_events);
return err; return err;
} }
...@@ -1298,7 +1308,7 @@ static int __perf_session__process_events(struct perf_session *session, ...@@ -1298,7 +1308,7 @@ static int __perf_session__process_events(struct perf_session *session,
u64 file_size) u64 file_size)
{ {
struct ordered_events *oe = &session->ordered_events; struct ordered_events *oe = &session->ordered_events;
struct perf_tool *tool = oe->tool; struct perf_tool *tool = session->tool;
int fd = perf_data_file__fd(session->file); int fd = perf_data_file__fd(session->file);
u64 head, page_offset, file_offset, file_pos, size; u64 head, page_offset, file_offset, file_pos, size;
int err, mmap_prot, mmap_flags, map_idx = 0; int err, mmap_prot, mmap_flags, map_idx = 0;
...@@ -1394,7 +1404,7 @@ static int __perf_session__process_events(struct perf_session *session, ...@@ -1394,7 +1404,7 @@ static int __perf_session__process_events(struct perf_session *session,
err = ordered_events__flush(oe, OE_FLUSH__FINAL); err = ordered_events__flush(oe, OE_FLUSH__FINAL);
out_err: out_err:
ui_progress__finish(); ui_progress__finish();
perf_tool__warn_about_errors(tool, &session->evlist->stats); perf_session__warn_about_errors(session);
ordered_events__free(&session->ordered_events); ordered_events__free(&session->ordered_events);
session->one_mmap = false; session->one_mmap = false;
return err; return err;
......
...@@ -26,6 +26,7 @@ struct perf_session { ...@@ -26,6 +26,7 @@ struct perf_session {
u64 one_mmap_offset; u64 one_mmap_offset;
struct ordered_events ordered_events; struct ordered_events ordered_events;
struct perf_data_file *file; struct perf_data_file *file;
struct perf_tool *tool;
}; };
#define PRINT_IP_OPT_IP (1<<0) #define PRINT_IP_OPT_IP (1<<0)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册