Merge tag 'memblock-v5.14-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rppt...
[linux-2.6-microblaze.git] / tools / perf / util / cs-etm.c
index 533f6f2..32ad92d 100644 (file)
@@ -54,6 +54,7 @@ struct cs_etm_auxtrace {
        u8 sample_instructions;
 
        int num_cpu;
+       u64 latest_kernel_timestamp;
        u32 auxtrace_type;
        u64 branches_sample_type;
        u64 branches_id;
@@ -1192,6 +1193,8 @@ static int cs_etm__synth_instruction_sample(struct cs_etm_queue *etmq,
        event->sample.header.misc = cs_etm__cpu_mode(etmq, addr);
        event->sample.header.size = sizeof(struct perf_event_header);
 
+       if (!etm->timeless_decoding)
+               sample.time = etm->latest_kernel_timestamp;
        sample.ip = addr;
        sample.pid = tidq->pid;
        sample.tid = tidq->tid;
@@ -1248,6 +1251,8 @@ static int cs_etm__synth_branch_sample(struct cs_etm_queue *etmq,
        event->sample.header.misc = cs_etm__cpu_mode(etmq, ip);
        event->sample.header.size = sizeof(struct perf_event_header);
 
+       if (!etm->timeless_decoding)
+               sample.time = etm->latest_kernel_timestamp;
        sample.ip = ip;
        sample.pid = tidq->pid;
        sample.tid = tidq->tid;
@@ -2402,6 +2407,11 @@ static int cs_etm__process_event(struct perf_session *session,
                        return err;
        }
 
+       /*
+        * Don't wait for cs_etm__flush_events() in per-thread/timeless mode to start the decode. We
+        * need the tid of the PERF_RECORD_EXIT event to assign to the synthesised samples because
+        * ETM_OPT_CTXTID is not enabled.
+        */
        if (etm->timeless_decoding &&
            event->header.type == PERF_RECORD_EXIT)
                return cs_etm__process_timeless_queues(etm,
@@ -2412,9 +2422,14 @@ static int cs_etm__process_event(struct perf_session *session,
        else if (event->header.type == PERF_RECORD_SWITCH_CPU_WIDE)
                return cs_etm__process_switch_cpu_wide(etm, event);
 
-       if (!etm->timeless_decoding &&
-           event->header.type == PERF_RECORD_AUX)
-               return cs_etm__process_queues(etm);
+       if (!etm->timeless_decoding && event->header.type == PERF_RECORD_AUX) {
+               /*
+                * Record the latest kernel timestamp available in the header
+                * for samples so that synthesised samples occur from this point
+                * onwards.
+                */
+               etm->latest_kernel_timestamp = sample_kernel_timestamp;
+       }
 
        return 0;
 }
@@ -2462,6 +2477,10 @@ static bool cs_etm__is_timeless_decoding(struct cs_etm_auxtrace *etm)
        struct evlist *evlist = etm->session->evlist;
        bool timeless_decoding = true;
 
+       /* Override timeless mode with user input from --itrace=Z */
+       if (etm->synth_opts.timeless_decoding)
+               return true;
+
        /*
         * Circle through the list of event and complain if we find one
         * with the time bit set.
@@ -2808,6 +2827,14 @@ int cs_etm__process_auxtrace_info(union perf_event *event,
        if (err)
                goto err_free_etm;
 
+       if (session->itrace_synth_opts->set) {
+               etm->synth_opts = *session->itrace_synth_opts;
+       } else {
+               itrace_synth_opts__set_default(&etm->synth_opts,
+                               session->itrace_synth_opts->default_no_sample);
+               etm->synth_opts.callchain = false;
+       }
+
        etm->session = session;
        etm->machine = &session->machines.host;
 
@@ -2852,14 +2879,6 @@ int cs_etm__process_auxtrace_info(union perf_event *event,
                return 0;
        }
 
-       if (session->itrace_synth_opts->set) {
-               etm->synth_opts = *session->itrace_synth_opts;
-       } else {
-               itrace_synth_opts__set_default(&etm->synth_opts,
-                               session->itrace_synth_opts->default_no_sample);
-               etm->synth_opts.callchain = false;
-       }
-
        err = cs_etm__synth_events(etm, session);
        if (err)
                goto err_delete_thread;