From 890e1df1bec891d9203724541e81f8fbe5183388 Mon Sep 17 00:00:00 2001 From: hc <hc@nodka.com> Date: Mon, 19 Feb 2024 01:57:06 +0000 Subject: [PATCH] default settings GPIO PA4 PA6 PA3 PB5 --- kernel/tools/perf/util/scripting-engines/trace-event-python.c | 441 +++++++++++++++++++++++++++++++++++-------------------- 1 files changed, 280 insertions(+), 161 deletions(-) diff --git a/kernel/tools/perf/util/scripting-engines/trace-event-python.c b/kernel/tools/perf/util/scripting-engines/trace-event-python.c index 2814251..23dc501 100644 --- a/kernel/tools/perf/util/scripting-engines/trace-event-python.c +++ b/kernel/tools/perf/util/scripting-engines/trace-event-python.c @@ -31,11 +31,12 @@ #include <linux/compiler.h> #include <linux/time64.h> -#include "../../perf.h" +#include "../build-id.h" +#include "../counts.h" #include "../debug.h" +#include "../dso.h" #include "../callchain.h" #include "../evsel.h" -#include "../util.h" #include "../event.h" #include "../thread.h" #include "../comm.h" @@ -44,8 +45,9 @@ #include "../thread-stack.h" #include "../trace-event.h" #include "../call-path.h" +#include "map.h" +#include "symbol.h" #include "thread_map.h" -#include "cpumap.h" #include "print_binary.h" #include "stat.h" #include "mem-events.h" @@ -110,6 +112,8 @@ PyObject *sample_handler; PyObject *call_path_handler; PyObject *call_return_handler; + PyObject *synth_handler; + PyObject *context_switch_handler; bool db_export_mode; }; @@ -193,7 +197,7 @@ call_object(handler, args, handler_name); } -static void define_value(enum print_arg_type field_type, +static void define_value(enum tep_print_arg_type field_type, const char *ev_name, const char *field_name, const char *field_value, @@ -204,7 +208,7 @@ unsigned long long value; unsigned n = 0; - if (field_type == PRINT_SYMBOL) + if (field_type == TEP_PRINT_SYMBOL) handler_name = "define_symbolic_value"; t = PyTuple_New(4); @@ -223,8 +227,8 @@ Py_DECREF(t); } -static void define_values(enum print_arg_type field_type, - struct print_flag_sym *field, +static void define_values(enum tep_print_arg_type field_type, + struct tep_print_flag_sym *field, const char *ev_name, const char *field_name) { @@ -235,7 +239,7 @@ define_values(field_type, field->next, ev_name, field_name); } -static void define_field(enum print_arg_type field_type, +static void define_field(enum tep_print_arg_type field_type, const char *ev_name, const char *field_name, const char *delim) @@ -244,10 +248,10 @@ PyObject *t; unsigned n = 0; - if (field_type == PRINT_SYMBOL) + if (field_type == TEP_PRINT_SYMBOL) handler_name = "define_symbolic_field"; - if (field_type == PRINT_FLAGS) + if (field_type == TEP_PRINT_FLAGS) t = PyTuple_New(3); else t = PyTuple_New(2); @@ -256,7 +260,7 @@ PyTuple_SetItem(t, n++, _PyUnicode_FromString(ev_name)); PyTuple_SetItem(t, n++, _PyUnicode_FromString(field_name)); - if (field_type == PRINT_FLAGS) + if (field_type == TEP_PRINT_FLAGS) PyTuple_SetItem(t, n++, _PyUnicode_FromString(delim)); try_call_object(handler_name, t); @@ -264,54 +268,54 @@ Py_DECREF(t); } -static void define_event_symbols(struct event_format *event, +static void define_event_symbols(struct tep_event *event, const char *ev_name, - struct print_arg *args) + struct tep_print_arg *args) { if (args == NULL) return; switch (args->type) { - case PRINT_NULL: + case TEP_PRINT_NULL: break; - case PRINT_ATOM: - define_value(PRINT_FLAGS, ev_name, cur_field_name, "0", + case TEP_PRINT_ATOM: + define_value(TEP_PRINT_FLAGS, ev_name, cur_field_name, "0", args->atom.atom); zero_flag_atom = 0; break; - case PRINT_FIELD: + case TEP_PRINT_FIELD: free(cur_field_name); cur_field_name = strdup(args->field.name); break; - case PRINT_FLAGS: + case TEP_PRINT_FLAGS: define_event_symbols(event, ev_name, args->flags.field); - define_field(PRINT_FLAGS, ev_name, cur_field_name, + define_field(TEP_PRINT_FLAGS, ev_name, cur_field_name, args->flags.delim); - define_values(PRINT_FLAGS, args->flags.flags, ev_name, + define_values(TEP_PRINT_FLAGS, args->flags.flags, ev_name, cur_field_name); break; - case PRINT_SYMBOL: + case TEP_PRINT_SYMBOL: define_event_symbols(event, ev_name, args->symbol.field); - define_field(PRINT_SYMBOL, ev_name, cur_field_name, NULL); - define_values(PRINT_SYMBOL, args->symbol.symbols, ev_name, + define_field(TEP_PRINT_SYMBOL, ev_name, cur_field_name, NULL); + define_values(TEP_PRINT_SYMBOL, args->symbol.symbols, ev_name, cur_field_name); break; - case PRINT_HEX: - case PRINT_HEX_STR: + case TEP_PRINT_HEX: + case TEP_PRINT_HEX_STR: define_event_symbols(event, ev_name, args->hex.field); define_event_symbols(event, ev_name, args->hex.size); break; - case PRINT_INT_ARRAY: + case TEP_PRINT_INT_ARRAY: define_event_symbols(event, ev_name, args->int_array.field); define_event_symbols(event, ev_name, args->int_array.count); define_event_symbols(event, ev_name, args->int_array.el_size); break; - case PRINT_STRING: + case TEP_PRINT_STRING: break; - case PRINT_TYPE: + case TEP_PRINT_TYPE: define_event_symbols(event, ev_name, args->typecast.item); break; - case PRINT_OP: + case TEP_PRINT_OP: if (strcmp(args->op.op, ":") == 0) zero_flag_atom = 1; define_event_symbols(event, ev_name, args->op.left); @@ -319,11 +323,11 @@ break; default: /* gcc warns for these? */ - case PRINT_BSTRING: - case PRINT_DYNAMIC_ARRAY: - case PRINT_DYNAMIC_ARRAY_LEN: - case PRINT_FUNC: - case PRINT_BITMASK: + case TEP_PRINT_BSTRING: + case TEP_PRINT_DYNAMIC_ARRAY: + case TEP_PRINT_DYNAMIC_ARRAY_LEN: + case TEP_PRINT_FUNC: + case TEP_PRINT_BITMASK: /* we should warn... */ return; } @@ -332,10 +336,10 @@ define_event_symbols(event, ev_name, args->next); } -static PyObject *get_field_numeric_entry(struct event_format *event, - struct format_field *field, void *data) +static PyObject *get_field_numeric_entry(struct tep_event *event, + struct tep_format_field *field, void *data) { - bool is_array = field->flags & FIELD_IS_ARRAY; + bool is_array = field->flags & TEP_FIELD_IS_ARRAY; PyObject *obj = NULL, *list = NULL; unsigned long long val; unsigned int item_size, n_items, i; @@ -353,7 +357,7 @@ val = read_size(event, data + field->offset + i * item_size, item_size); - if (field->flags & FIELD_IS_SIGNED) { + if (field->flags & TEP_FIELD_IS_SIGNED) { if ((long long)val >= LONG_MIN && (long long)val <= LONG_MAX) obj = _PyLong_FromLong(val); @@ -388,7 +392,7 @@ } static PyObject *python_process_callchain(struct perf_sample *sample, - struct perf_evsel *evsel, + struct evsel *evsel, struct addr_location *al) { PyObject *pylist; @@ -424,24 +428,24 @@ pydict_set_item_string_decref(pyelem, "ip", PyLong_FromUnsignedLongLong(node->ip)); - if (node->sym) { + if (node->ms.sym) { PyObject *pysym = PyDict_New(); if (!pysym) Py_FatalError("couldn't create Python dictionary"); pydict_set_item_string_decref(pysym, "start", - PyLong_FromUnsignedLongLong(node->sym->start)); + PyLong_FromUnsignedLongLong(node->ms.sym->start)); pydict_set_item_string_decref(pysym, "end", - PyLong_FromUnsignedLongLong(node->sym->end)); + PyLong_FromUnsignedLongLong(node->ms.sym->end)); pydict_set_item_string_decref(pysym, "binding", - _PyLong_FromLong(node->sym->binding)); + _PyLong_FromLong(node->ms.sym->binding)); pydict_set_item_string_decref(pysym, "name", - _PyUnicode_FromStringAndSize(node->sym->name, - node->sym->namelen)); + _PyUnicode_FromStringAndSize(node->ms.sym->name, + node->ms.sym->namelen)); pydict_set_item_string_decref(pyelem, "sym", pysym); } - if (node->map) { - const char *dsoname = get_dsoname(node->map); + if (node->ms.map) { + const char *dsoname = get_dsoname(node->ms.map); pydict_set_item_string_decref(pyelem, "dso", _PyUnicode_FromString(dsoname)); @@ -460,6 +464,7 @@ struct thread *thread) { struct branch_stack *br = sample->branch_stack; + struct branch_entry *entries = perf_sample__branch_entries(sample); PyObject *pylist; u64 i; @@ -480,28 +485,28 @@ Py_FatalError("couldn't create Python dictionary"); pydict_set_item_string_decref(pyelem, "from", - PyLong_FromUnsignedLongLong(br->entries[i].from)); + PyLong_FromUnsignedLongLong(entries[i].from)); pydict_set_item_string_decref(pyelem, "to", - PyLong_FromUnsignedLongLong(br->entries[i].to)); + PyLong_FromUnsignedLongLong(entries[i].to)); pydict_set_item_string_decref(pyelem, "mispred", - PyBool_FromLong(br->entries[i].flags.mispred)); + PyBool_FromLong(entries[i].flags.mispred)); pydict_set_item_string_decref(pyelem, "predicted", - PyBool_FromLong(br->entries[i].flags.predicted)); + PyBool_FromLong(entries[i].flags.predicted)); pydict_set_item_string_decref(pyelem, "in_tx", - PyBool_FromLong(br->entries[i].flags.in_tx)); + PyBool_FromLong(entries[i].flags.in_tx)); pydict_set_item_string_decref(pyelem, "abort", - PyBool_FromLong(br->entries[i].flags.abort)); + PyBool_FromLong(entries[i].flags.abort)); pydict_set_item_string_decref(pyelem, "cycles", - PyLong_FromUnsignedLongLong(br->entries[i].flags.cycles)); + PyLong_FromUnsignedLongLong(entries[i].flags.cycles)); thread__find_map_fb(thread, sample->cpumode, - br->entries[i].from, &al); + entries[i].from, &al); dsoname = get_dsoname(al.map); pydict_set_item_string_decref(pyelem, "from_dsoname", _PyUnicode_FromString(dsoname)); thread__find_map_fb(thread, sample->cpumode, - br->entries[i].to, &al); + entries[i].to, &al); dsoname = get_dsoname(al.map); pydict_set_item_string_decref(pyelem, "to_dsoname", _PyUnicode_FromString(dsoname)); @@ -557,6 +562,7 @@ struct thread *thread) { struct branch_stack *br = sample->branch_stack; + struct branch_entry *entries = perf_sample__branch_entries(sample); PyObject *pylist; u64 i; char bf[512]; @@ -577,22 +583,22 @@ Py_FatalError("couldn't create Python dictionary"); thread__find_symbol_fb(thread, sample->cpumode, - br->entries[i].from, &al); + entries[i].from, &al); get_symoff(al.sym, &al, true, bf, sizeof(bf)); pydict_set_item_string_decref(pyelem, "from", _PyUnicode_FromString(bf)); thread__find_symbol_fb(thread, sample->cpumode, - br->entries[i].to, &al); + entries[i].to, &al); get_symoff(al.sym, &al, true, bf, sizeof(bf)); pydict_set_item_string_decref(pyelem, "to", _PyUnicode_FromString(bf)); - get_br_mspred(&br->entries[i].flags, bf, sizeof(bf)); + get_br_mspred(&entries[i].flags, bf, sizeof(bf)); pydict_set_item_string_decref(pyelem, "pred", _PyUnicode_FromString(bf)); - if (br->entries[i].flags.in_tx) { + if (entries[i].flags.in_tx) { pydict_set_item_string_decref(pyelem, "in_tx", _PyUnicode_FromString("X")); } else { @@ -600,7 +606,7 @@ _PyUnicode_FromString("-")); } - if (br->entries[i].flags.abort) { + if (entries[i].flags.abort) { pydict_set_item_string_decref(pyelem, "abort", _PyUnicode_FromString("A")); } else { @@ -630,9 +636,9 @@ static void set_sample_read_in_dict(PyObject *dict_sample, struct perf_sample *sample, - struct perf_evsel *evsel) + struct evsel *evsel) { - u64 read_format = evsel->attr.read_format; + u64 read_format = evsel->core.attr.read_format; PyObject *values; unsigned int i; @@ -688,6 +694,9 @@ bf[0] = 0; + if (!regs || !regs->regs) + return 0; + for_each_set_bit(r, (unsigned long *) &mask, sizeof(mask) * 8) { u64 val = regs->regs[i++]; @@ -701,9 +710,9 @@ static void set_regs_in_dict(PyObject *dict, struct perf_sample *sample, - struct perf_evsel *evsel) + struct evsel *evsel) { - struct perf_event_attr *attr = &evsel->attr; + struct perf_event_attr *attr = &evsel->core.attr; char bf[512]; regs_map(&sample->intr_regs, attr->sample_regs_intr, bf, sizeof(bf)); @@ -718,7 +727,7 @@ } static PyObject *get_perf_sample_dict(struct perf_sample *sample, - struct perf_evsel *evsel, + struct evsel *evsel, struct addr_location *al, PyObject *callchain) { @@ -732,8 +741,8 @@ if (!dict_sample) Py_FatalError("couldn't create Python dictionary"); - pydict_set_item_string_decref(dict, "ev_name", _PyUnicode_FromString(perf_evsel__name(evsel))); - pydict_set_item_string_decref(dict, "attr", _PyBytes_FromStringAndSize((const char *)&evsel->attr, sizeof(evsel->attr))); + pydict_set_item_string_decref(dict, "ev_name", _PyUnicode_FromString(evsel__name(evsel))); + pydict_set_item_string_decref(dict, "attr", _PyBytes_FromStringAndSize((const char *)&evsel->core.attr, sizeof(evsel->core.attr))); pydict_set_item_string_decref(dict_sample, "pid", _PyLong_FromLong(sample->pid)); @@ -786,14 +795,14 @@ } static void python_process_tracepoint(struct perf_sample *sample, - struct perf_evsel *evsel, + struct evsel *evsel, struct addr_location *al) { - struct event_format *event = evsel->tp_format; + struct tep_event *event = evsel->tp_format; PyObject *handler, *context, *t, *obj = NULL, *callchain; PyObject *dict = NULL, *all_entries_dict = NULL; static char handler_name[256]; - struct format_field *field; + struct tep_format_field *field; unsigned long s, ns; unsigned n = 0; int pid; @@ -805,7 +814,7 @@ if (!event) { snprintf(handler_name, sizeof(handler_name), - "ug! no event found for type %" PRIu64, (u64)evsel->attr.config); + "ug! no event found for type %" PRIu64, (u64)evsel->core.attr.config); Py_FatalError(handler_name); } @@ -835,7 +844,7 @@ ns = nsecs - s * NSEC_PER_SEC; scripting_context->event_data = data; - scripting_context->pevent = evsel->tp_format->pevent; + scripting_context->pevent = evsel->tp_format->tep; context = _PyCapsule_New(scripting_context, NULL, NULL); @@ -866,22 +875,22 @@ unsigned int offset, len; unsigned long long val; - if (field->flags & FIELD_IS_ARRAY) { + if (field->flags & TEP_FIELD_IS_ARRAY) { offset = field->offset; len = field->size; - if (field->flags & FIELD_IS_DYNAMIC) { + if (field->flags & TEP_FIELD_IS_DYNAMIC) { val = tep_read_number(scripting_context->pevent, data + offset, len); offset = val; len = offset >> 16; offset &= 0xffff; } - if (field->flags & FIELD_IS_STRING && + if (field->flags & TEP_FIELD_IS_STRING && is_printable_array(data + offset, len)) { obj = _PyUnicode_FromString((char *) data + offset); } else { obj = PyByteArray_FromStringAndSize((const char *) data + offset, len); - field->flags &= ~FIELD_IS_STRING; + field->flags &= ~TEP_FIELD_IS_STRING; } } else { /* FIELD_IS_NUMERIC */ obj = get_field_numeric_entry(event, field, data); @@ -925,13 +934,29 @@ return t; } -static int tuple_set_u64(PyObject *t, unsigned int pos, u64 val) +static int tuple_set_s64(PyObject *t, unsigned int pos, s64 val) { #if BITS_PER_LONG == 64 return PyTuple_SetItem(t, pos, _PyLong_FromLong(val)); #endif #if BITS_PER_LONG == 32 return PyTuple_SetItem(t, pos, PyLong_FromLongLong(val)); +#endif +} + +/* + * Databases support only signed 64-bit numbers, so even though we are + * exporting a u64, it must be as s64. + */ +#define tuple_set_d64 tuple_set_s64 + +static int tuple_set_u64(PyObject *t, unsigned int pos, u64 val) +{ +#if BITS_PER_LONG == 64 + return PyTuple_SetItem(t, pos, PyLong_FromUnsignedLong(val)); +#endif +#if BITS_PER_LONG == 32 + return PyTuple_SetItem(t, pos, PyLong_FromUnsignedLongLong(val)); #endif } @@ -945,15 +970,21 @@ return PyTuple_SetItem(t, pos, _PyUnicode_FromString(s)); } -static int python_export_evsel(struct db_export *dbe, struct perf_evsel *evsel) +static int tuple_set_bytes(PyObject *t, unsigned int pos, void *bytes, + unsigned int sz) +{ + return PyTuple_SetItem(t, pos, _PyBytes_FromStringAndSize(bytes, sz)); +} + +static int python_export_evsel(struct db_export *dbe, struct evsel *evsel) { struct tables *tables = container_of(dbe, struct tables, dbe); PyObject *t; t = tuple_new(2); - tuple_set_u64(t, 0, evsel->db_id); - tuple_set_string(t, 1, perf_evsel__name(evsel)); + tuple_set_d64(t, 0, evsel->db_id); + tuple_set_string(t, 1, evsel__name(evsel)); call_object(tables->evsel_handler, t, "evsel_table"); @@ -970,7 +1001,7 @@ t = tuple_new(3); - tuple_set_u64(t, 0, machine->db_id); + tuple_set_d64(t, 0, machine->db_id); tuple_set_s32(t, 1, machine->pid); tuple_set_string(t, 2, machine->root_dir ? machine->root_dir : ""); @@ -989,9 +1020,9 @@ t = tuple_new(5); - tuple_set_u64(t, 0, thread->db_id); - tuple_set_u64(t, 1, machine->db_id); - tuple_set_u64(t, 2, main_thread_db_id); + tuple_set_d64(t, 0, thread->db_id); + tuple_set_d64(t, 1, machine->db_id); + tuple_set_d64(t, 2, main_thread_db_id); tuple_set_s32(t, 3, thread->pid_); tuple_set_s32(t, 4, thread->tid); @@ -1002,15 +1033,19 @@ return 0; } -static int python_export_comm(struct db_export *dbe, struct comm *comm) +static int python_export_comm(struct db_export *dbe, struct comm *comm, + struct thread *thread) { struct tables *tables = container_of(dbe, struct tables, dbe); PyObject *t; - t = tuple_new(2); + t = tuple_new(5); - tuple_set_u64(t, 0, comm->db_id); + tuple_set_d64(t, 0, comm->db_id); tuple_set_string(t, 1, comm__str(comm)); + tuple_set_d64(t, 2, thread->db_id); + tuple_set_d64(t, 3, comm->start); + tuple_set_s32(t, 4, comm->exec); call_object(tables->comm_handler, t, "comm_table"); @@ -1027,9 +1062,9 @@ t = tuple_new(3); - tuple_set_u64(t, 0, db_id); - tuple_set_u64(t, 1, comm->db_id); - tuple_set_u64(t, 2, thread->db_id); + tuple_set_d64(t, 0, db_id); + tuple_set_d64(t, 1, comm->db_id); + tuple_set_d64(t, 2, thread->db_id); call_object(tables->comm_thread_handler, t, "comm_thread_table"); @@ -1045,12 +1080,12 @@ char sbuild_id[SBUILD_ID_SIZE]; PyObject *t; - build_id__sprintf(dso->build_id, sizeof(dso->build_id), sbuild_id); + build_id__sprintf(&dso->bid, sbuild_id); t = tuple_new(5); - tuple_set_u64(t, 0, dso->db_id); - tuple_set_u64(t, 1, machine->db_id); + tuple_set_d64(t, 0, dso->db_id); + tuple_set_d64(t, 1, machine->db_id); tuple_set_string(t, 2, dso->short_name); tuple_set_string(t, 3, dso->long_name); tuple_set_string(t, 4, sbuild_id); @@ -1071,10 +1106,10 @@ t = tuple_new(6); - tuple_set_u64(t, 0, *sym_db_id); - tuple_set_u64(t, 1, dso->db_id); - tuple_set_u64(t, 2, sym->start); - tuple_set_u64(t, 3, sym->end); + tuple_set_d64(t, 0, *sym_db_id); + tuple_set_d64(t, 1, dso->db_id); + tuple_set_d64(t, 2, sym->start); + tuple_set_d64(t, 3, sym->end); tuple_set_s32(t, 4, sym->binding); tuple_set_string(t, 5, sym->name); @@ -1103,40 +1138,69 @@ return 0; } -static int python_export_sample(struct db_export *dbe, - struct export_sample *es) +static void python_export_sample_table(struct db_export *dbe, + struct export_sample *es) { struct tables *tables = container_of(dbe, struct tables, dbe); PyObject *t; - t = tuple_new(22); + t = tuple_new(24); - tuple_set_u64(t, 0, es->db_id); - tuple_set_u64(t, 1, es->evsel->db_id); - tuple_set_u64(t, 2, es->al->machine->db_id); - tuple_set_u64(t, 3, es->al->thread->db_id); - tuple_set_u64(t, 4, es->comm_db_id); - tuple_set_u64(t, 5, es->dso_db_id); - tuple_set_u64(t, 6, es->sym_db_id); - tuple_set_u64(t, 7, es->offset); - tuple_set_u64(t, 8, es->sample->ip); - tuple_set_u64(t, 9, es->sample->time); + tuple_set_d64(t, 0, es->db_id); + tuple_set_d64(t, 1, es->evsel->db_id); + tuple_set_d64(t, 2, es->al->maps->machine->db_id); + tuple_set_d64(t, 3, es->al->thread->db_id); + tuple_set_d64(t, 4, es->comm_db_id); + tuple_set_d64(t, 5, es->dso_db_id); + tuple_set_d64(t, 6, es->sym_db_id); + tuple_set_d64(t, 7, es->offset); + tuple_set_d64(t, 8, es->sample->ip); + tuple_set_d64(t, 9, es->sample->time); tuple_set_s32(t, 10, es->sample->cpu); - tuple_set_u64(t, 11, es->addr_dso_db_id); - tuple_set_u64(t, 12, es->addr_sym_db_id); - tuple_set_u64(t, 13, es->addr_offset); - tuple_set_u64(t, 14, es->sample->addr); - tuple_set_u64(t, 15, es->sample->period); - tuple_set_u64(t, 16, es->sample->weight); - tuple_set_u64(t, 17, es->sample->transaction); - tuple_set_u64(t, 18, es->sample->data_src); + tuple_set_d64(t, 11, es->addr_dso_db_id); + tuple_set_d64(t, 12, es->addr_sym_db_id); + tuple_set_d64(t, 13, es->addr_offset); + tuple_set_d64(t, 14, es->sample->addr); + tuple_set_d64(t, 15, es->sample->period); + tuple_set_d64(t, 16, es->sample->weight); + tuple_set_d64(t, 17, es->sample->transaction); + tuple_set_d64(t, 18, es->sample->data_src); tuple_set_s32(t, 19, es->sample->flags & PERF_BRANCH_MASK); tuple_set_s32(t, 20, !!(es->sample->flags & PERF_IP_FLAG_IN_TX)); - tuple_set_u64(t, 21, es->call_path_id); + tuple_set_d64(t, 21, es->call_path_id); + tuple_set_d64(t, 22, es->sample->insn_cnt); + tuple_set_d64(t, 23, es->sample->cyc_cnt); call_object(tables->sample_handler, t, "sample_table"); Py_DECREF(t); +} + +static void python_export_synth(struct db_export *dbe, struct export_sample *es) +{ + struct tables *tables = container_of(dbe, struct tables, dbe); + PyObject *t; + + t = tuple_new(3); + + tuple_set_d64(t, 0, es->db_id); + tuple_set_d64(t, 1, es->evsel->core.attr.config); + tuple_set_bytes(t, 2, es->sample->raw_data, es->sample->raw_size); + + call_object(tables->synth_handler, t, "synth_data"); + + Py_DECREF(t); +} + +static int python_export_sample(struct db_export *dbe, + struct export_sample *es) +{ + struct tables *tables = container_of(dbe, struct tables, dbe); + + python_export_sample_table(dbe, es); + + if (es->evsel->core.attr.type == PERF_TYPE_SYNTH && tables->synth_handler) + python_export_synth(dbe, es); return 0; } @@ -1152,10 +1216,10 @@ t = tuple_new(4); - tuple_set_u64(t, 0, cp->db_id); - tuple_set_u64(t, 1, parent_db_id); - tuple_set_u64(t, 2, sym_db_id); - tuple_set_u64(t, 3, cp->ip); + tuple_set_d64(t, 0, cp->db_id); + tuple_set_d64(t, 1, parent_db_id); + tuple_set_d64(t, 2, sym_db_id); + tuple_set_d64(t, 3, cp->ip); call_object(tables->call_path_handler, t, "call_path_table"); @@ -1171,19 +1235,22 @@ u64 comm_db_id = cr->comm ? cr->comm->db_id : 0; PyObject *t; - t = tuple_new(11); + t = tuple_new(14); - tuple_set_u64(t, 0, cr->db_id); - tuple_set_u64(t, 1, cr->thread->db_id); - tuple_set_u64(t, 2, comm_db_id); - tuple_set_u64(t, 3, cr->cp->db_id); - tuple_set_u64(t, 4, cr->call_time); - tuple_set_u64(t, 5, cr->return_time); - tuple_set_u64(t, 6, cr->branch_count); - tuple_set_u64(t, 7, cr->call_ref); - tuple_set_u64(t, 8, cr->return_ref); - tuple_set_u64(t, 9, cr->cp->parent->db_id); + tuple_set_d64(t, 0, cr->db_id); + tuple_set_d64(t, 1, cr->thread->db_id); + tuple_set_d64(t, 2, comm_db_id); + tuple_set_d64(t, 3, cr->cp->db_id); + tuple_set_d64(t, 4, cr->call_time); + tuple_set_d64(t, 5, cr->return_time); + tuple_set_d64(t, 6, cr->branch_count); + tuple_set_d64(t, 7, cr->call_ref); + tuple_set_d64(t, 8, cr->return_ref); + tuple_set_d64(t, 9, cr->cp->parent->db_id); tuple_set_s32(t, 10, cr->flags); + tuple_set_d64(t, 11, cr->parent_db_id); + tuple_set_d64(t, 12, cr->insn_count); + tuple_set_d64(t, 13, cr->cyc_count); call_object(tables->call_return_handler, t, "call_return_table"); @@ -1192,15 +1259,44 @@ return 0; } -static int python_process_call_return(struct call_return *cr, void *data) +static int python_export_context_switch(struct db_export *dbe, u64 db_id, + struct machine *machine, + struct perf_sample *sample, + u64 th_out_id, u64 comm_out_id, + u64 th_in_id, u64 comm_in_id, int flags) +{ + struct tables *tables = container_of(dbe, struct tables, dbe); + PyObject *t; + + t = tuple_new(9); + + tuple_set_d64(t, 0, db_id); + tuple_set_d64(t, 1, machine->db_id); + tuple_set_d64(t, 2, sample->time); + tuple_set_s32(t, 3, sample->cpu); + tuple_set_d64(t, 4, th_out_id); + tuple_set_d64(t, 5, comm_out_id); + tuple_set_d64(t, 6, th_in_id); + tuple_set_d64(t, 7, comm_in_id); + tuple_set_s32(t, 8, flags); + + call_object(tables->context_switch_handler, t, "context_switch"); + + Py_DECREF(t); + + return 0; +} + +static int python_process_call_return(struct call_return *cr, u64 *parent_db_id, + void *data) { struct db_export *dbe = data; - return db_export__call_return(dbe, cr); + return db_export__call_return(dbe, cr, parent_db_id); } static void python_process_general_event(struct perf_sample *sample, - struct perf_evsel *evsel, + struct evsel *evsel, struct addr_location *al) { PyObject *handler, *t, *dict, *callchain; @@ -1236,12 +1332,12 @@ static void python_process_event(union perf_event *event, struct perf_sample *sample, - struct perf_evsel *evsel, + struct evsel *evsel, struct addr_location *al) { struct tables *tables = &tables_global; - switch (evsel->attr.type) { + switch (evsel->core.attr.type) { case PERF_TYPE_TRACEPOINT: python_process_tracepoint(sample, evsel, al); break; @@ -1254,12 +1350,22 @@ } } +static void python_process_switch(union perf_event *event, + struct perf_sample *sample, + struct machine *machine) +{ + struct tables *tables = &tables_global; + + if (tables->db_export_mode) + db_export__switch(&tables->dbe, event, sample, machine); +} + static void get_handler_name(char *str, size_t size, - struct perf_evsel *evsel) + struct evsel *evsel) { char *p = str; - scnprintf(str, size, "stat__%s", perf_evsel__name(evsel)); + scnprintf(str, size, "stat__%s", evsel__name(evsel)); while ((p = strchr(p, ':'))) { *p = '_'; @@ -1268,7 +1374,7 @@ } static void -process_stat(struct perf_evsel *counter, int cpu, int thread, u64 tstamp, +process_stat(struct evsel *counter, int cpu, int thread, u64 tstamp, struct perf_counts_values *count) { PyObject *handler, *t; @@ -1305,10 +1411,10 @@ } static void python_process_stat(struct perf_stat_config *config, - struct perf_evsel *counter, u64 tstamp) + struct evsel *counter, u64 tstamp) { - struct thread_map *threads = counter->threads; - struct cpu_map *cpus = counter->cpus; + struct perf_thread_map *threads = counter->core.threads; + struct perf_cpu_map *cpus = counter->core.cpus; int cpu, thread; if (config->aggr_mode == AGGR_GLOBAL) { @@ -1320,7 +1426,7 @@ for (thread = 0; thread < threads->nr; thread++) { for (cpu = 0; cpu < cpus->nr; cpu++) { process_stat(counter, cpus->map[cpu], - thread_map__pid(threads, thread), tstamp, + perf_thread_map__pid(threads, thread), tstamp, perf_counts(counter->counts, cpu, thread)); } } @@ -1469,6 +1575,15 @@ SET_TABLE_HANDLER(sample); SET_TABLE_HANDLER(call_path); SET_TABLE_HANDLER(call_return); + SET_TABLE_HANDLER(context_switch); + + /* + * Synthesized events are samples but with architecture-specific data + * stored in sample->raw_data. They are exported via + * python_export_sample() and consequently do not need a separate export + * callback. + */ + tables->synth_handler = get_handler("synth_data"); } #if PY_MAJOR_VERSION < 3 @@ -1567,9 +1682,7 @@ static int python_flush_script(void) { - struct tables *tables = &tables_global; - - return db_export__flush(&tables->dbe); + return 0; } /* @@ -1592,10 +1705,11 @@ static int python_generate_script(struct tep_handle *pevent, const char *outfile) { - struct event_format *event = NULL; - struct format_field *f; + int i, not_first, count, nr_events; + struct tep_event **all_events; + struct tep_event *event = NULL; + struct tep_format_field *f; char fname[PATH_MAX]; - int not_first, count; FILE *ofp; sprintf(fname, "%s.py", outfile); @@ -1640,7 +1754,11 @@ fprintf(ofp, "def trace_end():\n"); fprintf(ofp, "\tprint(\"in trace_end\")\n\n"); - while ((event = trace_find_next_event(pevent, event))) { + nr_events = tep_get_events_count(pevent); + all_events = tep_list_events(pevent, TEP_EVENT_SORT_ID); + + for (i = 0; all_events && i < nr_events; i++) { + event = all_events[i]; fprintf(ofp, "def %s__%s(", event->system, event->name); fprintf(ofp, "event_name, "); fprintf(ofp, "context, "); @@ -1688,12 +1806,12 @@ count++; fprintf(ofp, "%s=", f->name); - if (f->flags & FIELD_IS_STRING || - f->flags & FIELD_IS_FLAG || - f->flags & FIELD_IS_ARRAY || - f->flags & FIELD_IS_SYMBOLIC) + if (f->flags & TEP_FIELD_IS_STRING || + f->flags & TEP_FIELD_IS_FLAG || + f->flags & TEP_FIELD_IS_ARRAY || + f->flags & TEP_FIELD_IS_SYMBOLIC) fprintf(ofp, "%%s"); - else if (f->flags & FIELD_IS_SIGNED) + else if (f->flags & TEP_FIELD_IS_SIGNED) fprintf(ofp, "%%d"); else fprintf(ofp, "%%u"); @@ -1711,7 +1829,7 @@ if (++count % 5 == 0) fprintf(ofp, "\n\t\t"); - if (f->flags & FIELD_IS_FLAG) { + if (f->flags & TEP_FIELD_IS_FLAG) { if ((count - 1) % 5 != 0) { fprintf(ofp, "\n\t\t"); count = 4; @@ -1721,7 +1839,7 @@ event->name); fprintf(ofp, "\"%s\", %s)", f->name, f->name); - } else if (f->flags & FIELD_IS_SYMBOLIC) { + } else if (f->flags & TEP_FIELD_IS_SYMBOLIC) { if ((count - 1) % 5 != 0) { fprintf(ofp, "\n\t\t"); count = 4; @@ -1778,6 +1896,7 @@ .flush_script = python_flush_script, .stop_script = python_stop_script, .process_event = python_process_event, + .process_switch = python_process_switch, .process_stat = python_process_stat, .process_stat_interval = python_process_stat_interval, .generate_script = python_generate_script, -- Gitblit v1.6.2