mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2025-01-03 20:34:58 +08:00
0c0f6299ba
While the offline memory test obey ratio limit, the same test with error injection does not and tries to offline all the hotpluggable memory, spamming system logs with hundreds of thousands of dump_page() entries, slowing system down (to the point the test itself timesout and gets terminated) and excessive fs occupation: ... [ 9784.393354] page:c00c0000007d1b40 refcount:3 mapcount:0 mapping:c0000001fc03e950 index:0xe7b [ 9784.393355] def_blk_aops [ 9784.393356] flags: 0x3ffff800002062(referenced|active|workingset|private) [ 9784.393358] raw: 003ffff800002062 c0000001b9343a68 c0000001b9343a68 c0000001fc03e950 [ 9784.393359] raw: 0000000000000e7b c000000006607b18 00000003ffffffff c00000000490d000 [ 9784.393359] page dumped because: migration failure [ 9784.393360] page->mem_cgroup:c00000000490d000 [ 9784.393416] migrating pfn 1f46d failed ret:1 ... $ grep "page dumped because: migration failure" /var/log/kern.log | wc -l 2405558 $ ls -la /var/log/kern.log -rw-r----- 1 syslog adm 2256109539 Jun 30 14:19 /var/log/kern.log Signed-off-by: Paolo Pisati <paolo.pisati@canonical.com> Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com> Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
294 lines
6.2 KiB
Bash
Executable File
294 lines
6.2 KiB
Bash
Executable File
#!/bin/bash
|
|
# SPDX-License-Identifier: GPL-2.0
|
|
|
|
SYSFS=
|
|
|
|
# Kselftest framework requirement - SKIP code is 4.
|
|
ksft_skip=4
|
|
|
|
prerequisite()
|
|
{
|
|
msg="skip all tests:"
|
|
|
|
if [ $UID != 0 ]; then
|
|
echo $msg must be run as root >&2
|
|
exit $ksft_skip
|
|
fi
|
|
|
|
SYSFS=`mount -t sysfs | head -1 | awk '{ print $3 }'`
|
|
|
|
if [ ! -d "$SYSFS" ]; then
|
|
echo $msg sysfs is not mounted >&2
|
|
exit $ksft_skip
|
|
fi
|
|
|
|
if ! ls $SYSFS/devices/system/memory/memory* > /dev/null 2>&1; then
|
|
echo $msg memory hotplug is not supported >&2
|
|
exit $ksft_skip
|
|
fi
|
|
|
|
if ! grep -q 1 $SYSFS/devices/system/memory/memory*/removable; then
|
|
echo $msg no hot-pluggable memory >&2
|
|
exit $ksft_skip
|
|
fi
|
|
}
|
|
|
|
#
|
|
# list all hot-pluggable memory
|
|
#
|
|
hotpluggable_memory()
|
|
{
|
|
local state=${1:-.\*}
|
|
|
|
for memory in $SYSFS/devices/system/memory/memory*; do
|
|
if grep -q 1 $memory/removable &&
|
|
grep -q $state $memory/state; then
|
|
echo ${memory##/*/memory}
|
|
fi
|
|
done
|
|
}
|
|
|
|
hotpluggable_offline_memory()
|
|
{
|
|
hotpluggable_memory offline
|
|
}
|
|
|
|
hotpluggable_online_memory()
|
|
{
|
|
hotpluggable_memory online
|
|
}
|
|
|
|
memory_is_online()
|
|
{
|
|
grep -q online $SYSFS/devices/system/memory/memory$1/state
|
|
}
|
|
|
|
memory_is_offline()
|
|
{
|
|
grep -q offline $SYSFS/devices/system/memory/memory$1/state
|
|
}
|
|
|
|
online_memory()
|
|
{
|
|
echo online > $SYSFS/devices/system/memory/memory$1/state
|
|
}
|
|
|
|
offline_memory()
|
|
{
|
|
echo offline > $SYSFS/devices/system/memory/memory$1/state
|
|
}
|
|
|
|
online_memory_expect_success()
|
|
{
|
|
local memory=$1
|
|
|
|
if ! online_memory $memory; then
|
|
echo $FUNCNAME $memory: unexpected fail >&2
|
|
return 1
|
|
elif ! memory_is_online $memory; then
|
|
echo $FUNCNAME $memory: unexpected offline >&2
|
|
return 1
|
|
fi
|
|
return 0
|
|
}
|
|
|
|
online_memory_expect_fail()
|
|
{
|
|
local memory=$1
|
|
|
|
if online_memory $memory 2> /dev/null; then
|
|
echo $FUNCNAME $memory: unexpected success >&2
|
|
return 1
|
|
elif ! memory_is_offline $memory; then
|
|
echo $FUNCNAME $memory: unexpected online >&2
|
|
return 1
|
|
fi
|
|
return 0
|
|
}
|
|
|
|
offline_memory_expect_success()
|
|
{
|
|
local memory=$1
|
|
|
|
if ! offline_memory $memory; then
|
|
echo $FUNCNAME $memory: unexpected fail >&2
|
|
return 1
|
|
elif ! memory_is_offline $memory; then
|
|
echo $FUNCNAME $memory: unexpected offline >&2
|
|
return 1
|
|
fi
|
|
return 0
|
|
}
|
|
|
|
offline_memory_expect_fail()
|
|
{
|
|
local memory=$1
|
|
|
|
if offline_memory $memory 2> /dev/null; then
|
|
echo $FUNCNAME $memory: unexpected success >&2
|
|
return 1
|
|
elif ! memory_is_online $memory; then
|
|
echo $FUNCNAME $memory: unexpected offline >&2
|
|
return 1
|
|
fi
|
|
return 0
|
|
}
|
|
|
|
error=-12
|
|
priority=0
|
|
# Run with default of ratio=2 for Kselftest run
|
|
ratio=2
|
|
retval=0
|
|
|
|
while getopts e:hp:r: opt; do
|
|
case $opt in
|
|
e)
|
|
error=$OPTARG
|
|
;;
|
|
h)
|
|
echo "Usage $0 [ -e errno ] [ -p notifier-priority ] [ -r percent-of-memory-to-offline ]"
|
|
exit
|
|
;;
|
|
p)
|
|
priority=$OPTARG
|
|
;;
|
|
r)
|
|
ratio=$OPTARG
|
|
if [ "$ratio" -gt 100 ] || [ "$ratio" -lt 0 ]; then
|
|
echo "The percentage should be an integer within 0~100 range"
|
|
exit 1
|
|
fi
|
|
;;
|
|
esac
|
|
done
|
|
|
|
if ! [ "$error" -ge -4095 -a "$error" -lt 0 ]; then
|
|
echo "error code must be -4095 <= errno < 0" >&2
|
|
exit 1
|
|
fi
|
|
|
|
prerequisite
|
|
|
|
echo "Test scope: $ratio% hotplug memory"
|
|
|
|
#
|
|
# Online all hot-pluggable memory
|
|
#
|
|
hotpluggable_num=`hotpluggable_offline_memory | wc -l`
|
|
echo -e "\t online all hot-pluggable memory in offline state:"
|
|
if [ "$hotpluggable_num" -gt 0 ]; then
|
|
for memory in `hotpluggable_offline_memory`; do
|
|
echo "offline->online memory$memory"
|
|
if ! online_memory_expect_success $memory; then
|
|
retval=1
|
|
fi
|
|
done
|
|
else
|
|
echo -e "\t\t SKIPPED - no hot-pluggable memory in offline state"
|
|
fi
|
|
|
|
#
|
|
# Offline $ratio percent of hot-pluggable memory
|
|
#
|
|
hotpluggable_num=`hotpluggable_online_memory | wc -l`
|
|
target=`echo "a=$hotpluggable_num*$ratio; if ( a%100 ) a/100+1 else a/100" | bc`
|
|
echo -e "\t offline $ratio% hot-pluggable memory in online state"
|
|
echo -e "\t trying to offline $target out of $hotpluggable_num memory block(s):"
|
|
for memory in `hotpluggable_online_memory`; do
|
|
if [ "$target" -gt 0 ]; then
|
|
echo "online->offline memory$memory"
|
|
if offline_memory_expect_success $memory; then
|
|
target=$(($target - 1))
|
|
fi
|
|
fi
|
|
done
|
|
if [ "$target" -gt 0 ]; then
|
|
retval=1
|
|
echo -e "\t\t FAILED - unable to offline some memory blocks, device busy?"
|
|
fi
|
|
|
|
#
|
|
# Online all hot-pluggable memory again
|
|
#
|
|
hotpluggable_num=`hotpluggable_offline_memory | wc -l`
|
|
echo -e "\t online all hot-pluggable memory in offline state:"
|
|
if [ "$hotpluggable_num" -gt 0 ]; then
|
|
for memory in `hotpluggable_offline_memory`; do
|
|
echo "offline->online memory$memory"
|
|
if ! online_memory_expect_success $memory; then
|
|
retval=1
|
|
fi
|
|
done
|
|
else
|
|
echo -e "\t\t SKIPPED - no hot-pluggable memory in offline state"
|
|
fi
|
|
|
|
#
|
|
# Test with memory notifier error injection
|
|
#
|
|
|
|
DEBUGFS=`mount -t debugfs | head -1 | awk '{ print $3 }'`
|
|
NOTIFIER_ERR_INJECT_DIR=$DEBUGFS/notifier-error-inject/memory
|
|
|
|
prerequisite_extra()
|
|
{
|
|
msg="skip extra tests:"
|
|
|
|
/sbin/modprobe -q -r memory-notifier-error-inject
|
|
/sbin/modprobe -q memory-notifier-error-inject priority=$priority
|
|
|
|
if [ ! -d "$DEBUGFS" ]; then
|
|
echo $msg debugfs is not mounted >&2
|
|
exit $retval
|
|
fi
|
|
|
|
if [ ! -d $NOTIFIER_ERR_INJECT_DIR ]; then
|
|
echo $msg memory-notifier-error-inject module is not available >&2
|
|
exit $retval
|
|
fi
|
|
}
|
|
|
|
echo -e "\t Test with memory notifier error injection"
|
|
prerequisite_extra
|
|
|
|
#
|
|
# Offline $ratio percent of hot-pluggable memory
|
|
#
|
|
echo 0 > $NOTIFIER_ERR_INJECT_DIR/actions/MEM_GOING_OFFLINE/error
|
|
for memory in `hotpluggable_online_memory`; do
|
|
if [ $((RANDOM % 100)) -lt $ratio ]; then
|
|
offline_memory_expect_success $memory
|
|
fi
|
|
done
|
|
|
|
#
|
|
# Test memory hot-add error handling (offline => online)
|
|
#
|
|
echo $error > $NOTIFIER_ERR_INJECT_DIR/actions/MEM_GOING_ONLINE/error
|
|
for memory in `hotpluggable_offline_memory`; do
|
|
online_memory_expect_fail $memory
|
|
done
|
|
|
|
#
|
|
# Online all hot-pluggable memory
|
|
#
|
|
echo 0 > $NOTIFIER_ERR_INJECT_DIR/actions/MEM_GOING_ONLINE/error
|
|
for memory in `hotpluggable_offline_memory`; do
|
|
online_memory_expect_success $memory
|
|
done
|
|
|
|
#
|
|
# Test memory hot-remove error handling (online => offline)
|
|
#
|
|
echo $error > $NOTIFIER_ERR_INJECT_DIR/actions/MEM_GOING_OFFLINE/error
|
|
for memory in `hotpluggable_online_memory`; do
|
|
if [ $((RANDOM % 100)) -lt $ratio ]; then
|
|
offline_memory_expect_fail $memory
|
|
fi
|
|
done
|
|
|
|
echo 0 > $NOTIFIER_ERR_INJECT_DIR/actions/MEM_GOING_OFFLINE/error
|
|
/sbin/modprobe -q -r memory-notifier-error-inject
|
|
|
|
exit $retval
|