tracing: selftests: Add trace remote tests

Exercise the tracefs interface for trace remote with a set of tests to
check:

  * loading/unloading (unloading.tc)
  * reset (reset.tc)
  * size changes (buffer_size.tc)
  * consuming read (trace_pipe.tc)
  * non-consuming read (trace.tc)

Cc: Shuah Khan <skhan@linuxfoundation.org>
Cc: linux-kselftest@vger.kernel.org
Link: https://patch.msgid.link/20260309162516.2623589-16-vdonnefort@google.com
Reviewed-by: Steven Rostedt (Google) <rostedt@goodmis.org>
Signed-off-by: Vincent Donnefort <vdonnefort@google.com>
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
This commit is contained in:
Vincent Donnefort 2026-03-09 16:25:01 +00:00 committed by Steven Rostedt (Google)
parent ea908a2b79
commit 0a1b03251d
6 changed files with 498 additions and 0 deletions

View File

@ -0,0 +1,25 @@
#!/bin/sh
# SPDX-License-Identifier: GPL-2.0
# description: Test trace remote buffer size
# requires: remotes/test
. $TEST_DIR/remotes/functions
test_buffer_size()
{
echo 0 > tracing_on
assert_unloaded
echo 4096 > buffer_size_kb
echo 1 > tracing_on
assert_loaded
echo 0 > tracing_on
echo 7 > buffer_size_kb
}
if [ -z "$SOURCE_REMOTE_TEST" ]; then
set -e
setup_remote_test
test_buffer_size
fi

View File

@ -0,0 +1,88 @@
# SPDX-License-Identifier: GPL-2.0
setup_remote()
{
local name=$1
[ -e $TRACING_DIR/remotes/$name/write_event ] || exit_unresolved
cd remotes/$name/
echo 0 > tracing_on
clear_trace
echo 7 > buffer_size_kb
echo 0 > events/enable
echo 1 > events/$name/selftest/enable
echo 1 > tracing_on
}
setup_remote_test()
{
[ -d $TRACING_DIR/remotes/test/ ] || modprobe remote_test || exit_unresolved
setup_remote "test"
}
assert_loaded()
{
grep -q "(loaded)" buffer_size_kb
}
assert_unloaded()
{
grep -q "(unloaded)" buffer_size_kb
}
dump_trace_pipe()
{
output=$(mktemp $TMPDIR/remote_test.XXXXXX)
cat trace_pipe > $output &
pid=$!
sleep 1
kill -1 $pid
echo $output
}
check_trace()
{
start_id="$1"
end_id="$2"
file="$3"
# Ensure the file is not empty
test -n "$(head $file)"
prev_ts=0
id=0
# Only keep <timestamp> <id>
tmp=$(mktemp $TMPDIR/remote_test.XXXXXX)
sed -e 's/\[[0-9]*\]\s*\([0-9]*.[0-9]*\): [a-z]* id=\([0-9]*\)/\1 \2/' $file > $tmp
while IFS= read -r line; do
ts=$(echo $line | cut -d ' ' -f 1)
id=$(echo $line | cut -d ' ' -f 2)
test $(echo "$ts>$prev_ts" | bc) -eq 1
test $id -eq $start_id
prev_ts=$ts
start_id=$((start_id + 1))
done < $tmp
test $id -eq $end_id
rm $tmp
}
get_cpu_ids()
{
sed -n 's/^processor\s*:\s*\([0-9]\+\).*/\1/p' /proc/cpuinfo
}
get_page_size() {
sed -ne 's/^.*data.*size:\([0-9][0-9]*\).*/\1/p' events/header_page
}
get_selftest_event_size() {
sed -ne 's/^.*field:.*;.*size:\([0-9][0-9]*\);.*/\1/p' events/*/selftest/format | awk '{s+=$1} END {print s}'
}

View File

@ -0,0 +1,90 @@
#!/bin/sh
# SPDX-License-Identifier: GPL-2.0
# description: Test trace remote reset
# requires: remotes/test
. $TEST_DIR/remotes/functions
check_reset()
{
write_event_path="write_event"
taskset=""
clear_trace
# Is the buffer empty?
output=$(dump_trace_pipe)
test $(wc -l $output | cut -d ' ' -f1) -eq 0
if $(echo $(pwd) | grep -q "per_cpu/cpu"); then
write_event_path="../../write_event"
cpu_id=$(echo $(pwd) | sed -e 's/.*per_cpu\/cpu//')
taskset="taskset -c $cpu_id"
fi
rm $output
# Can we properly write a new event?
$taskset echo 7890 > $write_event_path
output=$(dump_trace_pipe)
test $(wc -l $output | cut -d ' ' -f1) -eq 1
grep -q "id=7890" $output
rm $output
}
test_global_interface()
{
output=$(mktemp $TMPDIR/remote_test.XXXXXX)
# Confidence check
echo 123456 > write_event
output=$(dump_trace_pipe)
grep -q "id=123456" $output
rm $output
# Reset single event
echo 1 > write_event
check_reset
# Reset lost events
for i in $(seq 1 10000); do
echo 1 > write_event
done
check_reset
}
test_percpu_interface()
{
[ "$(get_cpu_ids | wc -l)" -ge 2 ] || return 0
for cpu in $(get_cpu_ids); do
taskset -c $cpu echo 1 > write_event
done
check_non_empty=0
for cpu in $(get_cpu_ids); do
cd per_cpu/cpu$cpu/
if [ $check_non_empty -eq 0 ]; then
check_reset
check_non_empty=1
else
# Check we have only reset 1 CPU
output=$(dump_trace_pipe)
test $(wc -l $output | cut -d ' ' -f1) -eq 1
rm $output
fi
cd -
done
}
test_reset()
{
test_global_interface
test_percpu_interface
}
if [ -z "$SOURCE_REMOTE_TEST" ]; then
set -e
setup_remote_test
test_reset
fi

View File

@ -0,0 +1,127 @@
#!/bin/sh
# SPDX-License-Identifier: GPL-2.0
# description: Test trace remote non-consuming read
# requires: remotes/test
. $TEST_DIR/remotes/functions
test_trace()
{
echo 0 > tracing_on
assert_unloaded
echo 7 > buffer_size_kb
echo 1 > tracing_on
assert_loaded
# Simple test: Emit few events and try to read them
for i in $(seq 1 8); do
echo $i > write_event
done
check_trace 1 8 trace
#
# Test interaction with consuming read
#
cat trace_pipe > /dev/null &
pid=$!
sleep 1
kill $pid
test $(wc -l < trace) -eq 0
for i in $(seq 16 32); do
echo $i > write_event
done
check_trace 16 32 trace
#
# Test interaction with reset
#
echo 0 > trace
test $(wc -l < trace) -eq 0
for i in $(seq 1 8); do
echo $i > write_event
done
check_trace 1 8 trace
#
# Test interaction with lost events
#
# Ensure the writer is not on the reader page by reloading the buffer
echo 0 > tracing_on
echo 0 > trace
assert_unloaded
echo 1 > tracing_on
assert_loaded
# Ensure ring-buffer overflow by emitting events from the same CPU
for cpu in $(get_cpu_ids); do
break
done
events_per_page=$(($(get_page_size) / $(get_selftest_event_size))) # Approx: does not take TS into account
nr_events=$(($events_per_page * 2))
for i in $(seq 1 $nr_events); do
taskset -c $cpu echo $i > write_event
done
id=$(sed -n -e '1s/\[[0-9]*\]\s*[0-9]*.[0-9]*: [a-z]* id=\([0-9]*\)/\1/p' trace)
test $id -ne 1
check_trace $id $nr_events trace
#
# Test per-CPU interface
#
echo 0 > trace
for cpu in $(get_cpu_ids) ; do
taskset -c $cpu echo $cpu > write_event
done
for cpu in $(get_cpu_ids); do
cd per_cpu/cpu$cpu/
check_trace $cpu $cpu trace
cd - > /dev/null
done
#
# Test with hotplug
#
[ "$(get_cpu_ids | wc -l)" -ge 2 ] || return 0
echo 0 > trace
for cpu in $(get_cpu_ids); do
echo 0 > /sys/devices/system/cpu/cpu$cpu/online || return 0
break
done
for i in $(seq 1 8); do
echo $i > write_event
done
check_trace 1 8 trace
echo 1 > /sys/devices/system/cpu/cpu$cpu/online
}
if [ -z "$SOURCE_REMOTE_TEST" ]; then
set -e
setup_remote_test
test_trace
fi

View File

@ -0,0 +1,127 @@
#!/bin/sh
# SPDX-License-Identifier: GPL-2.0
# description: Test trace remote consuming read
# requires: remotes/test
. $TEST_DIR/remotes/functions
test_trace_pipe()
{
echo 0 > tracing_on
assert_unloaded
# Emit events from the same CPU
for cpu in $(get_cpu_ids); do
break
done
#
# Simple test: Emit enough events to fill few pages
#
echo 1024 > buffer_size_kb
echo 1 > tracing_on
assert_loaded
events_per_page=$(($(get_page_size) / $(get_selftest_event_size)))
nr_events=$(($events_per_page * 4))
output=$(mktemp $TMPDIR/remote_test.XXXXXX)
cat trace_pipe > $output &
pid=$!
for i in $(seq 1 $nr_events); do
taskset -c $cpu echo $i > write_event
done
echo 0 > tracing_on
sleep 1
kill $pid
check_trace 1 $nr_events $output
rm $output
#
# Test interaction with lost events
#
assert_unloaded
echo 7 > buffer_size_kb
echo 1 > tracing_on
assert_loaded
nr_events=$((events_per_page * 2))
for i in $(seq 1 $nr_events); do
taskset -c $cpu echo $i > write_event
done
output=$(dump_trace_pipe)
lost_events=$(sed -n -e '1s/CPU:.*\[LOST \([0-9]*\) EVENTS\]/\1/p' $output)
test -n "$lost_events"
id=$(sed -n -e '2s/\[[0-9]*\]\s*[0-9]*.[0-9]*: [a-z]* id=\([0-9]*\)/\1/p' $output)
test "$id" -eq $(($lost_events + 1))
# Drop [LOST EVENTS] line
sed -i '1d' $output
check_trace $id $nr_events $output
rm $output
#
# Test per-CPU interface
#
echo 0 > trace
echo 1 > tracing_on
for cpu in $(get_cpu_ids); do
taskset -c $cpu echo $cpu > write_event
done
for cpu in $(get_cpu_ids); do
cd per_cpu/cpu$cpu/
output=$(dump_trace_pipe)
check_trace $cpu $cpu $output
rm $output
cd - > /dev/null
done
#
# Test interaction with hotplug
#
[ "$(get_cpu_ids | wc -l)" -ge 2 ] || return 0
echo 0 > trace
for cpu in $(get_cpu_ids); do
echo 0 > /sys/devices/system/cpu/cpu$cpu/online || return 0
break
done
for i in $(seq 1 8); do
echo $i > write_event
done
output=$(dump_trace_pipe)
check_trace 1 8 $output
rm $output
echo 1 > /sys/devices/system/cpu/cpu$cpu/online
}
if [ -z "$SOURCE_REMOTE_TEST" ]; then
set -e
setup_remote_test
test_trace_pipe
fi

View File

@ -0,0 +1,41 @@
#!/bin/sh
# SPDX-License-Identifier: GPL-2.0
# description: Test trace remote unloading
# requires: remotes/test
. $TEST_DIR/remotes/functions
test_unloading()
{
# No reader, writing
assert_loaded
# No reader, no writing
echo 0 > tracing_on
assert_unloaded
# 1 reader, no writing
cat trace_pipe &
pid=$!
sleep 1
assert_loaded
kill $pid
assert_unloaded
# No reader, no writing, events
echo 1 > tracing_on
echo 1 > write_event
echo 0 > tracing_on
assert_loaded
# Test reset
clear_trace
assert_unloaded
}
if [ -z "$SOURCE_REMOTE_TEST" ]; then
set -e
setup_remote_test
test_unloading
fi