.../ftrace/test.d/00basic/trace_marker_raw.tc | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-)
On ARM64 kernels with 64K pages, the trace_marker_raw test fails because
bash's printf builtin uses stdio buffering which splits output into
multiple small write() calls to the tracefs file. Since each individual
write is within TRACE_MARKER_MAX_SIZE (4096), they all succeed, causing
the "too big" write test to incorrectly pass.
Fix by writing through dd with iflag=fullblock to guarantee a single
atomic write() syscall to trace_marker_raw.
Fixes: 37f46601383a ("selftests/tracing: Add basic test for trace_marker_raw file")
Signed-off-by: Tianchen Ding <dtcccc@linux.alibaba.com>
---
v3:
Measure the binary length via wc -c instead of hard-coding "size + 4".
v2:
Update comment about 64K pages.
---
.../ftrace/test.d/00basic/trace_marker_raw.tc | 14 +++++++++++---
1 file changed, 11 insertions(+), 3 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 8e905d4fe6dd..f985ff391463 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
@@ -36,15 +36,23 @@ make_str() {
data=`printf -- 'X%.0s' $(seq $cnt)`
- printf "${val}${data}"
+ # Return escape-sequence text (e.g. "\003\000..."); the caller
+ # converts to binary. Shell command substitution strips NUL bytes,
+ # so the binary form cannot survive being captured into a variable.
+ printf '%s' "${val}${data}"
}
write_buffer() {
id=$1
size=$2
- # write the string into the raw marker
- make_str $id $size > trace_marker_raw
+ str=`make_str $id $size`
+ len=`printf "$str" | wc -c`
+ # Pipe through dd to ensure a single atomic write() syscall
+ # on architectures with 64K pages, where shell's printf builtin
+ # uses stdio buffering which may split the output into multiple
+ # writes.
+ printf "$str" | dd of=trace_marker_raw bs=$len iflag=fullblock
}
--
2.39.3
Shuah,
can you take this?
Reviewed-by: Steven Rostedt <rostedt@goodmis.org.
Tianchen,
for future patches, please send new versions as a separate thread and
not a reply to the thread of the previous version.
Thanks,
-- Steve
On Mon, 1 Jun 2026 10:32:51 +0800
Tianchen Ding <dtcccc@linux.alibaba.com> wrote:
> On ARM64 kernels with 64K pages, the trace_marker_raw test fails because
> bash's printf builtin uses stdio buffering which splits output into
> multiple small write() calls to the tracefs file. Since each individual
> write is within TRACE_MARKER_MAX_SIZE (4096), they all succeed, causing
> the "too big" write test to incorrectly pass.
>
> Fix by writing through dd with iflag=fullblock to guarantee a single
> atomic write() syscall to trace_marker_raw.
>
> Fixes: 37f46601383a ("selftests/tracing: Add basic test for trace_marker_raw file")
> Signed-off-by: Tianchen Ding <dtcccc@linux.alibaba.com>
> ---
> v3:
> Measure the binary length via wc -c instead of hard-coding "size + 4".
>
> v2:
> Update comment about 64K pages.
> ---
> .../ftrace/test.d/00basic/trace_marker_raw.tc | 14 +++++++++++---
> 1 file changed, 11 insertions(+), 3 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 8e905d4fe6dd..f985ff391463 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
> @@ -36,15 +36,23 @@ make_str() {
>
> data=`printf -- 'X%.0s' $(seq $cnt)`
>
> - printf "${val}${data}"
> + # Return escape-sequence text (e.g. "\003\000..."); the caller
> + # converts to binary. Shell command substitution strips NUL bytes,
> + # so the binary form cannot survive being captured into a variable.
> + printf '%s' "${val}${data}"
> }
>
> write_buffer() {
> id=$1
> size=$2
>
> - # write the string into the raw marker
> - make_str $id $size > trace_marker_raw
> + str=`make_str $id $size`
> + len=`printf "$str" | wc -c`
> + # Pipe through dd to ensure a single atomic write() syscall
> + # on architectures with 64K pages, where shell's printf builtin
> + # uses stdio buffering which may split the output into multiple
> + # writes.
> + printf "$str" | dd of=trace_marker_raw bs=$len iflag=fullblock
> }
>
>
© 2016 - 2026 Red Hat, Inc.