* [PATCH 1/2] tracing: Store trace_marker_raw payload length in events
@ 2026-04-08 15:32 Cao Ruichuang
2026-04-08 15:32 ` [PATCH 2/2] selftests/ftrace: Check exact trace_marker_raw payload lengths Cao Ruichuang
2026-04-08 17:39 ` [PATCH 1/2] tracing: Store trace_marker_raw payload length in events Steven Rostedt
0 siblings, 2 replies; 4+ messages in thread
From: Cao Ruichuang @ 2026-04-08 15:32 UTC (permalink / raw)
To: rostedt, mhiramat, mathieu.desnoyers, shuah
Cc: linux-kernel, linux-trace-kernel, linux-kselftest
trace_marker_raw currently records its bytes in TRACE_RAW_DATA events,
but the event output path derives the byte count from the padded record
size in the ring buffer. As a result, the printed raw-data payload is
rounded up and small writes do not preserve their true length.
Keep the true payload length in the TRACE_RAW_DATA event itself and use
that field when printing the bytes. This leaves the ring buffer record
size semantics unchanged while letting trace_marker_raw report the exact
payload that was written.
Signed-off-by: Cao Ruichuang <create0818@163.com>
---
kernel/trace/trace.c | 11 ++++++-----
kernel/trace/trace_entries.h | 1 +
kernel/trace/trace_output.c | 4 ++--
3 files changed, 9 insertions(+), 7 deletions(-)
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index a626211ce..d9cb643b8 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -6906,11 +6906,13 @@ static ssize_t write_raw_marker_to_buffer(struct trace_array *tr,
struct ring_buffer_event *event;
struct trace_buffer *buffer;
struct raw_data_entry *entry;
+ size_t payload_len;
ssize_t written;
size_t size;
/* cnt includes both the entry->id and the data behind it. */
- size = struct_offset(entry, id) + cnt;
+ payload_len = cnt - sizeof(entry->id);
+ size = struct_offset(entry, buf) + payload_len;
buffer = tr->array_buffer.buffer;
@@ -6924,10 +6926,9 @@ static ssize_t write_raw_marker_to_buffer(struct trace_array *tr,
return -EBADF;
entry = ring_buffer_event_data(event);
- unsafe_memcpy(&entry->id, buf, cnt,
- "id and content already reserved on ring buffer"
- "'buf' includes the 'id' and the data."
- "'entry' was allocated with cnt from 'id'.");
+ memcpy(&entry->id, buf, sizeof(entry->id));
+ entry->len = payload_len;
+ memcpy(entry->buf, buf + sizeof(entry->id), payload_len);
written = cnt;
__buffer_unlock_commit(buffer, event);
diff --git a/kernel/trace/trace_entries.h b/kernel/trace/trace_entries.h
index 54417468f..5f867a144 100644
--- a/kernel/trace/trace_entries.h
+++ b/kernel/trace/trace_entries.h
@@ -288,6 +288,7 @@ FTRACE_ENTRY(raw_data, raw_data_entry,
F_STRUCT(
__field( unsigned int, id )
+ __field(unsigned int, len)
__dynamic_array( char, buf )
),
diff --git a/kernel/trace/trace_output.c b/kernel/trace/trace_output.c
index 1996d7aba..4e1edfa05 100644
--- a/kernel/trace/trace_output.c
+++ b/kernel/trace/trace_output.c
@@ -1817,13 +1817,13 @@ static enum print_line_t trace_raw_data(struct trace_iterator *iter, int flags,
struct trace_event *event)
{
struct raw_data_entry *field;
- int i;
+ unsigned int i;
trace_assign_type(field, iter->ent);
trace_seq_printf(&iter->seq, "# %x buf:", field->id);
- for (i = 0; i < iter->ent_size - offsetof(struct raw_data_entry, buf); i++)
+ for (i = 0; i < field->len; i++)
trace_seq_printf(&iter->seq, " %02x",
(unsigned char)field->buf[i]);
--
2.39.5 (Apple Git-154)
^ permalink raw reply related [flat|nested] 4+ messages in thread* [PATCH 2/2] selftests/ftrace: Check exact trace_marker_raw payload lengths
2026-04-08 15:32 [PATCH 1/2] tracing: Store trace_marker_raw payload length in events Cao Ruichuang
@ 2026-04-08 15:32 ` Cao Ruichuang
2026-04-08 17:39 ` [PATCH 1/2] tracing: Store trace_marker_raw payload length in events Steven Rostedt
1 sibling, 0 replies; 4+ messages in thread
From: Cao Ruichuang @ 2026-04-08 15:32 UTC (permalink / raw)
To: rostedt, mhiramat, mathieu.desnoyers, shuah
Cc: linux-kernel, linux-trace-kernel, linux-kselftest
trace_marker_raw.tc currently depends on awk strtonum() and assumes
that the printed raw-data byte count is rounded up to four bytes.
Now that TRACE_RAW_DATA records keep the true payload length in the
event itself, update the testcase to validate the exact number of bytes
printed for a short sequence of writes. While doing that, make the test
portable to /bin/sh environments that use mawk by replacing strtonum()
and the lscpu endian probe with od-based checks.
Signed-off-by: Cao Ruichuang <create0818@163.com>
---
.../ftrace/test.d/00basic/trace_marker_raw.tc | 93 ++++++++++++-------
1 file changed, 59 insertions(+), 34 deletions(-)
diff --git a/tools/testing/selftests/ftrace/test.d/00basic/trace_marker_raw.tc b/tools/testing/selftests/ftrace/test.d/00basic/trace_marker_raw.tc
index a2c42e13f..3b37890f8 100644
--- a/tools/testing/selftests/ftrace/test.d/00basic/trace_marker_raw.tc
+++ b/tools/testing/selftests/ftrace/test.d/00basic/trace_marker_raw.tc
@@ -1,11 +1,11 @@
#!/bin/sh
# SPDX-License-Identifier: GPL-2.0
# description: Basic tests on writing to trace_marker_raw
-# requires: trace_marker_raw
+# requires: trace_marker_raw od:program
# flags: instance
is_little_endian() {
- if lscpu | grep -q 'Little Endian'; then
+ if [ "$(printf '\001\000\000\000' | od -An -tu4 | tr -d '[:space:]')" = "1" ]; then
echo 1;
else
echo 0;
@@ -34,7 +34,7 @@ make_str() {
data=`printf -- 'X%.0s' $(seq $cnt)`
- printf "${val}${data}"
+ printf "%b%s" "${val}" "${data}"
}
write_buffer() {
@@ -47,36 +47,68 @@ write_buffer() {
test_multiple_writes() {
+ out_file=$TMPDIR/trace_marker_raw.out
+ match_file=$TMPDIR/trace_marker_raw.lines
+ wait_iter=0
+ pause_on_trace=
+
+ if [ -f options/pause-on-trace ]; then
+ pause_on_trace=`cat options/pause-on-trace`
+ echo 0 > options/pause-on-trace
+ fi
+
+ : > trace
+ cat trace_pipe > $out_file &
+ reader_pid=$!
+ sleep 1
+
+ # Write sizes that cover both the short and long raw-data encodings
+ # without overflowing the trace buffer before we can verify them.
+ for i in `seq 1 12`; do
+ write_buffer 0x12345678 $i
+ done
- # Write a bunch of data where the id is the count of
- # data to write
- for i in `seq 1 10` `seq 101 110` `seq 1001 1010`; do
- write_buffer $i $i
+ while [ "`grep -c ' buf:' $out_file 2> /dev/null || true`" -lt 12 ]; do
+ wait_iter=$((wait_iter + 1))
+ if [ $wait_iter -ge 10 ]; then
+ kill $reader_pid 2> /dev/null || true
+ wait $reader_pid 2> /dev/null || true
+ if [ -n "$pause_on_trace" ]; then
+ echo $pause_on_trace > options/pause-on-trace
+ fi
+ return 1
+ fi
+ sleep 1
done
# add a little buffer
echo stop > trace_marker
+ sleep 1
+ kill $reader_pid 2> /dev/null || true
+ wait $reader_pid 2> /dev/null || true
+ if [ -n "$pause_on_trace" ]; then
+ echo $pause_on_trace > options/pause-on-trace
+ fi
- # Check to make sure the number of entries is the id (rounded up by 4)
- awk '/.*: # [0-9a-f]* / {
- print;
- cnt = -1;
- for (i = 0; i < NF; i++) {
- # The counter is after the "#" marker
- if ( $i == "#" ) {
- i++;
- cnt = strtonum("0x" $i);
- num = NF - (i + 1);
- # The number of items is always rounded up by 4
- cnt2 = int((cnt + 3) / 4) * 4;
- if (cnt2 != num) {
- exit 1;
- }
- break;
- }
- }
- }
- // { if (NR > 30) { exit 0; } } ' trace_pipe;
+ grep ' buf:' $out_file > $match_file || return 1
+ if [ "`wc -l < $match_file`" -ne 12 ]; then
+ cat $match_file
+ return 1
+ fi
+
+ # Check to make sure the number of byte values matches the id exactly.
+ for expected in `seq 1 12`; do
+ line=`sed -n "${expected}p" $match_file`
+ if [ -z "$line" ]; then
+ return 1
+ fi
+ rest=${line#* buf: }
+ set -- $rest
+ if [ "$#" -ne "$expected" ]; then
+ echo "$line"
+ return 1
+ fi
+ done
}
@@ -107,13 +139,6 @@ test_buffer() {
ORIG=`cat buffer_size_kb`
-# test_multiple_writes test needs at least 12KB buffer
-NEW_SIZE=12
-
-if [ ${ORIG} -lt ${NEW_SIZE} ]; then
- echo ${NEW_SIZE} > buffer_size_kb
-fi
-
test_buffer
if ! test_multiple_writes; then
echo ${ORIG} > buffer_size_kb
--
2.39.5 (Apple Git-154)
^ permalink raw reply related [flat|nested] 4+ messages in thread* Re: [PATCH 1/2] tracing: Store trace_marker_raw payload length in events
2026-04-08 15:32 [PATCH 1/2] tracing: Store trace_marker_raw payload length in events Cao Ruichuang
2026-04-08 15:32 ` [PATCH 2/2] selftests/ftrace: Check exact trace_marker_raw payload lengths Cao Ruichuang
@ 2026-04-08 17:39 ` Steven Rostedt
2026-04-09 5:12 ` Cao Ruichuang
1 sibling, 1 reply; 4+ messages in thread
From: Steven Rostedt @ 2026-04-08 17:39 UTC (permalink / raw)
To: Cao Ruichuang
Cc: mhiramat, mathieu.desnoyers, shuah, linux-kernel,
linux-trace-kernel, linux-kselftest
On Wed, 8 Apr 2026 23:32:40 +0800
Cao Ruichuang <create0818@163.com> wrote:
> trace_marker_raw currently records its bytes in TRACE_RAW_DATA events,
> but the event output path derives the byte count from the padded record
> size in the ring buffer. As a result, the printed raw-data payload is
> rounded up and small writes do not preserve their true length.
>
> Keep the true payload length in the TRACE_RAW_DATA event itself and use
> that field when printing the bytes. This leaves the ring buffer record
> size semantics unchanged while letting trace_marker_raw report the exact
> payload that was written.
May I ask why? The above describes what is happening but fails to
leave out the why? Why does the payload length need to be added to the
event? I mean, it's recording raw data, and the user who writes to it
already knows the length as this was made for applications to write
structures directly into the buffer. When reading back from the buffer
the structure size is the length.
Thus, why record the length? I see no reason to. The length wastes
precious space in the ring buffer when the user of trace_marker_raw
should already know its length.
-- Steve
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH 1/2] tracing: Store trace_marker_raw payload length in events
2026-04-08 17:39 ` [PATCH 1/2] tracing: Store trace_marker_raw payload length in events Steven Rostedt
@ 2026-04-09 5:12 ` Cao Ruichuang
0 siblings, 0 replies; 4+ messages in thread
From: Cao Ruichuang @ 2026-04-09 5:12 UTC (permalink / raw)
To: Steven Rostedt
Cc: mhiramat, mathieu.desnoyers, shuah, linux-kernel,
linux-trace-kernel, linux-kselftest
Hi Steven,
I looked through the current trace_marker_raw users and the expected
usage more carefully.
The existing users I found treat trace_marker_raw as a binary channel
and parse the data from raw events or trace_pipe_raw, not from the
formatted trace output. Given that, I do not see a strong requirement
for TRACE_RAW_DATA itself to carry and maintain an exact payload length
just for the text printing path.
So I agree this is not really a technical limitation in the current
implementation, but a requirement question, and the requirement does
not look strong enough here.
I'll drop this series for now and close this task on my side.
Thanks,
Cao Ruichuang
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-04-09 5:13 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-08 15:32 [PATCH 1/2] tracing: Store trace_marker_raw payload length in events Cao Ruichuang
2026-04-08 15:32 ` [PATCH 2/2] selftests/ftrace: Check exact trace_marker_raw payload lengths Cao Ruichuang
2026-04-08 17:39 ` [PATCH 1/2] tracing: Store trace_marker_raw payload length in events Steven Rostedt
2026-04-09 5:12 ` Cao Ruichuang
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox