xref: /OK3568_Linux_fs/kernel/tools/testing/selftests/cpu-hotplug/cpu-on-off-test.sh (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun#!/bin/bash
2*4882a593Smuzhiyun# SPDX-License-Identifier: GPL-2.0
3*4882a593Smuzhiyun
4*4882a593SmuzhiyunSYSFS=
5*4882a593Smuzhiyun# Kselftest framework requirement - SKIP code is 4.
6*4882a593Smuzhiyunksft_skip=4
7*4882a593Smuzhiyun
8*4882a593Smuzhiyunprerequisite()
9*4882a593Smuzhiyun{
10*4882a593Smuzhiyun	msg="skip all tests:"
11*4882a593Smuzhiyun
12*4882a593Smuzhiyun	if [ $UID != 0 ]; then
13*4882a593Smuzhiyun		echo $msg must be run as root >&2
14*4882a593Smuzhiyun		exit $ksft_skip
15*4882a593Smuzhiyun	fi
16*4882a593Smuzhiyun
17*4882a593Smuzhiyun	taskset -p 01 $$
18*4882a593Smuzhiyun
19*4882a593Smuzhiyun	SYSFS=`mount -t sysfs | head -1 | awk '{ print $3 }'`
20*4882a593Smuzhiyun
21*4882a593Smuzhiyun	if [ ! -d "$SYSFS" ]; then
22*4882a593Smuzhiyun		echo $msg sysfs is not mounted >&2
23*4882a593Smuzhiyun		exit $ksft_skip
24*4882a593Smuzhiyun	fi
25*4882a593Smuzhiyun
26*4882a593Smuzhiyun	if ! ls $SYSFS/devices/system/cpu/cpu* > /dev/null 2>&1; then
27*4882a593Smuzhiyun		echo $msg cpu hotplug is not supported >&2
28*4882a593Smuzhiyun		exit $ksft_skip
29*4882a593Smuzhiyun	fi
30*4882a593Smuzhiyun
31*4882a593Smuzhiyun	echo "CPU online/offline summary:"
32*4882a593Smuzhiyun	online_cpus=`cat $SYSFS/devices/system/cpu/online`
33*4882a593Smuzhiyun	online_max=${online_cpus##*-}
34*4882a593Smuzhiyun
35*4882a593Smuzhiyun	if [[ "$online_cpus" = "$online_max" ]]; then
36*4882a593Smuzhiyun		echo "$msg: since there is only one cpu: $online_cpus"
37*4882a593Smuzhiyun		exit $ksft_skip
38*4882a593Smuzhiyun	fi
39*4882a593Smuzhiyun
40*4882a593Smuzhiyun	present_cpus=`cat $SYSFS/devices/system/cpu/present`
41*4882a593Smuzhiyun	present_max=${present_cpus##*-}
42*4882a593Smuzhiyun	echo "present_cpus = $present_cpus present_max = $present_max"
43*4882a593Smuzhiyun
44*4882a593Smuzhiyun	echo -e "\t Cpus in online state: $online_cpus"
45*4882a593Smuzhiyun
46*4882a593Smuzhiyun	offline_cpus=`cat $SYSFS/devices/system/cpu/offline`
47*4882a593Smuzhiyun	if [[ "a$offline_cpus" = "a" ]]; then
48*4882a593Smuzhiyun		offline_cpus=0
49*4882a593Smuzhiyun	else
50*4882a593Smuzhiyun		offline_max=${offline_cpus##*-}
51*4882a593Smuzhiyun	fi
52*4882a593Smuzhiyun	echo -e "\t Cpus in offline state: $offline_cpus"
53*4882a593Smuzhiyun}
54*4882a593Smuzhiyun
55*4882a593Smuzhiyun#
56*4882a593Smuzhiyun# list all hot-pluggable CPUs
57*4882a593Smuzhiyun#
58*4882a593Smuzhiyunhotpluggable_cpus()
59*4882a593Smuzhiyun{
60*4882a593Smuzhiyun	local state=${1:-.\*}
61*4882a593Smuzhiyun
62*4882a593Smuzhiyun	for cpu in $SYSFS/devices/system/cpu/cpu*; do
63*4882a593Smuzhiyun		if [ -f $cpu/online ] && grep -q $state $cpu/online; then
64*4882a593Smuzhiyun			echo ${cpu##/*/cpu}
65*4882a593Smuzhiyun		fi
66*4882a593Smuzhiyun	done
67*4882a593Smuzhiyun}
68*4882a593Smuzhiyun
69*4882a593Smuzhiyunhotplaggable_offline_cpus()
70*4882a593Smuzhiyun{
71*4882a593Smuzhiyun	hotpluggable_cpus 0
72*4882a593Smuzhiyun}
73*4882a593Smuzhiyun
74*4882a593Smuzhiyunhotpluggable_online_cpus()
75*4882a593Smuzhiyun{
76*4882a593Smuzhiyun	hotpluggable_cpus 1
77*4882a593Smuzhiyun}
78*4882a593Smuzhiyun
79*4882a593Smuzhiyuncpu_is_online()
80*4882a593Smuzhiyun{
81*4882a593Smuzhiyun	grep -q 1 $SYSFS/devices/system/cpu/cpu$1/online
82*4882a593Smuzhiyun}
83*4882a593Smuzhiyun
84*4882a593Smuzhiyuncpu_is_offline()
85*4882a593Smuzhiyun{
86*4882a593Smuzhiyun	grep -q 0 $SYSFS/devices/system/cpu/cpu$1/online
87*4882a593Smuzhiyun}
88*4882a593Smuzhiyun
89*4882a593Smuzhiyunonline_cpu()
90*4882a593Smuzhiyun{
91*4882a593Smuzhiyun	echo 1 > $SYSFS/devices/system/cpu/cpu$1/online
92*4882a593Smuzhiyun}
93*4882a593Smuzhiyun
94*4882a593Smuzhiyunoffline_cpu()
95*4882a593Smuzhiyun{
96*4882a593Smuzhiyun	echo 0 > $SYSFS/devices/system/cpu/cpu$1/online
97*4882a593Smuzhiyun}
98*4882a593Smuzhiyun
99*4882a593Smuzhiyunonline_cpu_expect_success()
100*4882a593Smuzhiyun{
101*4882a593Smuzhiyun	local cpu=$1
102*4882a593Smuzhiyun
103*4882a593Smuzhiyun	if ! online_cpu $cpu; then
104*4882a593Smuzhiyun		echo $FUNCNAME $cpu: unexpected fail >&2
105*4882a593Smuzhiyun		exit 1
106*4882a593Smuzhiyun	elif ! cpu_is_online $cpu; then
107*4882a593Smuzhiyun		echo $FUNCNAME $cpu: unexpected offline >&2
108*4882a593Smuzhiyun		exit 1
109*4882a593Smuzhiyun	fi
110*4882a593Smuzhiyun}
111*4882a593Smuzhiyun
112*4882a593Smuzhiyunonline_cpu_expect_fail()
113*4882a593Smuzhiyun{
114*4882a593Smuzhiyun	local cpu=$1
115*4882a593Smuzhiyun
116*4882a593Smuzhiyun	if online_cpu $cpu 2> /dev/null; then
117*4882a593Smuzhiyun		echo $FUNCNAME $cpu: unexpected success >&2
118*4882a593Smuzhiyun		exit 1
119*4882a593Smuzhiyun	elif ! cpu_is_offline $cpu; then
120*4882a593Smuzhiyun		echo $FUNCNAME $cpu: unexpected online >&2
121*4882a593Smuzhiyun		exit 1
122*4882a593Smuzhiyun	fi
123*4882a593Smuzhiyun}
124*4882a593Smuzhiyun
125*4882a593Smuzhiyunoffline_cpu_expect_success()
126*4882a593Smuzhiyun{
127*4882a593Smuzhiyun	local cpu=$1
128*4882a593Smuzhiyun
129*4882a593Smuzhiyun	if ! offline_cpu $cpu; then
130*4882a593Smuzhiyun		echo $FUNCNAME $cpu: unexpected fail >&2
131*4882a593Smuzhiyun		exit 1
132*4882a593Smuzhiyun	elif ! cpu_is_offline $cpu; then
133*4882a593Smuzhiyun		echo $FUNCNAME $cpu: unexpected offline >&2
134*4882a593Smuzhiyun		exit 1
135*4882a593Smuzhiyun	fi
136*4882a593Smuzhiyun}
137*4882a593Smuzhiyun
138*4882a593Smuzhiyunoffline_cpu_expect_fail()
139*4882a593Smuzhiyun{
140*4882a593Smuzhiyun	local cpu=$1
141*4882a593Smuzhiyun
142*4882a593Smuzhiyun	if offline_cpu $cpu 2> /dev/null; then
143*4882a593Smuzhiyun		echo $FUNCNAME $cpu: unexpected success >&2
144*4882a593Smuzhiyun		exit 1
145*4882a593Smuzhiyun	elif ! cpu_is_online $cpu; then
146*4882a593Smuzhiyun		echo $FUNCNAME $cpu: unexpected offline >&2
147*4882a593Smuzhiyun		exit 1
148*4882a593Smuzhiyun	fi
149*4882a593Smuzhiyun}
150*4882a593Smuzhiyun
151*4882a593Smuzhiyunerror=-12
152*4882a593Smuzhiyunallcpus=0
153*4882a593Smuzhiyunpriority=0
154*4882a593Smuzhiyunonline_cpus=0
155*4882a593Smuzhiyunonline_max=0
156*4882a593Smuzhiyunoffline_cpus=0
157*4882a593Smuzhiyunoffline_max=0
158*4882a593Smuzhiyunpresent_cpus=0
159*4882a593Smuzhiyunpresent_max=0
160*4882a593Smuzhiyun
161*4882a593Smuzhiyunwhile getopts e:ahp: opt; do
162*4882a593Smuzhiyun	case $opt in
163*4882a593Smuzhiyun	e)
164*4882a593Smuzhiyun		error=$OPTARG
165*4882a593Smuzhiyun		;;
166*4882a593Smuzhiyun	a)
167*4882a593Smuzhiyun		allcpus=1
168*4882a593Smuzhiyun		;;
169*4882a593Smuzhiyun	h)
170*4882a593Smuzhiyun		echo "Usage $0 [ -a ] [ -e errno ] [ -p notifier-priority ]"
171*4882a593Smuzhiyun		echo -e "\t default offline one cpu"
172*4882a593Smuzhiyun		echo -e "\t run with -a option to offline all cpus"
173*4882a593Smuzhiyun		exit
174*4882a593Smuzhiyun		;;
175*4882a593Smuzhiyun	p)
176*4882a593Smuzhiyun		priority=$OPTARG
177*4882a593Smuzhiyun		;;
178*4882a593Smuzhiyun	esac
179*4882a593Smuzhiyundone
180*4882a593Smuzhiyun
181*4882a593Smuzhiyunif ! [ "$error" -ge -4095 -a "$error" -lt 0 ]; then
182*4882a593Smuzhiyun	echo "error code must be -4095 <= errno < 0" >&2
183*4882a593Smuzhiyun	exit 1
184*4882a593Smuzhiyunfi
185*4882a593Smuzhiyun
186*4882a593Smuzhiyunprerequisite
187*4882a593Smuzhiyun
188*4882a593Smuzhiyun#
189*4882a593Smuzhiyun# Safe test (default) - offline and online one cpu
190*4882a593Smuzhiyun#
191*4882a593Smuzhiyunif [ $allcpus -eq 0 ]; then
192*4882a593Smuzhiyun	echo "Limited scope test: one hotplug cpu"
193*4882a593Smuzhiyun	echo -e "\t (leaves cpu in the original state):"
194*4882a593Smuzhiyun	echo -e "\t online to offline to online: cpu $online_max"
195*4882a593Smuzhiyun	offline_cpu_expect_success $online_max
196*4882a593Smuzhiyun	online_cpu_expect_success $online_max
197*4882a593Smuzhiyun
198*4882a593Smuzhiyun	if [[ $offline_cpus -gt 0 ]]; then
199*4882a593Smuzhiyun		echo -e "\t offline to online to offline: cpu $present_max"
200*4882a593Smuzhiyun		online_cpu_expect_success $present_max
201*4882a593Smuzhiyun		offline_cpu_expect_success $present_max
202*4882a593Smuzhiyun		online_cpu $present_max
203*4882a593Smuzhiyun	fi
204*4882a593Smuzhiyun	exit 0
205*4882a593Smuzhiyunelse
206*4882a593Smuzhiyun	echo "Full scope test: all hotplug cpus"
207*4882a593Smuzhiyun	echo -e "\t online all offline cpus"
208*4882a593Smuzhiyun	echo -e "\t offline all online cpus"
209*4882a593Smuzhiyun	echo -e "\t online all offline cpus"
210*4882a593Smuzhiyunfi
211*4882a593Smuzhiyun
212*4882a593Smuzhiyun#
213*4882a593Smuzhiyun# Online all hot-pluggable CPUs
214*4882a593Smuzhiyun#
215*4882a593Smuzhiyunfor cpu in `hotplaggable_offline_cpus`; do
216*4882a593Smuzhiyun	online_cpu_expect_success $cpu
217*4882a593Smuzhiyundone
218*4882a593Smuzhiyun
219*4882a593Smuzhiyun#
220*4882a593Smuzhiyun# Offline all hot-pluggable CPUs
221*4882a593Smuzhiyun#
222*4882a593Smuzhiyunfor cpu in `hotpluggable_online_cpus`; do
223*4882a593Smuzhiyun	offline_cpu_expect_success $cpu
224*4882a593Smuzhiyundone
225*4882a593Smuzhiyun
226*4882a593Smuzhiyun#
227*4882a593Smuzhiyun# Online all hot-pluggable CPUs again
228*4882a593Smuzhiyun#
229*4882a593Smuzhiyunfor cpu in `hotplaggable_offline_cpus`; do
230*4882a593Smuzhiyun	online_cpu_expect_success $cpu
231*4882a593Smuzhiyundone
232*4882a593Smuzhiyun
233*4882a593Smuzhiyun#
234*4882a593Smuzhiyun# Test with cpu notifier error injection
235*4882a593Smuzhiyun#
236*4882a593Smuzhiyun
237*4882a593SmuzhiyunDEBUGFS=`mount -t debugfs | head -1 | awk '{ print $3 }'`
238*4882a593SmuzhiyunNOTIFIER_ERR_INJECT_DIR=$DEBUGFS/notifier-error-inject/cpu
239*4882a593Smuzhiyun
240*4882a593Smuzhiyunprerequisite_extra()
241*4882a593Smuzhiyun{
242*4882a593Smuzhiyun	msg="skip extra tests:"
243*4882a593Smuzhiyun
244*4882a593Smuzhiyun	/sbin/modprobe -q -r cpu-notifier-error-inject
245*4882a593Smuzhiyun	/sbin/modprobe -q cpu-notifier-error-inject priority=$priority
246*4882a593Smuzhiyun
247*4882a593Smuzhiyun	if [ ! -d "$DEBUGFS" ]; then
248*4882a593Smuzhiyun		echo $msg debugfs is not mounted >&2
249*4882a593Smuzhiyun		exit $ksft_skip
250*4882a593Smuzhiyun	fi
251*4882a593Smuzhiyun
252*4882a593Smuzhiyun	if [ ! -d $NOTIFIER_ERR_INJECT_DIR ]; then
253*4882a593Smuzhiyun		echo $msg cpu-notifier-error-inject module is not available >&2
254*4882a593Smuzhiyun		exit $ksft_skip
255*4882a593Smuzhiyun	fi
256*4882a593Smuzhiyun}
257*4882a593Smuzhiyun
258*4882a593Smuzhiyunprerequisite_extra
259*4882a593Smuzhiyun
260*4882a593Smuzhiyun#
261*4882a593Smuzhiyun# Offline all hot-pluggable CPUs
262*4882a593Smuzhiyun#
263*4882a593Smuzhiyunecho 0 > $NOTIFIER_ERR_INJECT_DIR/actions/CPU_DOWN_PREPARE/error
264*4882a593Smuzhiyunfor cpu in `hotpluggable_online_cpus`; do
265*4882a593Smuzhiyun	offline_cpu_expect_success $cpu
266*4882a593Smuzhiyundone
267*4882a593Smuzhiyun
268*4882a593Smuzhiyun#
269*4882a593Smuzhiyun# Test CPU hot-add error handling (offline => online)
270*4882a593Smuzhiyun#
271*4882a593Smuzhiyunecho $error > $NOTIFIER_ERR_INJECT_DIR/actions/CPU_UP_PREPARE/error
272*4882a593Smuzhiyunfor cpu in `hotplaggable_offline_cpus`; do
273*4882a593Smuzhiyun	online_cpu_expect_fail $cpu
274*4882a593Smuzhiyundone
275*4882a593Smuzhiyun
276*4882a593Smuzhiyun#
277*4882a593Smuzhiyun# Online all hot-pluggable CPUs
278*4882a593Smuzhiyun#
279*4882a593Smuzhiyunecho 0 > $NOTIFIER_ERR_INJECT_DIR/actions/CPU_UP_PREPARE/error
280*4882a593Smuzhiyunfor cpu in `hotplaggable_offline_cpus`; do
281*4882a593Smuzhiyun	online_cpu_expect_success $cpu
282*4882a593Smuzhiyundone
283*4882a593Smuzhiyun
284*4882a593Smuzhiyun#
285*4882a593Smuzhiyun# Test CPU hot-remove error handling (online => offline)
286*4882a593Smuzhiyun#
287*4882a593Smuzhiyunecho $error > $NOTIFIER_ERR_INJECT_DIR/actions/CPU_DOWN_PREPARE/error
288*4882a593Smuzhiyunfor cpu in `hotpluggable_online_cpus`; do
289*4882a593Smuzhiyun	offline_cpu_expect_fail $cpu
290*4882a593Smuzhiyundone
291*4882a593Smuzhiyun
292*4882a593Smuzhiyunecho 0 > $NOTIFIER_ERR_INJECT_DIR/actions/CPU_DOWN_PREPARE/error
293*4882a593Smuzhiyun/sbin/modprobe -q -r cpu-notifier-error-inject
294