18c2ecf20Sopenharmony_ci#!/bin/bash 28c2ecf20Sopenharmony_ci# SPDX-License-Identifier: GPL-2.0 38c2ecf20Sopenharmony_ci 48c2ecf20Sopenharmony_ciSYSFS= 58c2ecf20Sopenharmony_ci 68c2ecf20Sopenharmony_ci# Kselftest framework requirement - SKIP code is 4. 78c2ecf20Sopenharmony_ciksft_skip=4 88c2ecf20Sopenharmony_ci 98c2ecf20Sopenharmony_ciprerequisite() 108c2ecf20Sopenharmony_ci{ 118c2ecf20Sopenharmony_ci msg="skip all tests:" 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_ci if [ $UID != 0 ]; then 148c2ecf20Sopenharmony_ci echo $msg must be run as root >&2 158c2ecf20Sopenharmony_ci exit $ksft_skip 168c2ecf20Sopenharmony_ci fi 178c2ecf20Sopenharmony_ci 188c2ecf20Sopenharmony_ci SYSFS=`mount -t sysfs | head -1 | awk '{ print $3 }'` 198c2ecf20Sopenharmony_ci 208c2ecf20Sopenharmony_ci if [ ! -d "$SYSFS" ]; then 218c2ecf20Sopenharmony_ci echo $msg sysfs is not mounted >&2 228c2ecf20Sopenharmony_ci exit $ksft_skip 238c2ecf20Sopenharmony_ci fi 248c2ecf20Sopenharmony_ci 258c2ecf20Sopenharmony_ci if ! ls $SYSFS/devices/system/memory/memory* > /dev/null 2>&1; then 268c2ecf20Sopenharmony_ci echo $msg memory hotplug is not supported >&2 278c2ecf20Sopenharmony_ci exit $ksft_skip 288c2ecf20Sopenharmony_ci fi 298c2ecf20Sopenharmony_ci 308c2ecf20Sopenharmony_ci if ! grep -q 1 $SYSFS/devices/system/memory/memory*/removable; then 318c2ecf20Sopenharmony_ci echo $msg no hot-pluggable memory >&2 328c2ecf20Sopenharmony_ci exit $ksft_skip 338c2ecf20Sopenharmony_ci fi 348c2ecf20Sopenharmony_ci} 358c2ecf20Sopenharmony_ci 368c2ecf20Sopenharmony_ci# 378c2ecf20Sopenharmony_ci# list all hot-pluggable memory 388c2ecf20Sopenharmony_ci# 398c2ecf20Sopenharmony_cihotpluggable_memory() 408c2ecf20Sopenharmony_ci{ 418c2ecf20Sopenharmony_ci local state=${1:-.\*} 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_ci for memory in $SYSFS/devices/system/memory/memory*; do 448c2ecf20Sopenharmony_ci if grep -q 1 $memory/removable && 458c2ecf20Sopenharmony_ci grep -q $state $memory/state; then 468c2ecf20Sopenharmony_ci echo ${memory##/*/memory} 478c2ecf20Sopenharmony_ci fi 488c2ecf20Sopenharmony_ci done 498c2ecf20Sopenharmony_ci} 508c2ecf20Sopenharmony_ci 518c2ecf20Sopenharmony_cihotpluggable_offline_memory() 528c2ecf20Sopenharmony_ci{ 538c2ecf20Sopenharmony_ci hotpluggable_memory offline 548c2ecf20Sopenharmony_ci} 558c2ecf20Sopenharmony_ci 568c2ecf20Sopenharmony_cihotpluggable_online_memory() 578c2ecf20Sopenharmony_ci{ 588c2ecf20Sopenharmony_ci hotpluggable_memory online 598c2ecf20Sopenharmony_ci} 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_cimemory_is_online() 628c2ecf20Sopenharmony_ci{ 638c2ecf20Sopenharmony_ci grep -q online $SYSFS/devices/system/memory/memory$1/state 648c2ecf20Sopenharmony_ci} 658c2ecf20Sopenharmony_ci 668c2ecf20Sopenharmony_cimemory_is_offline() 678c2ecf20Sopenharmony_ci{ 688c2ecf20Sopenharmony_ci grep -q offline $SYSFS/devices/system/memory/memory$1/state 698c2ecf20Sopenharmony_ci} 708c2ecf20Sopenharmony_ci 718c2ecf20Sopenharmony_cionline_memory() 728c2ecf20Sopenharmony_ci{ 738c2ecf20Sopenharmony_ci echo online > $SYSFS/devices/system/memory/memory$1/state 748c2ecf20Sopenharmony_ci} 758c2ecf20Sopenharmony_ci 768c2ecf20Sopenharmony_cioffline_memory() 778c2ecf20Sopenharmony_ci{ 788c2ecf20Sopenharmony_ci echo offline > $SYSFS/devices/system/memory/memory$1/state 798c2ecf20Sopenharmony_ci} 808c2ecf20Sopenharmony_ci 818c2ecf20Sopenharmony_cionline_memory_expect_success() 828c2ecf20Sopenharmony_ci{ 838c2ecf20Sopenharmony_ci local memory=$1 848c2ecf20Sopenharmony_ci 858c2ecf20Sopenharmony_ci if ! online_memory $memory; then 868c2ecf20Sopenharmony_ci echo $FUNCNAME $memory: unexpected fail >&2 878c2ecf20Sopenharmony_ci return 1 888c2ecf20Sopenharmony_ci elif ! memory_is_online $memory; then 898c2ecf20Sopenharmony_ci echo $FUNCNAME $memory: unexpected offline >&2 908c2ecf20Sopenharmony_ci return 1 918c2ecf20Sopenharmony_ci fi 928c2ecf20Sopenharmony_ci return 0 938c2ecf20Sopenharmony_ci} 948c2ecf20Sopenharmony_ci 958c2ecf20Sopenharmony_cionline_memory_expect_fail() 968c2ecf20Sopenharmony_ci{ 978c2ecf20Sopenharmony_ci local memory=$1 988c2ecf20Sopenharmony_ci 998c2ecf20Sopenharmony_ci if online_memory $memory 2> /dev/null; then 1008c2ecf20Sopenharmony_ci echo $FUNCNAME $memory: unexpected success >&2 1018c2ecf20Sopenharmony_ci return 1 1028c2ecf20Sopenharmony_ci elif ! memory_is_offline $memory; then 1038c2ecf20Sopenharmony_ci echo $FUNCNAME $memory: unexpected online >&2 1048c2ecf20Sopenharmony_ci return 1 1058c2ecf20Sopenharmony_ci fi 1068c2ecf20Sopenharmony_ci return 0 1078c2ecf20Sopenharmony_ci} 1088c2ecf20Sopenharmony_ci 1098c2ecf20Sopenharmony_cioffline_memory_expect_success() 1108c2ecf20Sopenharmony_ci{ 1118c2ecf20Sopenharmony_ci local memory=$1 1128c2ecf20Sopenharmony_ci 1138c2ecf20Sopenharmony_ci if ! offline_memory $memory; then 1148c2ecf20Sopenharmony_ci echo $FUNCNAME $memory: unexpected fail >&2 1158c2ecf20Sopenharmony_ci return 1 1168c2ecf20Sopenharmony_ci elif ! memory_is_offline $memory; then 1178c2ecf20Sopenharmony_ci echo $FUNCNAME $memory: unexpected offline >&2 1188c2ecf20Sopenharmony_ci return 1 1198c2ecf20Sopenharmony_ci fi 1208c2ecf20Sopenharmony_ci return 0 1218c2ecf20Sopenharmony_ci} 1228c2ecf20Sopenharmony_ci 1238c2ecf20Sopenharmony_cioffline_memory_expect_fail() 1248c2ecf20Sopenharmony_ci{ 1258c2ecf20Sopenharmony_ci local memory=$1 1268c2ecf20Sopenharmony_ci 1278c2ecf20Sopenharmony_ci if offline_memory $memory 2> /dev/null; then 1288c2ecf20Sopenharmony_ci echo $FUNCNAME $memory: unexpected success >&2 1298c2ecf20Sopenharmony_ci return 1 1308c2ecf20Sopenharmony_ci elif ! memory_is_online $memory; then 1318c2ecf20Sopenharmony_ci echo $FUNCNAME $memory: unexpected offline >&2 1328c2ecf20Sopenharmony_ci return 1 1338c2ecf20Sopenharmony_ci fi 1348c2ecf20Sopenharmony_ci return 0 1358c2ecf20Sopenharmony_ci} 1368c2ecf20Sopenharmony_ci 1378c2ecf20Sopenharmony_cierror=-12 1388c2ecf20Sopenharmony_cipriority=0 1398c2ecf20Sopenharmony_ci# Run with default of ratio=2 for Kselftest run 1408c2ecf20Sopenharmony_ciratio=2 1418c2ecf20Sopenharmony_ciretval=0 1428c2ecf20Sopenharmony_ci 1438c2ecf20Sopenharmony_ciwhile getopts e:hp:r: opt; do 1448c2ecf20Sopenharmony_ci case $opt in 1458c2ecf20Sopenharmony_ci e) 1468c2ecf20Sopenharmony_ci error=$OPTARG 1478c2ecf20Sopenharmony_ci ;; 1488c2ecf20Sopenharmony_ci h) 1498c2ecf20Sopenharmony_ci echo "Usage $0 [ -e errno ] [ -p notifier-priority ] [ -r percent-of-memory-to-offline ]" 1508c2ecf20Sopenharmony_ci exit 1518c2ecf20Sopenharmony_ci ;; 1528c2ecf20Sopenharmony_ci p) 1538c2ecf20Sopenharmony_ci priority=$OPTARG 1548c2ecf20Sopenharmony_ci ;; 1558c2ecf20Sopenharmony_ci r) 1568c2ecf20Sopenharmony_ci ratio=$OPTARG 1578c2ecf20Sopenharmony_ci if [ "$ratio" -gt 100 ] || [ "$ratio" -lt 0 ]; then 1588c2ecf20Sopenharmony_ci echo "The percentage should be an integer within 0~100 range" 1598c2ecf20Sopenharmony_ci exit 1 1608c2ecf20Sopenharmony_ci fi 1618c2ecf20Sopenharmony_ci ;; 1628c2ecf20Sopenharmony_ci esac 1638c2ecf20Sopenharmony_cidone 1648c2ecf20Sopenharmony_ci 1658c2ecf20Sopenharmony_ciif ! [ "$error" -ge -4095 -a "$error" -lt 0 ]; then 1668c2ecf20Sopenharmony_ci echo "error code must be -4095 <= errno < 0" >&2 1678c2ecf20Sopenharmony_ci exit 1 1688c2ecf20Sopenharmony_cifi 1698c2ecf20Sopenharmony_ci 1708c2ecf20Sopenharmony_ciprerequisite 1718c2ecf20Sopenharmony_ci 1728c2ecf20Sopenharmony_ciecho "Test scope: $ratio% hotplug memory" 1738c2ecf20Sopenharmony_ci 1748c2ecf20Sopenharmony_ci# 1758c2ecf20Sopenharmony_ci# Online all hot-pluggable memory 1768c2ecf20Sopenharmony_ci# 1778c2ecf20Sopenharmony_cihotpluggable_num=`hotpluggable_offline_memory | wc -l` 1788c2ecf20Sopenharmony_ciecho -e "\t online all hot-pluggable memory in offline state:" 1798c2ecf20Sopenharmony_ciif [ "$hotpluggable_num" -gt 0 ]; then 1808c2ecf20Sopenharmony_ci for memory in `hotpluggable_offline_memory`; do 1818c2ecf20Sopenharmony_ci echo "offline->online memory$memory" 1828c2ecf20Sopenharmony_ci if ! online_memory_expect_success $memory; then 1838c2ecf20Sopenharmony_ci retval=1 1848c2ecf20Sopenharmony_ci fi 1858c2ecf20Sopenharmony_ci done 1868c2ecf20Sopenharmony_cielse 1878c2ecf20Sopenharmony_ci echo -e "\t\t SKIPPED - no hot-pluggable memory in offline state" 1888c2ecf20Sopenharmony_cifi 1898c2ecf20Sopenharmony_ci 1908c2ecf20Sopenharmony_ci# 1918c2ecf20Sopenharmony_ci# Offline $ratio percent of hot-pluggable memory 1928c2ecf20Sopenharmony_ci# 1938c2ecf20Sopenharmony_cihotpluggable_num=`hotpluggable_online_memory | wc -l` 1948c2ecf20Sopenharmony_citarget=`echo "a=$hotpluggable_num*$ratio; if ( a%100 ) a/100+1 else a/100" | bc` 1958c2ecf20Sopenharmony_ciecho -e "\t offline $ratio% hot-pluggable memory in online state" 1968c2ecf20Sopenharmony_ciecho -e "\t trying to offline $target out of $hotpluggable_num memory block(s):" 1978c2ecf20Sopenharmony_cifor memory in `hotpluggable_online_memory`; do 1988c2ecf20Sopenharmony_ci if [ "$target" -gt 0 ]; then 1998c2ecf20Sopenharmony_ci echo "online->offline memory$memory" 2008c2ecf20Sopenharmony_ci if offline_memory_expect_success $memory; then 2018c2ecf20Sopenharmony_ci target=$(($target - 1)) 2028c2ecf20Sopenharmony_ci fi 2038c2ecf20Sopenharmony_ci fi 2048c2ecf20Sopenharmony_cidone 2058c2ecf20Sopenharmony_ciif [ "$target" -gt 0 ]; then 2068c2ecf20Sopenharmony_ci retval=1 2078c2ecf20Sopenharmony_ci echo -e "\t\t FAILED - unable to offline some memory blocks, device busy?" 2088c2ecf20Sopenharmony_cifi 2098c2ecf20Sopenharmony_ci 2108c2ecf20Sopenharmony_ci# 2118c2ecf20Sopenharmony_ci# Online all hot-pluggable memory again 2128c2ecf20Sopenharmony_ci# 2138c2ecf20Sopenharmony_cihotpluggable_num=`hotpluggable_offline_memory | wc -l` 2148c2ecf20Sopenharmony_ciecho -e "\t online all hot-pluggable memory in offline state:" 2158c2ecf20Sopenharmony_ciif [ "$hotpluggable_num" -gt 0 ]; then 2168c2ecf20Sopenharmony_ci for memory in `hotpluggable_offline_memory`; do 2178c2ecf20Sopenharmony_ci echo "offline->online memory$memory" 2188c2ecf20Sopenharmony_ci if ! online_memory_expect_success $memory; then 2198c2ecf20Sopenharmony_ci retval=1 2208c2ecf20Sopenharmony_ci fi 2218c2ecf20Sopenharmony_ci done 2228c2ecf20Sopenharmony_cielse 2238c2ecf20Sopenharmony_ci echo -e "\t\t SKIPPED - no hot-pluggable memory in offline state" 2248c2ecf20Sopenharmony_cifi 2258c2ecf20Sopenharmony_ci 2268c2ecf20Sopenharmony_ci# 2278c2ecf20Sopenharmony_ci# Test with memory notifier error injection 2288c2ecf20Sopenharmony_ci# 2298c2ecf20Sopenharmony_ci 2308c2ecf20Sopenharmony_ciDEBUGFS=`mount -t debugfs | head -1 | awk '{ print $3 }'` 2318c2ecf20Sopenharmony_ciNOTIFIER_ERR_INJECT_DIR=$DEBUGFS/notifier-error-inject/memory 2328c2ecf20Sopenharmony_ci 2338c2ecf20Sopenharmony_ciprerequisite_extra() 2348c2ecf20Sopenharmony_ci{ 2358c2ecf20Sopenharmony_ci msg="skip extra tests:" 2368c2ecf20Sopenharmony_ci 2378c2ecf20Sopenharmony_ci /sbin/modprobe -q -r memory-notifier-error-inject 2388c2ecf20Sopenharmony_ci /sbin/modprobe -q memory-notifier-error-inject priority=$priority 2398c2ecf20Sopenharmony_ci 2408c2ecf20Sopenharmony_ci if [ ! -d "$DEBUGFS" ]; then 2418c2ecf20Sopenharmony_ci echo $msg debugfs is not mounted >&2 2428c2ecf20Sopenharmony_ci exit $retval 2438c2ecf20Sopenharmony_ci fi 2448c2ecf20Sopenharmony_ci 2458c2ecf20Sopenharmony_ci if [ ! -d $NOTIFIER_ERR_INJECT_DIR ]; then 2468c2ecf20Sopenharmony_ci echo $msg memory-notifier-error-inject module is not available >&2 2478c2ecf20Sopenharmony_ci exit $retval 2488c2ecf20Sopenharmony_ci fi 2498c2ecf20Sopenharmony_ci} 2508c2ecf20Sopenharmony_ci 2518c2ecf20Sopenharmony_ciecho -e "\t Test with memory notifier error injection" 2528c2ecf20Sopenharmony_ciprerequisite_extra 2538c2ecf20Sopenharmony_ci 2548c2ecf20Sopenharmony_ci# 2558c2ecf20Sopenharmony_ci# Offline $ratio percent of hot-pluggable memory 2568c2ecf20Sopenharmony_ci# 2578c2ecf20Sopenharmony_ciecho 0 > $NOTIFIER_ERR_INJECT_DIR/actions/MEM_GOING_OFFLINE/error 2588c2ecf20Sopenharmony_cifor memory in `hotpluggable_online_memory`; do 2598c2ecf20Sopenharmony_ci if [ $((RANDOM % 100)) -lt $ratio ]; then 2608c2ecf20Sopenharmony_ci offline_memory_expect_success $memory 2618c2ecf20Sopenharmony_ci fi 2628c2ecf20Sopenharmony_cidone 2638c2ecf20Sopenharmony_ci 2648c2ecf20Sopenharmony_ci# 2658c2ecf20Sopenharmony_ci# Test memory hot-add error handling (offline => online) 2668c2ecf20Sopenharmony_ci# 2678c2ecf20Sopenharmony_ciecho $error > $NOTIFIER_ERR_INJECT_DIR/actions/MEM_GOING_ONLINE/error 2688c2ecf20Sopenharmony_cifor memory in `hotpluggable_offline_memory`; do 2698c2ecf20Sopenharmony_ci online_memory_expect_fail $memory 2708c2ecf20Sopenharmony_cidone 2718c2ecf20Sopenharmony_ci 2728c2ecf20Sopenharmony_ci# 2738c2ecf20Sopenharmony_ci# Online all hot-pluggable memory 2748c2ecf20Sopenharmony_ci# 2758c2ecf20Sopenharmony_ciecho 0 > $NOTIFIER_ERR_INJECT_DIR/actions/MEM_GOING_ONLINE/error 2768c2ecf20Sopenharmony_cifor memory in `hotpluggable_offline_memory`; do 2778c2ecf20Sopenharmony_ci online_memory_expect_success $memory 2788c2ecf20Sopenharmony_cidone 2798c2ecf20Sopenharmony_ci 2808c2ecf20Sopenharmony_ci# 2818c2ecf20Sopenharmony_ci# Test memory hot-remove error handling (online => offline) 2828c2ecf20Sopenharmony_ci# 2838c2ecf20Sopenharmony_ciecho $error > $NOTIFIER_ERR_INJECT_DIR/actions/MEM_GOING_OFFLINE/error 2848c2ecf20Sopenharmony_cifor memory in `hotpluggable_online_memory`; do 2858c2ecf20Sopenharmony_ci offline_memory_expect_fail $memory 2868c2ecf20Sopenharmony_cidone 2878c2ecf20Sopenharmony_ci 2888c2ecf20Sopenharmony_ciecho 0 > $NOTIFIER_ERR_INJECT_DIR/actions/MEM_GOING_OFFLINE/error 2898c2ecf20Sopenharmony_ci/sbin/modprobe -q -r memory-notifier-error-inject 2908c2ecf20Sopenharmony_ci 2918c2ecf20Sopenharmony_ciexit $retval 292