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