summaryrefslogtreecommitdiffstats
path: root/meta/recipes-kernel/lttng/lttng-tools/87250ba19aec78f36e301494a03f5678fcb6fbb4.patch
diff options
context:
space:
mode:
authorRichard Purdie <richard.purdie@linuxfoundation.org>2021-12-13 22:59:23 +0000
committerRichard Purdie <richard.purdie@linuxfoundation.org>2021-12-14 22:46:38 +0000
commit7edb45c15c39e0aea8a7c5708dd6141b456a0a2e (patch)
treea130f0c11a3ae548fb21682f713647409f517d36 /meta/recipes-kernel/lttng/lttng-tools/87250ba19aec78f36e301494a03f5678fcb6fbb4.patch
parent878fbbe0e1c142bfd844fa1db475d65cef2121c3 (diff)
downloadpoky-7edb45c15c39e0aea8a7c5708dd6141b456a0a2e.tar.gz
lttng-tools: Backport ptest fix
Add a backport and a dependency from upstream to help address one of the lttng-tools ptest relayd hangs we've been seeing on the autobuilder. (From OE-Core rev: c8f845a8f391fa5f3f69a987b3977abdb4959db8) Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'meta/recipes-kernel/lttng/lttng-tools/87250ba19aec78f36e301494a03f5678fcb6fbb4.patch')
-rw-r--r--meta/recipes-kernel/lttng/lttng-tools/87250ba19aec78f36e301494a03f5678fcb6fbb4.patch218
1 files changed, 218 insertions, 0 deletions
diff --git a/meta/recipes-kernel/lttng/lttng-tools/87250ba19aec78f36e301494a03f5678fcb6fbb4.patch b/meta/recipes-kernel/lttng/lttng-tools/87250ba19aec78f36e301494a03f5678fcb6fbb4.patch
new file mode 100644
index 0000000000..f4db4f86fe
--- /dev/null
+++ b/meta/recipes-kernel/lttng/lttng-tools/87250ba19aec78f36e301494a03f5678fcb6fbb4.patch
@@ -0,0 +1,218 @@
1Upstream-Status: Backport
2
3From 87250ba19aec78f36e301494a03f5678fcb6fbb4 Mon Sep 17 00:00:00 2001
4From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20Galarneau?=
5 <jeremie.galarneau@efficios.com>
6Date: Mon, 1 Nov 2021 15:43:55 -0400
7Subject: [PATCH] Fix: relayd: live: mishandled initial null trace chunk
8MIME-Version: 1.0
9Content-Type: text/plain; charset=UTF-8
10Content-Transfer-Encoding: 8bit
11
12Observed issue
13==============
14
15As reported in #1323 (https://bugs.lttng.org/issues/1323), crashes of
16the relay daemon are observed when running the user space clear tests.
17
18The crash occurs with the following stack trace:
19 #0 0x000055fbb861d6ae in urcu_ref_get_unless_zero (ref=0x28) at /usr/local/include/urcu/ref.h:85
20 #1 lttng_trace_chunk_get (chunk=0x0) at trace-chunk.c:1836
21 #2 0x000055fbb86051e2 in make_viewer_streams (relay_session=relay_session@entry=0x7f6ea002d540, viewer_session=<optimized out>, seek_t=seek_t@entry=LTTNG_VIEWER_SEEK_BEGINNING, nb_total=nb_total@entry=0x7f6ea9607b00, nb_unsent=nb_unsent@entry=0x7f6ea9607aec, nb_created=nb_created@entry=0x7f6ea9607ae8, closed=<optimized out>) at live.c:405
22 #3 0x000055fbb86061d9 in viewer_get_new_streams (conn=0x7f6e94000fc0) at live.c:1155
23 #4 process_control (conn=0x7f6e94000fc0, recv_hdr=0x7f6ea9607af0) at live.c:2353
24 #5 thread_worker (data=<optimized out>) at live.c:2515
25 #6 0x00007f6eae86a609 in start_thread () from /lib/x86_64-linux-gnu/libpthread.so.0
26 #7 0x00007f6eae78f293 in clone () from /lib/x86_64-linux-gnu/libc.so.6
27
28The race window during which this occurs seems very small as it can take
29hours to reproduce this crash. However, a minimal reproducer could be
30identified, as stated in the bug report.
31
32Essentially, the same crash can be reproduced by attaching a live viewer
33to a session that has seen events being produced, been stopped and been
34cleared.
35
36Cause
37=====
38
39The crash occurs as an attempt is made to take a reference to a viewer
40session’s trace chunk as viewer streams are created. The crux of the
41problem is that the code doesn’t expect a viewer session’s trace chunk
42to be NULL.
43
44The viewer session’s current trace chunk is initially set, when a viewer
45attaches to the viewer session, to a copy the corresponding
46relay_session’s current trace chunk.
47
48A live session always attempts to "catch-up" to the newest available
49trace chunk. This means that when a viewer reaches the end of a trace
50chunk, the viewer session may not transition to the "next" one: it jumps
51to the most recent trace chunk available (the one being produced by the
52relay_session). Hence, if the producer performs multiple rotations
53before a viewer completes the consumption of a trace chunk, it will skip
54over those "intermediary" trace chunks.
55
56A viewer session updates its current trace chunk when:
57 1) new viewer streams are created,
58 2) a new index is requested,
59 3) metadata is requested.
60
61Hence, as a general principle, the viewer session will reference the
62most recent trace chunk available _even if its streams do not point to
63it_. It indicates which trace chunk viewer streams should transition to
64when the end of their current trace chunk is reached.
65
66The live code properly handles transitions to a null chunk. This can be
67verified by attaching a viewer to a live session, stopping the session,
68clearing it (thus entering a null trace chunk), and resuming tracing.
69
70The only issue is that the case where the first trace chunk of a viewer
71session is "null" (no active trace chunk) is mishandled in two places:
72 1) in make_viewer_streams(), where the crash is observed,
73 2) in viewer_get_metadata().
74
75Solution
76========
77
78In make_viewer_streams(), it is assumed that a viewer session will have
79a non-null trace chunk whenever a rotation is not ongoing. This is
80reflected by the fact that a reference is always acquired on the viewer
81session’s trace chunk.
82
83That code is one of the three places that can cause a viewer session’s
84trace chunk to be updated. We still want to update the viewer session to
85the most recently seen trace chunk (null, in this case). However, there
86is no reference to acquire and the trace chunk to use for the creation
87of the viewer stream is NULL. This is properly handled by
88viewer_stream_create().
89
90The second site to change is viewer_get_metadata() which doesn’t handle
91a viewer metadata stream not having an active trace chunk at all.
92Thankfully, the protocol allows us to express this condition by
93returning the LTTNG_VIEWER_NO_NEW_METADATA status code when a viewer
94metadata stream doesn’t have an open file and doesn’t have a current
95trace chunk.
96
97Surprisingly, this bug didn’t trigger in the case where a transition to
98a null chunk occurred _after_ attaching to a viewer session.
99
100This is because viewers will typically ask for metadata as a result of an
101LTTNG_VIEWER_FLAG_NEW_METADATA reply to the GET_NEXT_INDEX command. When
102a session is stopped and all data was consumed, this command returns
103that no new data is available, causing the viewers to wait and ask again
104later.
105
106However, when attaching, babeltrace2 (at least, and probably babeltrace 1.x)
107always asks for an initial segment of metadata before asking for an
108index.
109
110Known drawbacks
111===============
112
113None.
114
115Fixes: #1323
116
117Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
118Change-Id: I516fca60755e6897f6b7170c12d706ef57ad61a5
119---
120 src/bin/lttng-relayd/live.c | 47 ++++++++++++++++++++++++-----------
121 src/bin/lttng-relayd/stream.h | 5 ++++
122 2 files changed, 38 insertions(+), 14 deletions(-)
123
124Index: lttng-tools-2.13.1/src/bin/lttng-relayd/live.c
125===================================================================
126--- lttng-tools-2.13.1.orig/src/bin/lttng-relayd/live.c
127+++ lttng-tools-2.13.1/src/bin/lttng-relayd/live.c
128@@ -384,8 +384,6 @@ static int make_viewer_streams(struct re
129 goto error_unlock;
130 }
131 } else {
132- bool reference_acquired;
133-
134 /*
135 * Transition the viewer session into the newest trace chunk available.
136 */
137@@ -402,11 +400,26 @@ static int make_viewer_streams(struct re
138 }
139 }
140
141- reference_acquired = lttng_trace_chunk_get(
142- viewer_session->current_trace_chunk);
143- assert(reference_acquired);
144- viewer_stream_trace_chunk =
145- viewer_session->current_trace_chunk;
146+ if (relay_stream->trace_chunk) {
147+ /*
148+ * If the corresponding relay
149+ * stream's trace chunk is set,
150+ * the viewer stream will be
151+ * created under it.
152+ *
153+ * Note that a relay stream can
154+ * have a NULL output trace
155+ * chunk (for instance, after a
156+ * clear against a stopped
157+ * session).
158+ */
159+ const bool reference_acquired = lttng_trace_chunk_get(
160+ viewer_session->current_trace_chunk);
161+
162+ assert(reference_acquired);
163+ viewer_stream_trace_chunk =
164+ viewer_session->current_trace_chunk;
165+ }
166 }
167
168 viewer_stream = viewer_stream_create(
169@@ -2016,8 +2029,9 @@ int viewer_get_metadata(struct relay_con
170 }
171 }
172
173- if (conn->viewer_session->current_trace_chunk !=
174- vstream->stream_file.trace_chunk) {
175+ if (conn->viewer_session->current_trace_chunk &&
176+ conn->viewer_session->current_trace_chunk !=
177+ vstream->stream_file.trace_chunk) {
178 bool acquired_reference;
179
180 DBG("Viewer session and viewer stream chunk differ: "
181@@ -2034,11 +2048,16 @@ int viewer_get_metadata(struct relay_con
182
183 len = vstream->stream->metadata_received - vstream->metadata_sent;
184
185- /*
186- * Either this is the first time the metadata file is read, or a
187- * rotation of the corresponding relay stream has occurred.
188- */
189- if (!vstream->stream_file.handle && len > 0) {
190+ if (!vstream->stream_file.trace_chunk) {
191+ reply.status = htobe32(LTTNG_VIEWER_NO_NEW_METADATA);
192+ len = 0;
193+ goto send_reply;
194+ } else if (vstream->stream_file.trace_chunk &&
195+ !vstream->stream_file.handle && len > 0) {
196+ /*
197+ * Either this is the first time the metadata file is read, or a
198+ * rotation of the corresponding relay stream has occurred.
199+ */
200 struct fs_handle *fs_handle;
201 char file_path[LTTNG_PATH_MAX];
202 enum lttng_trace_chunk_status status;
203Index: lttng-tools-2.13.1/src/bin/lttng-relayd/stream.h
204===================================================================
205--- lttng-tools-2.13.1.orig/src/bin/lttng-relayd/stream.h
206+++ lttng-tools-2.13.1/src/bin/lttng-relayd/stream.h
207@@ -174,6 +174,11 @@ struct relay_stream {
208 /*
209 * The trace chunk to which the file currently being produced (if any)
210 * belongs.
211+ *
212+ * Note that a relay stream can have no output trace chunk. For
213+ * instance, after a session stop followed by a session clear,
214+ * streams will not have an output trace chunk until the session
215+ * is resumed.
216 */
217 struct lttng_trace_chunk *trace_chunk;
218 LTTNG_OPTIONAL(struct relay_stream_rotation) ongoing_rotation;