#include <linux/kernel.h>
#include <traceevent/event-parse.h>
#include <byteswap.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/mman.h>
#include "evlist.h"
#include "evsel.h"
#include "session.h"
#include "tool.h"
#include "sort.h"
#include "util.h"
#include "cpumap.h"
#include "perf_regs.h"
#include "asm/bug.h"
static int perf_session__open(struct perf_session *session)
{
struct perf_data_file *file = session->file;
if (perf_session__read_header(session) < 0) {
pr_err("incompatible file format (rerun with -v to learn more)");
return -1;
}
if (perf_data_file__is_pipe(file))
return 0;
if (!perf_evlist__valid_sample_type(session->evlist)) {
pr_err("non matching sample_type");
return -1;
}
if (!perf_evlist__valid_sample_id_all(session->evlist)) {
pr_err("non matching sample_id_all");
return -1;
}
if (!perf_evlist__valid_read_format(session->evlist)) {
pr_err("non matching read_format");
return -1;
}
return 0;
}
void perf_session__set_id_hdr_size(struct perf_session *session)
{
u16 id_hdr_size = perf_evlist__id_hdr_size(session->evlist);
machines__set_id_hdr_size(&session->machines, id_hdr_size);
}
int perf_session__create_kernel_maps(struct perf_session *session)
{
int ret = machine__create_kernel_maps(&session->machines.host);
if (ret >= 0)
ret = machines__create_guest_kernel_maps(&session->machines);
return ret;
}
static void perf_session__destroy_kernel_maps(struct perf_session *session)
{
machines__destroy_kernel_maps(&session->machines);
}
static bool perf_session__has_comm_exec(struct perf_session *session)
{
struct perf_evsel *evsel;
evlist__for_each(session->evlist, evsel) {
if (evsel->attr.comm_exec)
return true;
}
return false;
}
static void perf_session__set_comm_exec(struct perf_session *session)
{
bool comm_exec = perf_session__has_comm_exec(session);
machines__set_comm_exec(&session->machines, comm_exec);
}
struct perf_session *perf_session__new(struct perf_data_file *file,
bool repipe, struct perf_tool *tool)
{
struct perf_session *session = zalloc(sizeof(*session));
if (!session)
goto out;
session->repipe = repipe;
ordered_events__init(&session->ordered_events);
machines__init(&session->machines);
if (file) {
if (perf_data_file__open(file))
goto out_delete;
session->file = file;
if (perf_data_file__is_read(file)) {
if (perf_session__open(session) < 0)
goto out_close;
perf_session__set_id_hdr_size(session);
perf_session__set_comm_exec(session);
}
}
if (!file || perf_data_file__is_write(file)) {
/*
* In O_RDONLY mode this will be performed when reading the
* kernel MMAP event, in perf_event__process_mmap().
*/
if (perf_session__create_kernel_maps(session) < 0)
pr_warning("Cannot read kernel map\n");
}
if (tool && tool->ordering_requires_timestamps &&
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;
}
return session;
out_close:
perf_data_file__close(file);
out_delete:
perf_session__delete(session);
out:
return NULL;
}
static void perf_session__delete_dead_threads(struct perf_session *session)
{
machine__delete_dead_threads(&session->machines.host);
}
static void perf_session__delete_threads(struct perf_session *session)
{
machine__delete_threads(&session->machines.host);
}
static void perf_session_env__delete(struct perf_session_env *env)
{
zfree(&env->hostname);
zfree(&env->os_release);
zfree(&env->version);
zfree(&env->arch);
zfree(&env->cpu_desc);
zfree(&env->cpuid);
zfree(&env->cmdline);
zfree(&env->sibling_cores);
zfree(&env->sibling_threads);
zfree(&env->numa_nodes);
zfree(&env->pmu_mappings);
}
void perf_session__delete(struct perf_session *session)
{
perf_session__destroy_kernel_maps(session);
perf_session__delete_dead_threads(session);
perf_session__delete_threads(session);
perf_session_env__delete(&session->header.env);
machines__exit(&session->machines);
if (session->file)
perf_data_file__close(session->file);
free(session);
}
static int process_event_synth_tracing_data_stub(struct perf_tool *tool
__maybe_unused,
union perf_event *event
__maybe_unused,
struct perf_session *session
__maybe_unused)
{
dump_printf(": unhandled!\n");
return 0;
}
static int process_event_synth_attr_stub(struct perf_tool *tool __maybe_unused,
union perf_event *event __maybe_unused,
struct perf_evlist **pevlist
__maybe_unused)
{
dump_printf(": unhandled!\n");
return 0;
}
static int process_event_sample_stub(struct perf_tool *tool __maybe_unused,
union perf_event *event __maybe_unused,
struct perf_sample *sample __maybe_unused,
struct perf_evsel
|