162306a36Sopenharmony_ci#!/bin/bash
262306a36Sopenharmony_ci# SPDX-License-Identifier: GPL-2.0
362306a36Sopenharmony_ci
462306a36Sopenharmony_ciSYSFS=
562306a36Sopenharmony_ci# Kselftest framework requirement - SKIP code is 4.
662306a36Sopenharmony_ciksft_skip=4
762306a36Sopenharmony_ciretval=0
862306a36Sopenharmony_ci
962306a36Sopenharmony_ciprerequisite()
1062306a36Sopenharmony_ci{
1162306a36Sopenharmony_ci	msg="skip all tests:"
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_ci	if [ $UID != 0 ]; then
1462306a36Sopenharmony_ci		echo $msg must be run as root >&2
1562306a36Sopenharmony_ci		exit $ksft_skip
1662306a36Sopenharmony_ci	fi
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_ci	taskset -p 01 $$
1962306a36Sopenharmony_ci
2062306a36Sopenharmony_ci	SYSFS=`mount -t sysfs | head -1 | awk '{ print $3 }'`
2162306a36Sopenharmony_ci
2262306a36Sopenharmony_ci	if [ ! -d "$SYSFS" ]; then
2362306a36Sopenharmony_ci		echo $msg sysfs is not mounted >&2
2462306a36Sopenharmony_ci		exit $ksft_skip
2562306a36Sopenharmony_ci	fi
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_ci	if ! ls $SYSFS/devices/system/cpu/cpu* > /dev/null 2>&1; then
2862306a36Sopenharmony_ci		echo $msg cpu hotplug is not supported >&2
2962306a36Sopenharmony_ci		exit $ksft_skip
3062306a36Sopenharmony_ci	fi
3162306a36Sopenharmony_ci
3262306a36Sopenharmony_ci	echo "CPU online/offline summary:"
3362306a36Sopenharmony_ci	online_cpus=`cat $SYSFS/devices/system/cpu/online`
3462306a36Sopenharmony_ci	online_max=${online_cpus##*-}
3562306a36Sopenharmony_ci
3662306a36Sopenharmony_ci	if [[ "$online_cpus" = "$online_max" ]]; then
3762306a36Sopenharmony_ci		echo "$msg: since there is only one cpu: $online_cpus"
3862306a36Sopenharmony_ci		exit $ksft_skip
3962306a36Sopenharmony_ci	fi
4062306a36Sopenharmony_ci
4162306a36Sopenharmony_ci	present_cpus=`cat $SYSFS/devices/system/cpu/present`
4262306a36Sopenharmony_ci	present_max=${present_cpus##*-}
4362306a36Sopenharmony_ci	echo "present_cpus = $present_cpus present_max = $present_max"
4462306a36Sopenharmony_ci
4562306a36Sopenharmony_ci	echo -e "\t Cpus in online state: $online_cpus"
4662306a36Sopenharmony_ci
4762306a36Sopenharmony_ci	offline_cpus=`cat $SYSFS/devices/system/cpu/offline`
4862306a36Sopenharmony_ci	if [[ "a$offline_cpus" = "a" ]]; then
4962306a36Sopenharmony_ci		offline_cpus=0
5062306a36Sopenharmony_ci	else
5162306a36Sopenharmony_ci		offline_max=${offline_cpus##*-}
5262306a36Sopenharmony_ci	fi
5362306a36Sopenharmony_ci	echo -e "\t Cpus in offline state: $offline_cpus"
5462306a36Sopenharmony_ci}
5562306a36Sopenharmony_ci
5662306a36Sopenharmony_ci#
5762306a36Sopenharmony_ci# list all hot-pluggable CPUs
5862306a36Sopenharmony_ci#
5962306a36Sopenharmony_cihotpluggable_cpus()
6062306a36Sopenharmony_ci{
6162306a36Sopenharmony_ci	local state=${1:-.\*}
6262306a36Sopenharmony_ci
6362306a36Sopenharmony_ci	for cpu in $SYSFS/devices/system/cpu/cpu*; do
6462306a36Sopenharmony_ci		if [ -f $cpu/online ] && grep -q $state $cpu/online; then
6562306a36Sopenharmony_ci			echo ${cpu##/*/cpu}
6662306a36Sopenharmony_ci		fi
6762306a36Sopenharmony_ci	done
6862306a36Sopenharmony_ci}
6962306a36Sopenharmony_ci
7062306a36Sopenharmony_cihotplaggable_offline_cpus()
7162306a36Sopenharmony_ci{
7262306a36Sopenharmony_ci	hotpluggable_cpus 0
7362306a36Sopenharmony_ci}
7462306a36Sopenharmony_ci
7562306a36Sopenharmony_cihotpluggable_online_cpus()
7662306a36Sopenharmony_ci{
7762306a36Sopenharmony_ci	hotpluggable_cpus 1
7862306a36Sopenharmony_ci}
7962306a36Sopenharmony_ci
8062306a36Sopenharmony_cicpu_is_online()
8162306a36Sopenharmony_ci{
8262306a36Sopenharmony_ci	grep -q 1 $SYSFS/devices/system/cpu/cpu$1/online
8362306a36Sopenharmony_ci}
8462306a36Sopenharmony_ci
8562306a36Sopenharmony_cicpu_is_offline()
8662306a36Sopenharmony_ci{
8762306a36Sopenharmony_ci	grep -q 0 $SYSFS/devices/system/cpu/cpu$1/online
8862306a36Sopenharmony_ci}
8962306a36Sopenharmony_ci
9062306a36Sopenharmony_cionline_cpu()
9162306a36Sopenharmony_ci{
9262306a36Sopenharmony_ci	echo 1 > $SYSFS/devices/system/cpu/cpu$1/online
9362306a36Sopenharmony_ci}
9462306a36Sopenharmony_ci
9562306a36Sopenharmony_cioffline_cpu()
9662306a36Sopenharmony_ci{
9762306a36Sopenharmony_ci	echo 0 > $SYSFS/devices/system/cpu/cpu$1/online
9862306a36Sopenharmony_ci}
9962306a36Sopenharmony_ci
10062306a36Sopenharmony_cionline_cpu_expect_success()
10162306a36Sopenharmony_ci{
10262306a36Sopenharmony_ci	local cpu=$1
10362306a36Sopenharmony_ci
10462306a36Sopenharmony_ci	if ! online_cpu $cpu; then
10562306a36Sopenharmony_ci		echo $FUNCNAME $cpu: unexpected fail >&2
10662306a36Sopenharmony_ci		retval=1
10762306a36Sopenharmony_ci	elif ! cpu_is_online $cpu; then
10862306a36Sopenharmony_ci		echo $FUNCNAME $cpu: unexpected offline >&2
10962306a36Sopenharmony_ci		retval=1
11062306a36Sopenharmony_ci	fi
11162306a36Sopenharmony_ci}
11262306a36Sopenharmony_ci
11362306a36Sopenharmony_cionline_cpu_expect_fail()
11462306a36Sopenharmony_ci{
11562306a36Sopenharmony_ci	local cpu=$1
11662306a36Sopenharmony_ci
11762306a36Sopenharmony_ci	if online_cpu $cpu 2> /dev/null; then
11862306a36Sopenharmony_ci		echo $FUNCNAME $cpu: unexpected success >&2
11962306a36Sopenharmony_ci		retval=1
12062306a36Sopenharmony_ci	elif ! cpu_is_offline $cpu; then
12162306a36Sopenharmony_ci		echo $FUNCNAME $cpu: unexpected online >&2
12262306a36Sopenharmony_ci		retval=1
12362306a36Sopenharmony_ci	fi
12462306a36Sopenharmony_ci}
12562306a36Sopenharmony_ci
12662306a36Sopenharmony_cioffline_cpu_expect_success()
12762306a36Sopenharmony_ci{
12862306a36Sopenharmony_ci	local cpu=$1
12962306a36Sopenharmony_ci
13062306a36Sopenharmony_ci	if ! offline_cpu $cpu; then
13162306a36Sopenharmony_ci		echo $FUNCNAME $cpu: unexpected fail >&2
13262306a36Sopenharmony_ci		retval=1
13362306a36Sopenharmony_ci	elif ! cpu_is_offline $cpu; then
13462306a36Sopenharmony_ci		echo $FUNCNAME $cpu: unexpected offline >&2
13562306a36Sopenharmony_ci		retval=1
13662306a36Sopenharmony_ci	fi
13762306a36Sopenharmony_ci}
13862306a36Sopenharmony_ci
13962306a36Sopenharmony_cioffline_cpu_expect_fail()
14062306a36Sopenharmony_ci{
14162306a36Sopenharmony_ci	local cpu=$1
14262306a36Sopenharmony_ci
14362306a36Sopenharmony_ci	if offline_cpu $cpu 2> /dev/null; then
14462306a36Sopenharmony_ci		echo $FUNCNAME $cpu: unexpected success >&2
14562306a36Sopenharmony_ci		retval=1
14662306a36Sopenharmony_ci	elif ! cpu_is_online $cpu; then
14762306a36Sopenharmony_ci		echo $FUNCNAME $cpu: unexpected offline >&2
14862306a36Sopenharmony_ci		retval=1
14962306a36Sopenharmony_ci	fi
15062306a36Sopenharmony_ci}
15162306a36Sopenharmony_ci
15262306a36Sopenharmony_cionline_all_hot_pluggable_cpus()
15362306a36Sopenharmony_ci{
15462306a36Sopenharmony_ci	for cpu in `hotplaggable_offline_cpus`; do
15562306a36Sopenharmony_ci		online_cpu_expect_success $cpu
15662306a36Sopenharmony_ci	done
15762306a36Sopenharmony_ci}
15862306a36Sopenharmony_ci
15962306a36Sopenharmony_cioffline_all_hot_pluggable_cpus()
16062306a36Sopenharmony_ci{
16162306a36Sopenharmony_ci	local reserve_cpu=$online_max
16262306a36Sopenharmony_ci	for cpu in `hotpluggable_online_cpus`; do
16362306a36Sopenharmony_ci		# Reserve one cpu oneline at least.
16462306a36Sopenharmony_ci		if [ $cpu -eq $reserve_cpu ];then
16562306a36Sopenharmony_ci			continue
16662306a36Sopenharmony_ci		fi
16762306a36Sopenharmony_ci		offline_cpu_expect_success $cpu
16862306a36Sopenharmony_ci	done
16962306a36Sopenharmony_ci}
17062306a36Sopenharmony_ci
17162306a36Sopenharmony_ciallcpus=0
17262306a36Sopenharmony_cionline_cpus=0
17362306a36Sopenharmony_cionline_max=0
17462306a36Sopenharmony_cioffline_cpus=0
17562306a36Sopenharmony_cioffline_max=0
17662306a36Sopenharmony_cipresent_cpus=0
17762306a36Sopenharmony_cipresent_max=0
17862306a36Sopenharmony_ci
17962306a36Sopenharmony_ciwhile getopts ah opt; do
18062306a36Sopenharmony_ci	case $opt in
18162306a36Sopenharmony_ci	a)
18262306a36Sopenharmony_ci		allcpus=1
18362306a36Sopenharmony_ci		;;
18462306a36Sopenharmony_ci	h)
18562306a36Sopenharmony_ci		echo "Usage $0 [ -a ]"
18662306a36Sopenharmony_ci		echo -e "\t default offline one cpu"
18762306a36Sopenharmony_ci		echo -e "\t run with -a option to offline all cpus"
18862306a36Sopenharmony_ci		exit
18962306a36Sopenharmony_ci		;;
19062306a36Sopenharmony_ci	esac
19162306a36Sopenharmony_cidone
19262306a36Sopenharmony_ci
19362306a36Sopenharmony_ciprerequisite
19462306a36Sopenharmony_ci
19562306a36Sopenharmony_ci#
19662306a36Sopenharmony_ci# Safe test (default) - offline and online one cpu
19762306a36Sopenharmony_ci#
19862306a36Sopenharmony_ciif [ $allcpus -eq 0 ]; then
19962306a36Sopenharmony_ci	echo "Limited scope test: one hotplug cpu"
20062306a36Sopenharmony_ci	echo -e "\t (leaves cpu in the original state):"
20162306a36Sopenharmony_ci	echo -e "\t online to offline to online: cpu $online_max"
20262306a36Sopenharmony_ci	offline_cpu_expect_success $online_max
20362306a36Sopenharmony_ci	online_cpu_expect_success $online_max
20462306a36Sopenharmony_ci
20562306a36Sopenharmony_ci	if [[ $offline_cpus -gt 0 ]]; then
20662306a36Sopenharmony_ci		echo -e "\t online to offline to online: cpu $present_max"
20762306a36Sopenharmony_ci		online_cpu_expect_success $present_max
20862306a36Sopenharmony_ci		offline_cpu_expect_success $present_max
20962306a36Sopenharmony_ci		online_cpu $present_max
21062306a36Sopenharmony_ci	fi
21162306a36Sopenharmony_ci	exit $retval
21262306a36Sopenharmony_cielse
21362306a36Sopenharmony_ci	echo "Full scope test: all hotplug cpus"
21462306a36Sopenharmony_ci	echo -e "\t online all offline cpus"
21562306a36Sopenharmony_ci	echo -e "\t offline all online cpus"
21662306a36Sopenharmony_ci	echo -e "\t online all offline cpus"
21762306a36Sopenharmony_cifi
21862306a36Sopenharmony_ci
21962306a36Sopenharmony_cionline_all_hot_pluggable_cpus
22062306a36Sopenharmony_ci
22162306a36Sopenharmony_cioffline_all_hot_pluggable_cpus
22262306a36Sopenharmony_ci
22362306a36Sopenharmony_cionline_all_hot_pluggable_cpus
22462306a36Sopenharmony_ci
22562306a36Sopenharmony_ciexit $retval
226