perf cs-etm: Linking PE contextID with perf thread mechanic
authorMathieu Poirier <mathieu.poirier@linaro.org>
Fri, 24 May 2019 17:35:06 +0000 (11:35 -0600)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Mon, 10 Jun 2019 18:50:02 +0000 (15:50 -0300)
Link contextID packets received from the decoder with the perf tool
thread mechanic so that we know the specifics of the process currently
executing.

Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
Tested-by: Leo Yan <leo.yan@linaro.org>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Suzuki Poulouse <suzuki.poulose@arm.com>
Cc: coresight@lists.linaro.org
Cc: linux-arm-kernel@lists.infradead.org
Link: http://lkml.kernel.org/r/20190524173508.29044-16-mathieu.poirier@linaro.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
tools/perf/util/cs-etm-decoder/cs-etm-decoder.c
tools/perf/util/cs-etm.c
tools/perf/util/cs-etm.h

index 87264b7..ce85e52 100644 (file)
@@ -402,6 +402,24 @@ cs_etm_decoder__buffer_exception_ret(struct cs_etm_packet_queue *queue,
                                             CS_ETM_EXCEPTION_RET);
 }
 
+static ocsd_datapath_resp_t
+cs_etm_decoder__set_tid(struct cs_etm_queue *etmq,
+                       const ocsd_generic_trace_elem *elem,
+                       const uint8_t trace_chan_id)
+{
+       pid_t tid;
+
+       /* Ignore PE_CONTEXT packets that don't have a valid contextID */
+       if (!elem->context.ctxt_id_valid)
+               return OCSD_RESP_CONT;
+
+       tid =  elem->context.context_id;
+       if (cs_etm__etmq_set_tid(etmq, tid, trace_chan_id))
+               return OCSD_RESP_FATAL_SYS_ERR;
+
+       return OCSD_RESP_CONT;
+}
+
 static ocsd_datapath_resp_t cs_etm_decoder__gen_trace_elem_printer(
                                const void *context,
                                const ocsd_trc_index_t indx __maybe_unused,
@@ -440,6 +458,8 @@ static ocsd_datapath_resp_t cs_etm_decoder__gen_trace_elem_printer(
                                                            trace_chan_id);
                break;
        case OCSD_GEN_TRC_ELEM_PE_CONTEXT:
+               resp = cs_etm_decoder__set_tid(etmq, elem, trace_chan_id);
+               break;
        case OCSD_GEN_TRC_ELEM_ADDR_NACC:
        case OCSD_GEN_TRC_ELEM_TIMESTAMP:
        case OCSD_GEN_TRC_ELEM_CYCLE_COUNT:
index afc2491..17adf55 100644 (file)
@@ -907,13 +907,8 @@ cs_etm__get_trace(struct cs_etm_queue *etmq)
 }
 
 static void cs_etm__set_pid_tid_cpu(struct cs_etm_auxtrace *etm,
-                                   struct auxtrace_queue *queue,
                                    struct cs_etm_traceid_queue *tidq)
 {
-       /* CPU-wide tracing isn't supported yet */
-       if (queue->tid == -1)
-               return;
-
        if ((!tidq->thread) && (tidq->tid != -1))
                tidq->thread = machine__find_thread(etm->machine, -1,
                                                    tidq->tid);
@@ -922,6 +917,31 @@ static void cs_etm__set_pid_tid_cpu(struct cs_etm_auxtrace *etm,
                tidq->pid = tidq->thread->pid_;
 }
 
+int cs_etm__etmq_set_tid(struct cs_etm_queue *etmq,
+                        pid_t tid, u8 trace_chan_id)
+{
+       int cpu, err = -EINVAL;
+       struct cs_etm_auxtrace *etm = etmq->etm;
+       struct cs_etm_traceid_queue *tidq;
+
+       tidq = cs_etm__etmq_get_traceid_queue(etmq, trace_chan_id);
+       if (!tidq)
+               return err;
+
+       if (cs_etm__get_cpu(trace_chan_id, &cpu) < 0)
+               return err;
+
+       err = machine__set_current_tid(etm->machine, cpu, tid, tid);
+       if (err)
+               return err;
+
+       tidq->tid = tid;
+       thread__zput(tidq->thread);
+
+       cs_etm__set_pid_tid_cpu(etm, tidq);
+       return 0;
+}
+
 static int cs_etm__synth_instruction_sample(struct cs_etm_queue *etmq,
                                            struct cs_etm_traceid_queue *tidq,
                                            u64 addr, u64 period)
@@ -1866,7 +1886,7 @@ static int cs_etm__process_timeless_queues(struct cs_etm_auxtrace *etm,
                        continue;
 
                if ((tid == -1) || (tidq->tid == tid)) {
-                       cs_etm__set_pid_tid_cpu(etm, queue, tidq);
+                       cs_etm__set_pid_tid_cpu(etm, tidq);
                        cs_etm__run_decoder(etmq);
                }
        }
index f16082d..b2a7628 100644 (file)
@@ -181,6 +181,8 @@ struct cs_etm_packet_queue {
 int cs_etm__process_auxtrace_info(union perf_event *event,
                                  struct perf_session *session);
 int cs_etm__get_cpu(u8 trace_chan_id, int *cpu);
+int cs_etm__etmq_set_tid(struct cs_etm_queue *etmq,
+                        pid_t tid, u8 trace_chan_id);
 struct cs_etm_packet_queue
 *cs_etm__etmq_get_packet_queue(struct cs_etm_queue *etmq, u8 trace_chan_id);
 #else
@@ -197,6 +199,14 @@ static inline int cs_etm__get_cpu(u8 trace_chan_id __maybe_unused,
        return -1;
 }
 
+static inline int cs_etm__etmq_set_tid(
+                               struct cs_etm_queue *etmq __maybe_unused,
+                               pid_t tid __maybe_unused,
+                               u8 trace_chan_id __maybe_unused)
+{
+       return -1;
+}
+
 static inline struct cs_etm_packet_queue *cs_etm__etmq_get_packet_queue(
                                struct cs_etm_queue *etmq __maybe_unused,
                                u8 trace_chan_id __maybe_unused)