xref: /aosp_15_r20/external/ltp/testcases/kernel/controllers/memcg/regression/memcg_regression_test.sh (revision 49cdfc7efb34551c7342be41a7384b9c40d7cab7)
1#! /bin/sh
2# SPDX-License-Identifier: GPL-2.0-or-later
3# Copyright (c) 2009 FUJITSU LIMITED
4# Author: Li Zefan <[email protected]>
5# Added memcg enable/disable functionality: Rishikesh K Rajak <[email protected]>
6
7TST_ID="memcg_regression_test"
8TST_CLEANUP=cleanup
9TST_SETUP=setup
10TST_TESTFUNC=test_
11TST_NEEDS_ROOT=1
12TST_NEEDS_CMDS="killall kill"
13TST_CNT=4
14
15#buffer can rotate and number of found bugs can actually go down
16#so clear the buffer to avoid this
17dmesg -c > /dev/null
18nr_bug=0
19nr_null=0
20nr_warning=0
21nr_lockdep=0
22
23# check_kernel_bug - check if some kind of kernel bug happened
24check_kernel_bug()
25{
26	new_bug=`dmesg | grep -c "kernel BUG"`
27	new_null=`dmesg | grep -c "kernel NULL pointer dereference"`
28	new_warning=`dmesg | grep -c "^WARNING"`
29	new_lockdep=`dmesg | grep -c "possible recursive locking detected"`
30
31	# no kernel bug is detected
32	if [ $new_bug -eq $nr_bug -a $new_warning -eq $nr_warning -a \
33	     $new_null -eq $nr_null -a $new_lockdep -eq $nr_lockdep ]; then
34		return 1
35	fi
36
37	# some kernel bug is detected
38	if [ $new_bug -gt $nr_bug ]; then
39		tst_res TFAIL "kernel BUG was detected!"
40	fi
41	if [ $new_warning -gt $nr_warning ]; then
42		tst_res TFAIL "kernel WARNING was detected!"
43	fi
44	if [ $new_null -gt $nr_null ]; then
45		tst_res TWARN "kernel NULL pointer dereference!"
46	fi
47	if [ $new_lockdep -gt $nr_lockdep ]; then
48		tst_res TWARN "kernel lockdep warning was detected!"
49	fi
50
51	nr_bug=$new_bug
52	nr_null=$new_null
53	nr_warning=$new_warning
54	nr_lockdep=$new_lockdep
55
56	echo "check_kernel_bug found something!"
57	dmesg
58	return 0
59}
60
61setup()
62{
63	cgroup_require "memory"
64	cgroup_version=$(cgroup_get_version "memory")
65	mount_point=$(cgroup_get_mountpoint "memory")
66	test_dir=$(cgroup_get_test_path "memory")
67	task_list=$(cgroup_get_task_list "memory")
68	if [ "$cgroup_version" = "2" ]; then
69		memory_limit="memory.max"
70	else
71		memory_limit="memory.limit_in_bytes"
72	fi
73
74	[ "$cgroup_version" = "2" ] && ROD echo "+memory" \> "$test_dir/cgroup.subtree_control"
75
76	tst_res TINFO "test starts with cgroup version $cgroup_version"
77}
78
79cleanup()
80{
81	cleanup_testpath "$test_dir/0"
82	cgroup_cleanup
83}
84
85create_testpath()
86{
87	local path="$1"
88	[ ! -e "$path" ] && ROD mkdir "$path"
89}
90
91cleanup_testpath()
92{
93	local path="$1"
94	[ -e "$path" ] && ROD rmdir "$path"
95}
96
97#---------------------------------------------------------------------------
98# Bug:    The bug was, while forking mass processes, trigger memcgroup OOM,
99#         then NULL pointer dereference may be hit.
100# Kernel: 2.6.25-rcX
101# Links:  http://lkml.org/lkml/2008/4/14/38
102# Fix:    commit e115f2d89253490fb2dbf304b627f8d908df26f1
103#---------------------------------------------------------------------------
104test_1()
105{
106	local test_path
107	test_path="$test_dir/0"
108
109	create_testpath "$test_path"
110	ROD echo 0 \> "$test_path/$memory_limit"
111
112	./memcg_test_1 "$test_path/$task_list"
113
114	cleanup_testpath "$test_path"
115
116	check_kernel_bug
117	if [ $? -eq 1 ]; then
118		tst_res TPASS "no kernel bug was found"
119	fi
120}
121
122#---------------------------------------------------------------------------
123# Bug:    Shrink memory might never return, unless send signal to stop it.
124# Kernel: 2.6.29
125# Links:  http://marc.info/?t=123199973900003&r=1&w=2
126#         http://lkml.org/lkml/2009/2/3/72
127# Fix:    81d39c20f5ee2437d71709beb82597e2a38efbbc
128#---------------------------------------------------------------------------
129test_2()
130{
131	local test_path
132
133	# for cgroup2 writing to memory.max first checks the new limit against the
134	# current usage and will start killing processes if oom, therefore we do not
135	# expect EBUSY to be returned by the shrink operation.
136	if [ "$cgroup_version" = "2" ]; then
137		tst_res TCONF "Cgroup v2 found, skipping test"
138		return
139	fi
140
141	test_path="$test_dir/0"
142
143	./memcg_test_2 &
144	pid1=$!
145	sleep 1
146
147	create_testpath "$test_path"
148	ROD echo $pid1 \> "$test_path"/tasks
149
150	# let pid1 'test_2' allocate memory
151	/bin/kill -SIGUSR1 $pid1
152	sleep 1
153
154	# shrink memory
155	echo 1 > "$test_path"/memory.limit_in_bytes 2>&1 &
156	pid2=$!
157
158	# check if 'echo' will exit and exit with failure
159	for tmp in $(seq 0 4); do
160		sleep 1
161		ps -p $! > /dev/null
162		if [ $? -ne 0 ]; then
163			wait $pid2
164			if [ $? -eq 0 ]; then
165				tst_res TFAIL "echo should return failure"
166				kill -9 $pid1 $pid2 > /dev/null 2>&1
167				wait $pid1 $pid2
168				cleanup_testpath "$test_path"
169				return
170			fi
171			break
172		fi
173	done
174
175	if [ $tmp -eq 5 ]; then
176		tst_res TFAIL "'echo' doesn't exit!"
177	else
178		tst_res TPASS "EBUSY was returned as expected"
179	fi
180
181	kill -9 $pid1 $pid2 > /dev/null 2>&1
182	wait $pid1 $pid2 > /dev/null 2>&1
183	cleanup_testpath "$test_path"
184}
185
186#---------------------------------------------------------------------------
187# Bug:    crash when rmdir a cgroup on IA64
188# Kernel: 2.6.29-rcX
189# Links:  http://marc.info/?t=123235660300001&r=1&w=2
190# Fix:    commit 299b4eaa302138426d5a9ecd954de1f565d76c94
191#---------------------------------------------------------------------------
192test_3()
193{
194	local test_path
195	test_path="$test_dir/0"
196	create_testpath "$test_path"
197
198	for pid in $(cat "$mount_point/$task_list"); do
199		echo $pid > "$test_path/$task_list" 2> /dev/null
200	done
201
202	for pid in $(cat "$test_path/$task_list"); do
203		echo $pid > "$mount_point/$task_list" 2> /dev/null
204	done
205	cleanup_testpath "$test_path"
206
207	check_kernel_bug
208	if [ $? -eq 1 ]; then
209		tst_res TPASS "no kernel bug was found"
210	fi
211}
212
213#---------------------------------------------------------------------------
214# Bug:    the memcg's refcnt handling at swapoff was wrong, causing crash
215# Kernel: 2.6.29-rcX
216# Links:  http://marc.info/?t=123208656300004&r=1&w=2
217# Fix:    commit 85d9fc89fb0f0703df6444f260187c088a8d59ff
218#---------------------------------------------------------------------------
219test_4()
220{
221	local test_path
222	test_path="$test_dir/0"
223	create_testpath "$test_path"
224	swaps=$(cut -F1 /proc/swaps | tail -n +2)
225
226	./memcg_test_4.sh "$cgroup_version" "$mount_point" "$test_path"
227
228	check_kernel_bug
229	if [ $? -eq 1 ]; then
230		tst_res TPASS "no kernel bug was found"
231	fi
232
233	# test_4.sh might be killed by oom, so do clean up here
234	killall -9 memcg_test_4 2> /dev/null
235	killall -9 memcg_test_4.sh 2> /dev/null
236
237	# if test_4.sh gets killed, it won't clean cgroup it created
238	cleanup_testpath "$test_path"
239
240	for s in $swaps; do
241		swapon $s
242	done
243}
244
245. cgroup_lib.sh
246tst_run
247