]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/4.4.129/perf-intel-pt-fix-sync_switch.patch
3.18-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 4.4.129 / perf-intel-pt-fix-sync_switch.patch
CommitLineData
e45e7bed
GKH
1From 63d8e38f6ae6c36dd5b5ba0e8c112e8861532ea2 Mon Sep 17 00:00:00 2001
2From: Adrian Hunter <adrian.hunter@intel.com>
3Date: Wed, 7 Mar 2018 16:02:22 +0200
4Subject: perf intel-pt: Fix sync_switch
5
6From: Adrian Hunter <adrian.hunter@intel.com>
7
8commit 63d8e38f6ae6c36dd5b5ba0e8c112e8861532ea2 upstream.
9
10sync_switch is a facility to synchronize decoding more closely with the
11point in the kernel when the context actually switched.
12
13The flag when sync_switch is enabled was global to the decoding, whereas
14it is really specific to the CPU.
15
16The trace data for different CPUs is put on different queues, so add
17sync_switch to the intel_pt_queue structure and use that in preference
18to the global setting in the intel_pt structure.
19
20That fixes problems decoding one CPU's trace because sync_switch was
21disabled on a different CPU's queue.
22
23Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
24Cc: Jiri Olsa <jolsa@redhat.com>
25Cc: stable@vger.kernel.org
26Link: http://lkml.kernel.org/r/1520431349-30689-3-git-send-email-adrian.hunter@intel.com
27Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
28Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
29
30---
31 tools/perf/util/intel-pt.c | 32 +++++++++++++++++++++++++-------
32 1 file changed, 25 insertions(+), 7 deletions(-)
33
34--- a/tools/perf/util/intel-pt.c
35+++ b/tools/perf/util/intel-pt.c
36@@ -125,6 +125,7 @@ struct intel_pt_queue {
37 bool stop;
38 bool step_through_buffers;
39 bool use_buffer_pid_tid;
40+ bool sync_switch;
41 pid_t pid, tid;
42 int cpu;
43 int switch_state;
44@@ -852,10 +853,12 @@ static int intel_pt_setup_queue(struct i
45 if (pt->timeless_decoding || !pt->have_sched_switch)
46 ptq->use_buffer_pid_tid = true;
47 }
48+
49+ ptq->sync_switch = pt->sync_switch;
50 }
51
52 if (!ptq->on_heap &&
53- (!pt->sync_switch ||
54+ (!ptq->sync_switch ||
55 ptq->switch_state != INTEL_PT_SS_EXPECTING_SWITCH_EVENT)) {
56 const struct intel_pt_state *state;
57 int ret;
58@@ -1238,7 +1241,7 @@ static int intel_pt_sample(struct intel_
59 if (pt->synth_opts.last_branch)
60 intel_pt_update_last_branch_rb(ptq);
61
62- if (!pt->sync_switch)
63+ if (!ptq->sync_switch)
64 return 0;
65
66 if (intel_pt_is_switch_ip(ptq, state->to_ip)) {
67@@ -1319,6 +1322,21 @@ static u64 intel_pt_switch_ip(struct int
68 return switch_ip;
69 }
70
71+static void intel_pt_enable_sync_switch(struct intel_pt *pt)
72+{
73+ unsigned int i;
74+
75+ pt->sync_switch = true;
76+
77+ for (i = 0; i < pt->queues.nr_queues; i++) {
78+ struct auxtrace_queue *queue = &pt->queues.queue_array[i];
79+ struct intel_pt_queue *ptq = queue->priv;
80+
81+ if (ptq)
82+ ptq->sync_switch = true;
83+ }
84+}
85+
86 static int intel_pt_run_decoder(struct intel_pt_queue *ptq, u64 *timestamp)
87 {
88 const struct intel_pt_state *state = ptq->state;
89@@ -1335,7 +1353,7 @@ static int intel_pt_run_decoder(struct i
90 if (pt->switch_ip) {
91 intel_pt_log("switch_ip: %"PRIx64" ptss_ip: %"PRIx64"\n",
92 pt->switch_ip, pt->ptss_ip);
93- pt->sync_switch = true;
94+ intel_pt_enable_sync_switch(pt);
95 }
96 }
97 }
98@@ -1351,9 +1369,9 @@ static int intel_pt_run_decoder(struct i
99 if (state->err) {
100 if (state->err == INTEL_PT_ERR_NODATA)
101 return 1;
102- if (pt->sync_switch &&
103+ if (ptq->sync_switch &&
104 state->from_ip >= pt->kernel_start) {
105- pt->sync_switch = false;
106+ ptq->sync_switch = false;
107 intel_pt_next_tid(pt, ptq);
108 }
109 if (pt->synth_opts.errors) {
110@@ -1379,7 +1397,7 @@ static int intel_pt_run_decoder(struct i
111 state->timestamp, state->est_timestamp);
112 ptq->timestamp = state->est_timestamp;
113 /* Use estimated TSC in unknown switch state */
114- } else if (pt->sync_switch &&
115+ } else if (ptq->sync_switch &&
116 ptq->switch_state == INTEL_PT_SS_UNKNOWN &&
117 intel_pt_is_switch_ip(ptq, state->to_ip) &&
118 ptq->next_tid == -1) {
119@@ -1526,7 +1544,7 @@ static int intel_pt_sync_switch(struct i
120 return 1;
121
122 ptq = intel_pt_cpu_to_ptq(pt, cpu);
123- if (!ptq)
124+ if (!ptq || !ptq->sync_switch)
125 return 1;
126
127 switch (ptq->switch_state) {