summaryrefslogtreecommitdiff
path: root/tools/testing/selftests/rcutorture/bin/srcu_lockdep.sh
blob: c29a39f7d8914db61bcfce2723ca3568711ef583 (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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
#!/bin/bash
# SPDX-License-Identifier: GPL-2.0+
#
# Run SRCU-lockdep tests and report any that fail to meet expectations.
#
# Copyright (C) 2021 Meta Platforms, Inc.
#
# Authors: Paul E. McKenney <paulmck@kernel.org>

usage () {
	echo "Usage: $scriptname optional arguments:"
	echo "       --datestamp string"
	exit 1
}

ds=`date +%Y.%m.%d-%H.%M.%S`-srcu_lockdep
scriptname="$0"

T="`mktemp -d ${TMPDIR-/tmp}/srcu_lockdep.sh.XXXXXX`"
trap 'rm -rf $T' 0

RCUTORTURE="`pwd`/tools/testing/selftests/rcutorture"; export RCUTORTURE
PATH=${RCUTORTURE}/bin:$PATH; export PATH
. functions.sh

while test $# -gt 0
do
	case "$1" in
	--datestamp)
		checkarg --datestamp "(relative pathname)" "$#" "$2" '^[a-zA-Z0-9._/-]*$' '^--'
		ds=$2
		shift
		;;
	*)
		echo Unknown argument $1
		usage
		;;
	esac
	shift
done

nerrs=0

# Test lockdep's handling of deadlocks.
for d in 0 1
do
	for t in 0 1 2 4 5
	do
		for c in 1 2 3
		do
			err=
			val=$((d*1000+t*10+c))
			tools/testing/selftests/rcutorture/bin/kvm.sh --allcpus --duration 5s --configs "SRCU-P" --kconfig "CONFIG_FORCE_NEED_SRCU_NMI_SAFE=y" --bootargs "rcutorture.test_srcu_lockdep=$val rcutorture.reader_flavor=0x4" --trust-make --datestamp "$ds/$val" > "$T/kvm.sh.out" 2>&1
			ret=$?
			mv "$T/kvm.sh.out" "$RCUTORTURE/res/$ds/$val"
			if ! grep -q '^CONFIG_PROVE_LOCKING=y' .config
			then
				echo "rcu_torture_init_srcu_lockdep:Error: CONFIG_PROVE_LOCKING disabled in rcutorture SRCU-P scenario"
				err=1
			fi
			if test "$d" -ne 0 && test "$ret" -eq 0
			then
				err=1
				echo -n Unexpected success for > "$RCUTORTURE/res/$ds/$val/kvm.sh.err"
			fi
			if test "$d" -eq 0 && test "$ret" -ne 0
			then
				err=1
				echo -n Unexpected failure for > "$RCUTORTURE/res/$ds/$val/kvm.sh.err"
			fi
			if test -n "$err"
			then
				grep "rcu_torture_init_srcu_lockdep: test_srcu_lockdep = " "$RCUTORTURE/res/$ds/$val/SRCU-P/console.log" | sed -e 's/^.*rcu_torture_init_srcu_lockdep://' >> "$RCUTORTURE/res/$ds/$val/kvm.sh.err"
				cat "$RCUTORTURE/res/$ds/$val/kvm.sh.err"
				nerrs=$((nerrs+1))
			fi
		done
	done
done

# Verify that synchronize_srcu_atomic() does not trigger lockdep
# warnings when called inside rcu_read_lock().
for c in 1 2 3
do
	err=
	val=$((6*10+c))
	tools/testing/selftests/rcutorture/bin/kvm.sh --allcpus --duration 5s \
		--configs "SRCU-P" \
		--kconfig "CONFIG_FORCE_NEED_SRCU_NMI_SAFE=y" \
		--bootargs "rcutorture.test_srcu_lockdep=$val" \
		--trust-make --datestamp "$ds/$val" > "$T/kvm.sh.out" 2>&1
	ret=$?
	mv "$T/kvm.sh.out" "$RCUTORTURE/res/$ds/$val"
	if ! grep -q '^CONFIG_PROVE_LOCKING=y' .config
	then
		echo "rcu_torture_init_srcu_lockdep:Error: CONFIG_PROVE_LOCKING" \
				"disabled in rcutorture SRCU-P scenario"
		err=1
	fi
	if test "$ret" -ne 0
	then
		err=1
		echo -n Unexpected failure for > "$RCUTORTURE/res/$ds/$val/kvm.sh.err"
	elif grep -qE "WARNING: possible (recursive locking|circular locking dependency)" \
		"$RCUTORTURE/res/$ds/$val/SRCU-P/console.log"
	then
		err=1
		echo -n Unexpected lockdep warning for > "$RCUTORTURE/res/$ds/$val/kvm.sh.err"
	fi
	if test -n "$err"
	then
		grep "rcu_torture_init_srcu_lockdep: test_srcu_lockdep = " "$RCUTORTURE/res/$ds/$val/SRCU-P/console.log" | sed -e 's/^.*rcu_torture_init_srcu_lockdep://' >> "$RCUTORTURE/res/$ds/$val/kvm.sh.err"
		cat "$RCUTORTURE/res/$ds/$val/kvm.sh.err"
		nerrs=$((nerrs+1))
	fi
done

# Verify that synchronize_srcu_atomic() detects IRQ context mismatch
# when SRCU reader previously ran with IRQs enabled.
for c in 1 2 3
do
	err=
	val=$((1000+7*10+c))
	tools/testing/selftests/rcutorture/bin/kvm.sh --allcpus --duration 5s \
		--configs "SRCU-P" \
		--kconfig "CONFIG_FORCE_NEED_SRCU_NMI_SAFE=y" \
		--bootargs "rcutorture.test_srcu_lockdep=$val" \
		--trust-make --datestamp "$ds/$val" > "$T/kvm.sh.out" 2>&1
	ret=$?
	mv "$T/kvm.sh.out" "$RCUTORTURE/res/$ds/$val"
	if ! grep -q '^CONFIG_PROVE_LOCKING=y' .config
	then
		echo "rcu_torture_init_srcu_lockdep:Error: CONFIG_PROVE_LOCKING" \
				"disabled in rcutorture SRCU-P scenario"
		err=1
	fi
	if test "$ret" -eq 0
	then
		err=1
		echo -n Missing lockdep warning for > "$RCUTORTURE/res/$ds/$val/kvm.sh.err"
	elif ! grep -q "inconsistent {HARDIRQ-ON-R}" "$RCUTORTURE/res/$ds/$val/SRCU-P/console.log"
	then
		err=1
		echo -n Missing lockdep warning for > "$RCUTORTURE/res/$ds/$val/kvm.sh.err"
	fi
	if test -n "$err"
	then
		grep "rcu_torture_init_srcu_lockdep: test_srcu_lockdep = " "$RCUTORTURE/res/$ds/$val/SRCU-P/console.log" | sed -e 's/^.*rcu_torture_init_srcu_lockdep://' >> "$RCUTORTURE/res/$ds/$val/kvm.sh.err"
		cat "$RCUTORTURE/res/$ds/$val/kvm.sh.err"
		nerrs=$((nerrs+1))
	fi
done

# Test lockdep-enabled testing of mixed SRCU readers.
for val in 0x1 0xf
do
	err=
	tools/testing/selftests/rcutorture/bin/kvm.sh --allcpus --duration 5s --configs "SRCU-P" --kconfig "CONFIG_FORCE_NEED_SRCU_NMI_SAFE=y" --bootargs "rcutorture.reader_flavor=$val" --trust-make --datestamp "$ds/$val" > "$T/kvm.sh.out" 2>&1
	ret=$?
	mv "$T/kvm.sh.out" "$RCUTORTURE/res/$ds/$val"
	if ! grep -q '^CONFIG_PROVE_LOCKING=y' .config
	then
		echo "rcu_torture_init_srcu_lockdep:Error: CONFIG_PROVE_LOCKING disabled in rcutorture SRCU-P scenario"
		err=1
	fi
	if test "$val" = 0xf && test "$ret" -eq 0
	then
		err=1
		echo -n Unexpected success for > "$RCUTORTURE/res/$ds/$val/kvm.sh.err"
	fi
	if test "$val" = 0x1 && test "$ret" -ne 0
	then
		err=1
		echo -n Unexpected failure for > "$RCUTORTURE/res/$ds/$val/kvm.sh.err"
	fi
	if test -n "$err"
	then
		grep "rcu_torture_init_srcu_lockdep: test_srcu_lockdep = " "$RCUTORTURE/res/$ds/$val/SRCU-P/console.log" | sed -e 's/^.*rcu_torture_init_srcu_lockdep://' >> "$RCUTORTURE/res/$ds/$val/kvm.sh.err"
		cat "$RCUTORTURE/res/$ds/$val/kvm.sh.err"
		nerrs=$((nerrs+1))
	fi
done

# Set up exit code.
if test "$nerrs" -ne 0
then
	exit 1
fi
exit 0