^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * db-export.c: Support for exporting data suitable for import to a database
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (c) 2014, Intel Corporation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <stdlib.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include "dso.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include "evsel.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include "machine.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include "thread.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include "comm.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include "symbol.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include "map.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include "event.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include "thread-stack.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include "callchain.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include "call-path.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include "db-export.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/zalloc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) int db_export__init(struct db_export *dbe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) memset(dbe, 0, sizeof(struct db_export));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) void db_export__exit(struct db_export *dbe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) call_return_processor__free(dbe->crp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) dbe->crp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) int db_export__evsel(struct db_export *dbe, struct evsel *evsel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) if (evsel->db_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) evsel->db_id = ++dbe->evsel_last_db_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) if (dbe->export_evsel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) return dbe->export_evsel(dbe, evsel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) int db_export__machine(struct db_export *dbe, struct machine *machine)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) if (machine->db_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) machine->db_id = ++dbe->machine_last_db_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) if (dbe->export_machine)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) return dbe->export_machine(dbe, machine);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) int db_export__thread(struct db_export *dbe, struct thread *thread,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) struct machine *machine, struct thread *main_thread)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) u64 main_thread_db_id = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) if (thread->db_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) thread->db_id = ++dbe->thread_last_db_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) if (main_thread)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) main_thread_db_id = main_thread->db_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) if (dbe->export_thread)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) return dbe->export_thread(dbe, thread, main_thread_db_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) machine);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) static int __db_export__comm(struct db_export *dbe, struct comm *comm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) struct thread *thread)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) comm->db_id = ++dbe->comm_last_db_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) if (dbe->export_comm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) return dbe->export_comm(dbe, comm, thread);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) int db_export__comm(struct db_export *dbe, struct comm *comm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) struct thread *thread)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) if (comm->db_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) return __db_export__comm(dbe, comm, thread);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) * Export the "exec" comm. The "exec" comm is the program / application command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) * name at the time it first executes. It is used to group threads for the same
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) * program. Note that the main thread pid (or thread group id tgid) cannot be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) * used because it does not change when a new program is exec'ed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) int db_export__exec_comm(struct db_export *dbe, struct comm *comm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) struct thread *main_thread)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) if (comm->db_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) err = __db_export__comm(dbe, comm, main_thread);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) * Record the main thread for this comm. Note that the main thread can
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) * have many "exec" comms because there will be a new one every time it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) * exec's. An "exec" comm however will only ever have 1 main thread.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) * That is different to any other threads for that same program because
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) * exec() will effectively kill them, so the relationship between the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) * "exec" comm and non-main threads is 1-to-1. That is why
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) * db_export__comm_thread() is called here for the main thread, but it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) * is called for non-main threads when they are exported.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) return db_export__comm_thread(dbe, comm, main_thread);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) int db_export__comm_thread(struct db_export *dbe, struct comm *comm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) struct thread *thread)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) u64 db_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) db_id = ++dbe->comm_thread_last_db_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) if (dbe->export_comm_thread)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) return dbe->export_comm_thread(dbe, db_id, comm, thread);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) int db_export__dso(struct db_export *dbe, struct dso *dso,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) struct machine *machine)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) if (dso->db_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) dso->db_id = ++dbe->dso_last_db_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) if (dbe->export_dso)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) return dbe->export_dso(dbe, dso, machine);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) int db_export__symbol(struct db_export *dbe, struct symbol *sym,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) struct dso *dso)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) u64 *sym_db_id = symbol__priv(sym);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) if (*sym_db_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) *sym_db_id = ++dbe->symbol_last_db_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) if (dbe->export_symbol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) return dbe->export_symbol(dbe, sym, dso);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) static int db_ids_from_al(struct db_export *dbe, struct addr_location *al,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) u64 *dso_db_id, u64 *sym_db_id, u64 *offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) if (al->map) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) struct dso *dso = al->map->dso;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) err = db_export__dso(dbe, dso, al->maps->machine);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) *dso_db_id = dso->db_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) if (!al->sym) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) al->sym = symbol__new(al->addr, 0, 0, 0, "unknown");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) if (al->sym)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) dso__insert_symbol(dso, al->sym);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) if (al->sym) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) u64 *db_id = symbol__priv(al->sym);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) err = db_export__symbol(dbe, al->sym, dso);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) *sym_db_id = *db_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) *offset = al->addr - al->sym->start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) static struct call_path *call_path_from_sample(struct db_export *dbe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) struct machine *machine,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) struct thread *thread,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) struct perf_sample *sample,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) struct evsel *evsel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) u64 kernel_start = machine__kernel_start(machine);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) struct call_path *current = &dbe->cpr->call_path;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) enum chain_order saved_order = callchain_param.order;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) if (!symbol_conf.use_callchain || !sample->callchain)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) * Since the call path tree must be built starting with the root, we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) * must use ORDER_CALL for call chain resolution, in order to process
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) * the callchain starting with the root node and ending with the leaf.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) callchain_param.order = ORDER_CALLER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) err = thread__resolve_callchain(thread, &callchain_cursor, evsel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) sample, NULL, NULL, PERF_MAX_STACK_DEPTH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) callchain_param.order = saved_order;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) callchain_cursor_commit(&callchain_cursor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) while (1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) struct callchain_cursor_node *node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) struct addr_location al;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) u64 dso_db_id = 0, sym_db_id = 0, offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) memset(&al, 0, sizeof(al));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) node = callchain_cursor_current(&callchain_cursor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) if (!node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) * Handle export of symbol and dso for this node by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) * constructing an addr_location struct and then passing it to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) * db_ids_from_al() to perform the export.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) al.sym = node->ms.sym;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) al.map = node->ms.map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) al.maps = thread->maps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) al.addr = node->ip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) if (al.map && !al.sym)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) al.sym = dso__find_symbol(al.map->dso, al.addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) db_ids_from_al(dbe, &al, &dso_db_id, &sym_db_id, &offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) /* add node to the call path tree if it doesn't exist */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) current = call_path__findnew(dbe->cpr, current,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) al.sym, node->ip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) kernel_start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) callchain_cursor_advance(&callchain_cursor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) /* Reset the callchain order to its prior value. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) callchain_param.order = saved_order;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) if (current == &dbe->cpr->call_path) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) /* Bail because the callchain was empty. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) return current;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) int db_export__branch_type(struct db_export *dbe, u32 branch_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) if (dbe->export_branch_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) return dbe->export_branch_type(dbe, branch_type, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) static int db_export__threads(struct db_export *dbe, struct thread *thread,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) struct thread *main_thread,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) struct machine *machine, struct comm **comm_ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) struct comm *comm = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) struct comm *curr_comm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) if (main_thread) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) * A thread has a reference to the main thread, so export the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) * main thread first.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) err = db_export__thread(dbe, main_thread, machine, main_thread);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) * Export comm before exporting the non-main thread because
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) * db_export__comm_thread() can be called further below.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) comm = machine__thread_exec_comm(machine, main_thread);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) if (comm) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) err = db_export__exec_comm(dbe, comm, main_thread);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) *comm_ptr = comm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) if (thread != main_thread) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) * For a non-main thread, db_export__comm_thread() must be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) * called only if thread has not previously been exported.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) bool export_comm_thread = comm && !thread->db_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) err = db_export__thread(dbe, thread, machine, main_thread);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) if (export_comm_thread) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) err = db_export__comm_thread(dbe, comm, thread);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) curr_comm = thread__comm(thread);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) if (curr_comm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) return db_export__comm(dbe, curr_comm, thread);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) int db_export__sample(struct db_export *dbe, union perf_event *event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) struct perf_sample *sample, struct evsel *evsel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) struct addr_location *al)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) struct thread *thread = al->thread;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) struct export_sample es = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) .event = event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) .sample = sample,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) .evsel = evsel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) .al = al,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) struct thread *main_thread;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) struct comm *comm = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) err = db_export__evsel(dbe, evsel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) err = db_export__machine(dbe, al->maps->machine);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) main_thread = thread__main_thread(al->maps->machine, thread);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) err = db_export__threads(dbe, thread, main_thread, al->maps->machine, &comm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) goto out_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) if (comm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) es.comm_db_id = comm->db_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) es.db_id = ++dbe->sample_last_db_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) err = db_ids_from_al(dbe, al, &es.dso_db_id, &es.sym_db_id, &es.offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) goto out_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) if (dbe->cpr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) struct call_path *cp = call_path_from_sample(dbe, al->maps->machine,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) thread, sample,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) evsel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) if (cp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) db_export__call_path(dbe, cp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) es.call_path_id = cp->db_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) if ((evsel->core.attr.sample_type & PERF_SAMPLE_ADDR) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) sample_addr_correlates_sym(&evsel->core.attr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) struct addr_location addr_al;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) thread__resolve(thread, &addr_al, sample);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) err = db_ids_from_al(dbe, &addr_al, &es.addr_dso_db_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) &es.addr_sym_db_id, &es.addr_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) goto out_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) if (dbe->crp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) err = thread_stack__process(thread, comm, sample, al,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) &addr_al, es.db_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) dbe->crp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) goto out_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) if (dbe->export_sample)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) err = dbe->export_sample(dbe, &es);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) out_put:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) thread__put(main_thread);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) static struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) u32 branch_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) const char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) } branch_types[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) {0, "no branch"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CALL, "call"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_RETURN, "return"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CONDITIONAL, "conditional jump"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) {PERF_IP_FLAG_BRANCH, "unconditional jump"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CALL | PERF_IP_FLAG_INTERRUPT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) "software interrupt"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_RETURN | PERF_IP_FLAG_INTERRUPT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) "return from interrupt"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CALL | PERF_IP_FLAG_SYSCALLRET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) "system call"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_RETURN | PERF_IP_FLAG_SYSCALLRET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) "return from system call"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_ASYNC, "asynchronous branch"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CALL | PERF_IP_FLAG_ASYNC |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) PERF_IP_FLAG_INTERRUPT, "hardware interrupt"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_TX_ABORT, "transaction abort"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_TRACE_BEGIN, "trace begin"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_TRACE_END, "trace end"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) {0, NULL}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) int db_export__branch_types(struct db_export *dbe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) int i, err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) for (i = 0; branch_types[i].name ; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) err = db_export__branch_type(dbe, branch_types[i].branch_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) branch_types[i].name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) /* Add trace begin / end variants */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) for (i = 0; branch_types[i].name ; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) const char *name = branch_types[i].name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) u32 type = branch_types[i].branch_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) char buf[64];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) if (type == PERF_IP_FLAG_BRANCH ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) (type & (PERF_IP_FLAG_TRACE_BEGIN | PERF_IP_FLAG_TRACE_END)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) snprintf(buf, sizeof(buf), "trace begin / %s", name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) err = db_export__branch_type(dbe, type | PERF_IP_FLAG_TRACE_BEGIN, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) snprintf(buf, sizeof(buf), "%s / trace end", name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) err = db_export__branch_type(dbe, type | PERF_IP_FLAG_TRACE_END, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) int db_export__call_path(struct db_export *dbe, struct call_path *cp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) if (cp->db_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) if (cp->parent) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) err = db_export__call_path(dbe, cp->parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) cp->db_id = ++dbe->call_path_last_db_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) if (dbe->export_call_path)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) return dbe->export_call_path(dbe, cp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) int db_export__call_return(struct db_export *dbe, struct call_return *cr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) u64 *parent_db_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) err = db_export__call_path(dbe, cr->cp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) if (!cr->db_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) cr->db_id = ++dbe->call_return_last_db_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) if (parent_db_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) if (!*parent_db_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) *parent_db_id = ++dbe->call_return_last_db_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) cr->parent_db_id = *parent_db_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) if (dbe->export_call_return)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) return dbe->export_call_return(dbe, cr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) static int db_export__pid_tid(struct db_export *dbe, struct machine *machine,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) pid_t pid, pid_t tid, u64 *db_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) struct comm **comm_ptr, bool *is_idle)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) struct thread *thread = machine__find_thread(machine, pid, tid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) struct thread *main_thread;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) if (!thread || !thread->comm_set)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) goto out_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) *is_idle = !thread->pid_ && !thread->tid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) main_thread = thread__main_thread(machine, thread);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) err = db_export__threads(dbe, thread, main_thread, machine, comm_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) *db_id = thread->db_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) thread__put(main_thread);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) out_put:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) thread__put(thread);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) int db_export__switch(struct db_export *dbe, union perf_event *event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) struct perf_sample *sample, struct machine *machine)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) bool out = event->header.misc & PERF_RECORD_MISC_SWITCH_OUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) bool out_preempt = out &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) (event->header.misc & PERF_RECORD_MISC_SWITCH_OUT_PREEMPT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) int flags = out | (out_preempt << 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) bool is_idle_a = false, is_idle_b = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) u64 th_a_id = 0, th_b_id = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) u64 comm_out_id, comm_in_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) struct comm *comm_a = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) struct comm *comm_b = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) u64 th_out_id, th_in_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) u64 db_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) err = db_export__machine(dbe, machine);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) err = db_export__pid_tid(dbe, machine, sample->pid, sample->tid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) &th_a_id, &comm_a, &is_idle_a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) if (event->header.type == PERF_RECORD_SWITCH_CPU_WIDE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) pid_t pid = event->context_switch.next_prev_pid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) pid_t tid = event->context_switch.next_prev_tid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) err = db_export__pid_tid(dbe, machine, pid, tid, &th_b_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) &comm_b, &is_idle_b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) * Do not export if both threads are unknown (i.e. not being traced),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) * or one is unknown and the other is the idle task.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) if ((!th_a_id || is_idle_a) && (!th_b_id || is_idle_b))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) db_id = ++dbe->context_switch_last_db_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) if (out) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) th_out_id = th_a_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) th_in_id = th_b_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) comm_out_id = comm_a ? comm_a->db_id : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) comm_in_id = comm_b ? comm_b->db_id : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) th_out_id = th_b_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) th_in_id = th_a_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) comm_out_id = comm_b ? comm_b->db_id : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) comm_in_id = comm_a ? comm_a->db_id : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) if (dbe->export_context_switch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) return dbe->export_context_switch(dbe, db_id, machine, sample,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) th_out_id, comm_out_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) th_in_id, comm_in_id, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) }