From: Adrian Hunter <adrian.hunter@intel.com>
To: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Jiri Olsa <jolsa@redhat.com>, linux-kernel@vger.kernel.org
Subject: [PATCH 19/21] perf db-export: Export switch events
Date: Wed, 10 Jul 2019 11:58:08 +0300 [thread overview]
Message-ID: <20190710085810.1650-20-adrian.hunter@intel.com> (raw)
In-Reply-To: <20190710085810.1650-1-adrian.hunter@intel.com>
Export details of switch events including the threads and their current
comms.
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
tools/perf/util/db-export.c | 89 +++++++++++++++++++
tools/perf/util/db-export.h | 8 ++
.../scripting-engines/trace-event-python.c | 41 +++++++++
3 files changed, 138 insertions(+)
diff --git a/tools/perf/util/db-export.c b/tools/perf/util/db-export.c
index 2efc08b74176..cd32147aa2a3 100644
--- a/tools/perf/util/db-export.c
+++ b/tools/perf/util/db-export.c
@@ -518,3 +518,92 @@ int db_export__call_return(struct db_export *dbe, struct call_return *cr,
return 0;
}
+
+static int db_export__pid_tid(struct db_export *dbe, struct machine *machine,
+ pid_t pid, pid_t tid, u64 *db_id,
+ struct comm **comm_ptr, bool *is_idle)
+{
+ struct thread *thread = machine__find_thread(machine, pid, tid);
+ struct thread *main_thread;
+ int err = 0;
+
+ if (!thread || !thread->comm_set)
+ goto out_put;
+
+ *is_idle = !thread->pid_ && !thread->tid;
+
+ main_thread = thread__main_thread(machine, thread);
+
+ err = db_export__threads(dbe, thread, main_thread, machine, comm_ptr);
+
+ *db_id = thread->db_id;
+
+ thread__put(main_thread);
+out_put:
+ thread__put(thread);
+
+ return err;
+}
+
+int db_export__switch(struct db_export *dbe, union perf_event *event,
+ struct perf_sample *sample, struct machine *machine)
+{
+ bool out = event->header.misc & PERF_RECORD_MISC_SWITCH_OUT;
+ bool out_preempt = out &&
+ (event->header.misc & PERF_RECORD_MISC_SWITCH_OUT_PREEMPT);
+ int flags = out | (out_preempt << 1);
+ bool is_idle_a = false, is_idle_b = false;
+ u64 th_a_id = 0, th_b_id = 0;
+ u64 comm_out_id, comm_in_id;
+ struct comm *comm_a = NULL;
+ struct comm *comm_b = NULL;
+ u64 th_out_id, th_in_id;
+ u64 db_id;
+ int err;
+
+ err = db_export__machine(dbe, machine);
+ if (err)
+ return err;
+
+ err = db_export__pid_tid(dbe, machine, sample->pid, sample->tid,
+ &th_a_id, &comm_a, &is_idle_a);
+ if (err)
+ return err;
+
+ if (event->header.type == PERF_RECORD_SWITCH_CPU_WIDE) {
+ pid_t pid = event->context_switch.next_prev_pid;
+ pid_t tid = event->context_switch.next_prev_tid;
+
+ err = db_export__pid_tid(dbe, machine, pid, tid, &th_b_id,
+ &comm_b, &is_idle_b);
+ if (err)
+ return err;
+ }
+
+ /*
+ * Do not export if both threads are unknown (i.e. not being traced),
+ * or one is unknown and the other is the idle task.
+ */
+ if ((!th_a_id || is_idle_a) && (!th_b_id || is_idle_b))
+ return 0;
+
+ db_id = ++dbe->context_switch_last_db_id;
+
+ if (out) {
+ th_out_id = th_a_id;
+ th_in_id = th_b_id;
+ comm_out_id = comm_a ? comm_a->db_id : 0;
+ comm_in_id = comm_b ? comm_b->db_id : 0;
+ } else {
+ th_out_id = th_b_id;
+ th_in_id = th_a_id;
+ comm_out_id = comm_b ? comm_b->db_id : 0;
+ comm_in_id = comm_a ? comm_a->db_id : 0;
+ }
+
+ if (dbe->export_context_switch)
+ return dbe->export_context_switch(dbe, db_id, machine, sample,
+ th_out_id, comm_out_id,
+ th_in_id, comm_in_id, flags);
+ return 0;
+}
diff --git a/tools/perf/util/db-export.h b/tools/perf/util/db-export.h
index f5f0865f07e1..ba1f62a5fe10 100644
--- a/tools/perf/util/db-export.h
+++ b/tools/perf/util/db-export.h
@@ -57,6 +57,11 @@ struct db_export {
int (*export_call_path)(struct db_export *dbe, struct call_path *cp);
int (*export_call_return)(struct db_export *dbe,
struct call_return *cr);
+ int (*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 call_return_processor *crp;
struct call_path_root *cpr;
u64 evsel_last_db_id;
@@ -69,6 +74,7 @@ struct db_export {
u64 sample_last_db_id;
u64 call_path_last_db_id;
u64 call_return_last_db_id;
+ u64 context_switch_last_db_id;
};
int db_export__init(struct db_export *dbe);
@@ -98,5 +104,7 @@ int db_export__branch_types(struct db_export *dbe);
int db_export__call_path(struct db_export *dbe, struct call_path *cp);
int db_export__call_return(struct db_export *dbe, struct call_return *cr,
u64 *parent_db_id);
+int db_export__switch(struct db_export *dbe, union perf_event *event,
+ struct perf_sample *sample, struct machine *machine);
#endif
diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c
index 28167e938cef..25dc1d765553 100644
--- a/tools/perf/util/scripting-engines/trace-event-python.c
+++ b/tools/perf/util/scripting-engines/trace-event-python.c
@@ -113,6 +113,7 @@ struct tables {
PyObject *call_path_handler;
PyObject *call_return_handler;
PyObject *synth_handler;
+ PyObject *context_switch_handler;
bool db_export_mode;
};
@@ -1237,6 +1238,34 @@ static int python_export_call_return(struct db_export *dbe,
return 0;
}
+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_u64(t, 0, db_id);
+ tuple_set_u64(t, 1, machine->db_id);
+ tuple_set_u64(t, 2, sample->time);
+ tuple_set_s32(t, 3, sample->cpu);
+ tuple_set_u64(t, 4, th_out_id);
+ tuple_set_u64(t, 5, comm_out_id);
+ tuple_set_u64(t, 6, th_in_id);
+ tuple_set_u64(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)
{
@@ -1300,6 +1329,16 @@ static void python_process_event(union perf_event *event,
}
}
+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)
{
@@ -1515,6 +1554,7 @@ static void set_table_handlers(struct tables *tables)
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
@@ -1833,6 +1873,7 @@ struct scripting_ops python_scripting_ops = {
.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,
--
2.17.1
next prev parent reply other threads:[~2019-07-10 8:59 UTC|newest]
Thread overview: 43+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-07-10 8:57 [PATCH 00/21] perf db-export: Comm tidy-up and export switch events Adrian Hunter
2019-07-10 8:57 ` [PATCH 01/21] perf db-export: Get rid of db_export__deferred() Adrian Hunter
2019-07-17 22:51 ` [tip:perf/urgent] " tip-bot for Adrian Hunter
2019-07-10 8:57 ` [PATCH 02/21] perf db-export: Rename db_export__comm() to db_export__exec_comm() Adrian Hunter
2019-07-17 22:52 ` [tip:perf/urgent] " tip-bot for Adrian Hunter
2019-07-10 8:57 ` [PATCH 03/21] perf db-export: Pass main_thread to db_export__thread() Adrian Hunter
2019-07-17 22:52 ` [tip:perf/urgent] " tip-bot for Adrian Hunter
2019-07-10 8:57 ` [PATCH 04/21] perf db-export: Export main_thread in db_export__sample() Adrian Hunter
2019-07-17 22:53 ` [tip:perf/urgent] " tip-bot for Adrian Hunter
2019-07-10 8:57 ` [PATCH 05/21] perf db-export: Export comm before exporting thread Adrian Hunter
2019-07-17 22:54 ` [tip:perf/urgent] " tip-bot for Adrian Hunter
2019-07-10 8:57 ` [PATCH 06/21] perf db-export: Move export__comm_thread into db_export__sample() Adrian Hunter
2019-07-17 22:54 ` [tip:perf/urgent] " tip-bot for Adrian Hunter
2019-07-10 8:57 ` [PATCH 07/21] perf db-export: Fix a white space issue in db_export__sample() Adrian Hunter
2019-07-17 22:55 ` [tip:perf/urgent] " tip-bot for Adrian Hunter
2019-07-10 8:57 ` [PATCH 08/21] perf db-export: Export comm details Adrian Hunter
2019-07-17 22:56 ` [tip:perf/urgent] " tip-bot for Adrian Hunter
2019-07-10 8:57 ` [PATCH 09/21] perf scripts python: export-to-sqlite.py: " Adrian Hunter
2019-07-17 22:56 ` [tip:perf/urgent] " tip-bot for Adrian Hunter
2019-07-10 8:57 ` [PATCH 10/21] perf scripts python: export-to-postgresql.py: " Adrian Hunter
2019-07-17 22:57 ` [tip:perf/urgent] " tip-bot for Adrian Hunter
2019-07-10 8:58 ` [PATCH 11/21] perf db-export: Factor out db_export__comm() Adrian Hunter
2019-07-17 22:58 ` [tip:perf/urgent] " tip-bot for Adrian Hunter
2019-07-10 8:58 ` [PATCH 12/21] perf db-export: Also export thread's current comm Adrian Hunter
2019-07-17 22:59 ` [tip:perf/urgent] " tip-bot for Adrian Hunter
2019-07-10 8:58 ` [PATCH 13/21] perf scripts python: export-to-sqlite.py: Add has_calls column to comms table Adrian Hunter
2019-07-17 22:59 ` [tip:perf/urgent] " tip-bot for Adrian Hunter
2019-07-10 8:58 ` [PATCH 14/21] perf scripts python: export-to-postgresql.py: " Adrian Hunter
2019-07-17 23:00 ` [tip:perf/urgent] " tip-bot for Adrian Hunter
2019-07-10 8:58 ` [PATCH 15/21] perf scripts python: exported-sql-viewer.py: Remove redundant semi-colons Adrian Hunter
2019-07-17 23:01 ` [tip:perf/urgent] " tip-bot for Adrian Hunter
2019-07-10 8:58 ` [PATCH 16/21] perf scripts python: exported-sql-viewer.py: Use new 'has_calls' column Adrian Hunter
2019-07-17 23:01 ` [tip:perf/urgent] " tip-bot for Adrian Hunter
2019-07-10 8:58 ` [PATCH 17/21] perf script: Add scripting operation process_switch() Adrian Hunter
2019-07-17 23:02 ` [tip:perf/urgent] " tip-bot for Adrian Hunter
2019-07-10 8:58 ` [PATCH 18/21] perf db-export: Factor out db_export__threads() Adrian Hunter
2019-07-17 23:03 ` [tip:perf/urgent] " tip-bot for Adrian Hunter
2019-07-10 8:58 ` Adrian Hunter [this message]
2019-07-17 23:04 ` [tip:perf/urgent] perf db-export: Export switch events tip-bot for Adrian Hunter
2019-07-10 8:58 ` [PATCH 20/21] perf scripts python: export-to-sqlite.py: " Adrian Hunter
2019-07-17 23:04 ` [tip:perf/urgent] " tip-bot for Adrian Hunter
2019-07-10 8:58 ` [PATCH 21/21] perf scripts python: export-to-postgresql.py: " Adrian Hunter
2019-07-17 23:05 ` [tip:perf/urgent] " tip-bot for Adrian Hunter
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20190710085810.1650-20-adrian.hunter@intel.com \
--to=adrian.hunter@intel.com \
--cc=acme@kernel.org \
--cc=jolsa@redhat.com \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.