Back to home page

OSCL-LXR

 
 

    


0001 #!/bin/bash
0002 # SPDX-License-Identifier: GPL-2.0
0003 
0004 SYSFS=
0005 
0006 # Kselftest framework requirement - SKIP code is 4.
0007 ksft_skip=4
0008 
0009 prerequisite()
0010 {
0011         msg="skip all tests:"
0012 
0013         if [ $UID != 0 ]; then
0014                 echo $msg must be run as root >&2
0015                 exit $ksft_skip
0016         fi
0017 
0018         SYSFS=`mount -t sysfs | head -1 | awk '{ print $3 }'`
0019 
0020         if [ ! -d "$SYSFS" ]; then
0021                 echo $msg sysfs is not mounted >&2
0022                 exit $ksft_skip
0023         fi
0024 
0025         if ! ls $SYSFS/devices/system/memory/memory* > /dev/null 2>&1; then
0026                 echo $msg memory hotplug is not supported >&2
0027                 exit $ksft_skip
0028         fi
0029 
0030         if ! grep -q 1 $SYSFS/devices/system/memory/memory*/removable; then
0031                 echo $msg no hot-pluggable memory >&2
0032                 exit $ksft_skip
0033         fi
0034 }
0035 
0036 #
0037 # list all hot-pluggable memory
0038 #
0039 hotpluggable_memory()
0040 {
0041         local state=${1:-.\*}
0042 
0043         for memory in $SYSFS/devices/system/memory/memory*; do
0044                 if grep -q 1 $memory/removable &&
0045                    grep -q $state $memory/state; then
0046                         echo ${memory##/*/memory}
0047                 fi
0048         done
0049 }
0050 
0051 hotpluggable_offline_memory()
0052 {
0053         hotpluggable_memory offline
0054 }
0055 
0056 hotpluggable_online_memory()
0057 {
0058         hotpluggable_memory online
0059 }
0060 
0061 memory_is_online()
0062 {
0063         grep -q online $SYSFS/devices/system/memory/memory$1/state
0064 }
0065 
0066 memory_is_offline()
0067 {
0068         grep -q offline $SYSFS/devices/system/memory/memory$1/state
0069 }
0070 
0071 online_memory()
0072 {
0073         echo online > $SYSFS/devices/system/memory/memory$1/state
0074 }
0075 
0076 offline_memory()
0077 {
0078         echo offline > $SYSFS/devices/system/memory/memory$1/state
0079 }
0080 
0081 online_memory_expect_success()
0082 {
0083         local memory=$1
0084 
0085         if ! online_memory $memory; then
0086                 echo $FUNCNAME $memory: unexpected fail >&2
0087                 return 1
0088         elif ! memory_is_online $memory; then
0089                 echo $FUNCNAME $memory: unexpected offline >&2
0090                 return 1
0091         fi
0092         return 0
0093 }
0094 
0095 online_memory_expect_fail()
0096 {
0097         local memory=$1
0098 
0099         if online_memory $memory 2> /dev/null; then
0100                 echo $FUNCNAME $memory: unexpected success >&2
0101                 return 1
0102         elif ! memory_is_offline $memory; then
0103                 echo $FUNCNAME $memory: unexpected online >&2
0104                 return 1
0105         fi
0106         return 0
0107 }
0108 
0109 offline_memory_expect_success()
0110 {
0111         local memory=$1
0112 
0113         if ! offline_memory $memory; then
0114                 echo $FUNCNAME $memory: unexpected fail >&2
0115                 return 1
0116         elif ! memory_is_offline $memory; then
0117                 echo $FUNCNAME $memory: unexpected offline >&2
0118                 return 1
0119         fi
0120         return 0
0121 }
0122 
0123 offline_memory_expect_fail()
0124 {
0125         local memory=$1
0126 
0127         if offline_memory $memory 2> /dev/null; then
0128                 echo $FUNCNAME $memory: unexpected success >&2
0129                 return 1
0130         elif ! memory_is_online $memory; then
0131                 echo $FUNCNAME $memory: unexpected offline >&2
0132                 return 1
0133         fi
0134         return 0
0135 }
0136 
0137 error=-12
0138 priority=0
0139 # Run with default of ratio=2 for Kselftest run
0140 ratio=2
0141 retval=0
0142 
0143 while getopts e:hp:r: opt; do
0144         case $opt in
0145         e)
0146                 error=$OPTARG
0147                 ;;
0148         h)
0149                 echo "Usage $0 [ -e errno ] [ -p notifier-priority ] [ -r percent-of-memory-to-offline ]"
0150                 exit
0151                 ;;
0152         p)
0153                 priority=$OPTARG
0154                 ;;
0155         r)
0156                 ratio=$OPTARG
0157                 if [ "$ratio" -gt 100 ] || [ "$ratio" -lt 0 ]; then
0158                         echo "The percentage should be an integer within 0~100 range"
0159                         exit 1
0160                 fi
0161                 ;;
0162         esac
0163 done
0164 
0165 if ! [ "$error" -ge -4095 -a "$error" -lt 0 ]; then
0166         echo "error code must be -4095 <= errno < 0" >&2
0167         exit 1
0168 fi
0169 
0170 prerequisite
0171 
0172 echo "Test scope: $ratio% hotplug memory"
0173 
0174 #
0175 # Online all hot-pluggable memory
0176 #
0177 hotpluggable_num=`hotpluggable_offline_memory | wc -l`
0178 echo -e "\t online all hot-pluggable memory in offline state:"
0179 if [ "$hotpluggable_num" -gt 0 ]; then
0180         for memory in `hotpluggable_offline_memory`; do
0181                 echo "offline->online memory$memory"
0182                 if ! online_memory_expect_success $memory; then
0183                         retval=1
0184                 fi
0185         done
0186 else
0187         echo -e "\t\t SKIPPED - no hot-pluggable memory in offline state"
0188 fi
0189 
0190 #
0191 # Offline $ratio percent of hot-pluggable memory
0192 #
0193 hotpluggable_num=`hotpluggable_online_memory | wc -l`
0194 target=`echo "a=$hotpluggable_num*$ratio; if ( a%100 ) a/100+1 else a/100" | bc`
0195 echo -e "\t offline $ratio% hot-pluggable memory in online state"
0196 echo -e "\t trying to offline $target out of $hotpluggable_num memory block(s):"
0197 for memory in `hotpluggable_online_memory`; do
0198         if [ "$target" -gt 0 ]; then
0199                 echo "online->offline memory$memory"
0200                 if offline_memory_expect_success $memory; then
0201                         target=$(($target - 1))
0202                 fi
0203         fi
0204 done
0205 if [ "$target" -gt 0 ]; then
0206         retval=1
0207         echo -e "\t\t FAILED - unable to offline some memory blocks, device busy?"
0208 fi
0209 
0210 #
0211 # Online all hot-pluggable memory again
0212 #
0213 hotpluggable_num=`hotpluggable_offline_memory | wc -l`
0214 echo -e "\t online all hot-pluggable memory in offline state:"
0215 if [ "$hotpluggable_num" -gt 0 ]; then
0216         for memory in `hotpluggable_offline_memory`; do
0217                 echo "offline->online memory$memory"
0218                 if ! online_memory_expect_success $memory; then
0219                         retval=1
0220                 fi
0221         done
0222 else
0223         echo -e "\t\t SKIPPED - no hot-pluggable memory in offline state"
0224 fi
0225 
0226 #
0227 # Test with memory notifier error injection
0228 #
0229 
0230 DEBUGFS=`mount -t debugfs | head -1 | awk '{ print $3 }'`
0231 NOTIFIER_ERR_INJECT_DIR=$DEBUGFS/notifier-error-inject/memory
0232 
0233 prerequisite_extra()
0234 {
0235         msg="skip extra tests:"
0236 
0237         /sbin/modprobe -q -r memory-notifier-error-inject
0238         /sbin/modprobe -q memory-notifier-error-inject priority=$priority
0239 
0240         if [ ! -d "$DEBUGFS" ]; then
0241                 echo $msg debugfs is not mounted >&2
0242                 exit $retval
0243         fi
0244 
0245         if [ ! -d $NOTIFIER_ERR_INJECT_DIR ]; then
0246                 echo $msg memory-notifier-error-inject module is not available >&2
0247                 exit $retval
0248         fi
0249 }
0250 
0251 echo -e "\t Test with memory notifier error injection"
0252 prerequisite_extra
0253 
0254 #
0255 # Offline $ratio percent of hot-pluggable memory
0256 #
0257 echo 0 > $NOTIFIER_ERR_INJECT_DIR/actions/MEM_GOING_OFFLINE/error
0258 for memory in `hotpluggable_online_memory`; do
0259         if [ $((RANDOM % 100)) -lt $ratio ]; then
0260                 offline_memory_expect_success $memory
0261         fi
0262 done
0263 
0264 #
0265 # Test memory hot-add error handling (offline => online)
0266 #
0267 echo $error > $NOTIFIER_ERR_INJECT_DIR/actions/MEM_GOING_ONLINE/error
0268 for memory in `hotpluggable_offline_memory`; do
0269         online_memory_expect_fail $memory
0270 done
0271 
0272 #
0273 # Online all hot-pluggable memory
0274 #
0275 echo 0 > $NOTIFIER_ERR_INJECT_DIR/actions/MEM_GOING_ONLINE/error
0276 for memory in `hotpluggable_offline_memory`; do
0277         online_memory_expect_success $memory
0278 done
0279 
0280 #
0281 # Test memory hot-remove error handling (online => offline)
0282 #
0283 echo $error > $NOTIFIER_ERR_INJECT_DIR/actions/MEM_GOING_OFFLINE/error
0284 for memory in `hotpluggable_online_memory`; do
0285         if [ $((RANDOM % 100)) -lt $ratio ]; then
0286                 offline_memory_expect_fail $memory
0287         fi
0288 done
0289 
0290 echo 0 > $NOTIFIER_ERR_INJECT_DIR/actions/MEM_GOING_OFFLINE/error
0291 /sbin/modprobe -q -r memory-notifier-error-inject
0292 
0293 exit $retval