summaryrefslogtreecommitdiff
path: root/tools/testing/selftests/ftrace/test.d/00basic/trace_marker_raw.tc
blob: f985ff391463a7f326558de33b7ceebd81d735d8 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#!/bin/sh
# SPDX-License-Identifier: GPL-2.0
# description: Basic tests on writing to trace_marker_raw
# requires: trace_marker_raw
# flags: instance

check_awk_strtonum || exit_unresolved

is_little_endian() {
	if lscpu | grep -q 'Little Endian'; then
		echo 1;
	else
		echo 0;
	fi
}

little=`is_little_endian`

make_str() {
	id=$1
	cnt=$2

	if [ $little -eq 1 ]; then
		val=`printf "\\%03o\\%03o\\%03o\\%03o" \
			$(($id & 0xff)) \
			$((($id >> 8) & 0xff)) \
			$((($id >> 16) & 0xff)) \
			$((($id >> 24) & 0xff))`
	else
		val=`printf "\\%03o\\%03o\\%03o\\%03o" \
			$((($id >> 24) & 0xff)) \
			$((($id >> 16) & 0xff)) \
			$((($id >> 8) & 0xff)) \
			$(($id & 0xff))`
	fi

	data=`printf -- 'X%.0s' $(seq $cnt)`

	# 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

	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
}


test_multiple_writes() {

	# 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
	done

	# add a little buffer
	echo stop > trace_marker

	# 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;
}


get_buffer_data_size() {
	sed -ne 's/^.*data.*size:\([0-9][0-9]*\).*/\1/p' events/header_page
}

test_buffer() {

	# The id must be four bytes, test that 3 bytes fails a write
	if echo -n abc > ./trace_marker_raw ; then
		echo "Too small of write expected to fail but did not"
		echo ${ORIG} > buffer_size_kb
		exit_fail
	fi

	size=`get_buffer_data_size`
	echo size = $size

	# Now add a little more than what it can handle

	if write_buffer 0xdeadbeef $size ; then
		echo "Too big of write expected to fail but did not"
		echo ${ORIG} > buffer_size_kb
		exit_fail
	fi
}

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
	exit_fail
fi

echo ${ORIG} > buffer_size_kb