• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/bin/sh
2
3################################################################################
4#                                                                              #
5# Copyright (c) 2009 FUJITSU LIMITED                                           #
6#                                                                              #
7# This program is free software;  you can redistribute it and#or modify        #
8# it under the terms of the GNU General Public License as published by         #
9# the Free Software Foundation; either version 2 of the License, or            #
10# (at your option) any later version.                                          #
11#                                                                              #
12# This program is distributed in the hope that it will be useful, but          #
13# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY   #
14# or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License     #
15# for more details.                                                            #
16#                                                                              #
17# You should have received a copy of the GNU General Public License            #
18# along with this program;  if not, write to the Free Software                 #
19# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA      #
20#                                                                              #
21# Author: Miao Xie <miaox@cn.fujitsu.com>                                      #
22#                                                                              #
23################################################################################
24
25export TCID="cpuset_memory_spread"
26export TST_TOTAL=6
27export TST_COUNT=1
28
29. cpuset_funcs.sh
30
31check
32
33exit_status=0
34nr_cpus=$NR_CPUS
35nr_mems=$N_NODES
36
37# In general, the cache hog will use more than 10000 kb slab space on the nodes
38# on which it is running. The other nodes' slab space has littler change.(less
39# than 1000 kb).
40upperlimit=10000
41lowerlimit=2000
42
43cpus_all="$(seq -s, 0 $((nr_cpus-1)))"
44mems_all="$(seq -s, 0 $((nr_mems-1)))"
45
46nodedir="/sys/devices/system/node"
47
48FIFO="./myfifo"
49
50# memsinfo is an array implementation of the form of a multi-line string
51# _0: value0
52# _1: value1
53# _2: value2
54#
55memsinfo=""
56
57# set value to memsinfo ($1 - index, $2 - value)
58set_memsinfo_val()
59{
60	local nl='
61'
62	# clearing existent value (if present)
63	memsinfo=`echo "$memsinfo" | sed -r "/^\_$1\: /d"`
64
65	if [ -z "$memsinfo" ]; then
66		memsinfo="_$1: $2"
67	else
68		memsinfo="$memsinfo${nl}_$1: $2"
69	fi
70}
71
72# get value from memsinfo ($1 - index)
73get_memsinfo_val()
74{
75	local value=
76	value=`echo "$memsinfo" | grep -e "^\_$1\: "`
77	value=`echo "$value" | sed -r "s/^.*\: (.*)$/\1/"`
78	echo "$value"
79}
80
81
82init_memsinfo_array()
83{
84	local i=
85
86	for i in `seq 0 $((nr_mems-1))`
87	do
88		set_memsinfo_val $i 0
89	done
90}
91
92# get_meminfo <nodeid> <item>
93get_meminfo()
94{
95	local nodeid="$1"
96	local nodepath="$nodedir/node$nodeid"
97	local nodememinfo="$nodepath/meminfo"
98	local item="$2"
99	local info=`cat $nodememinfo | grep $item | awk '{print $4}'`
100	set_memsinfo_val $nodeid $info
101}
102
103# freemem_check
104# We need enough memory space on every node to run this test, so we must check
105# whether every node has enough free memory or not.
106# return value: 1 - Some node doesn't have enough free memory
107#               0 - Every node has enough free memory, We can do this test
108freemem_check()
109{
110	local i=
111
112	for i in `seq 0 $((nr_mems-1))`
113	do
114		get_meminfo $i "MemFree"
115	done
116
117	for i in `seq 0 $((nr_mems-1))`
118	do
119		# I think we need 100MB free memory to run test
120		if [ $(get_memsinfo_val $i) -lt 100000 ]; then
121			return 1
122		fi
123	done
124}
125
126# get_memsinfo
127get_memsinfo()
128{
129	local i=
130
131	for i in `seq 0 $((nr_mems-1))`
132	do
133		get_meminfo $i "FilePages"
134	done
135}
136
137# account_meminfo <nodeId>
138account_meminfo()
139{
140	local nodeId="$1"
141	local tmp="$(get_memsinfo_val $nodeId)"
142	get_meminfo $@ "FilePages"
143	set_memsinfo_val $nodeId $(($(get_memsinfo_val $nodeId)-$tmp))
144}
145
146# account_memsinfo
147account_memsinfo()
148{
149	local i=
150
151	for i in `seq 0 $((nr_mems-1))`
152	do
153		account_meminfo $i
154	done
155}
156
157
158# result_check <nodelist>
159# return 0: success
160#	 1: fail
161result_check()
162{
163	local nodelist="`echo $1 | sed -e 's/,/ /g'`"
164	local i=
165
166	for i in $nodelist
167	do
168		if [ $(get_memsinfo_val $i) -le $upperlimit ]; then
169			return 1
170		fi
171	done
172
173	local allnodelist="`echo $mems_all | sed -e 's/,/ /g'`"
174	allnodelist=" "$allnodelist" "
175	nodelist=" "$nodelist" "
176
177	local othernodelist="$allnodelist"
178	for i in $nodelist
179	do
180		othernodelist=`echo "$othernodelist" | sed -e "s/ $i / /g"`
181	done
182
183	for i in $othernodelist
184	do
185		if [ $(get_memsinfo_val $i) -gt $lowerlimit ]; then
186			return 1
187		fi
188	done
189}
190
191# general_memory_spread_test <cpusetpath> <is_spread> <cpu_list> <node_list> \
192# <expect_nodes> <test_pid>
193# expect_nodes: we expect to use the slab or cache on which node
194general_memory_spread_test()
195{
196	local cpusetpath="$CPUSET/1"
197	local is_spread="$1"
198	local cpu_list="$2"
199	local node_list="$3"
200	local expect_nodes="$4"
201	local test_pid="$5"
202
203	cpuset_set "$cpusetpath" "$cpu_list" "$node_list" "0" 2> $CPUSET_TMP/stderr
204	if [ $? -ne 0 ]; then
205		cpuset_log_error $CPUSET_TMP/stderr
206		tst_resm TFAIL "set general group parameter failed."
207		return 1
208	fi
209
210	/bin/echo "$is_spread" > "$cpusetpath/cpuset.memory_spread_page" 2> $CPUSET_TMP/stderr
211	if [ $? -ne 0 ]; then
212		cpuset_log_error $CPUSET_TMP/stderr
213		tst_resm TFAIL "set spread value failed."
214		return 1
215	fi
216
217	/bin/echo "$test_pid" > "$cpusetpath/tasks" 2> $CPUSET_TMP/stderr
218	if [ $? -ne 0 ]; then
219		cpuset_log_error $CPUSET_TMP/stderr
220		tst_resm TFAIL "attach task failed."
221		return 1
222	fi
223
224	# we'd better drop the caches before we test page cache.
225	sync
226	/bin/echo 3 > /proc/sys/vm/drop_caches 2> $CPUSET_TMP/stderr
227	if [ $? -ne 0 ]; then
228		cpuset_log_error $CPUSET_TMP/stderr
229		tst_resm TFAIL "drop caches failed."
230		return 1
231	fi
232
233	get_memsinfo
234	/bin/kill -s SIGUSR1 $test_pid
235	read exit_num < $FIFO
236	if [ $exit_num -eq 0 ]; then
237		tst_resm TFAIL "hot mem task failed."
238		return 1
239	fi
240
241	account_memsinfo
242	result_check $expect_nodes
243	if [ $? -ne 0 ]; then
244		tst_resm TFAIL "hog the memory on the unexpected node(FilePages_For_Nodes(KB): ${memsinfo}, Expect Nodes: $expect_nodes)."
245		return 1
246	fi
247}
248
249base_test()
250{
251	local pid=
252	local result_num=
253
254	setup
255	if [ $? -ne 0 ]; then
256		exit_status=1
257	else
258		cpuset_mem_hog &
259		pid=$!
260		general_memory_spread_test "$@" "$pid"
261		result_num=$?
262		if [ $result_num -ne 0 ]; then
263			exit_status=1
264		fi
265
266		/bin/kill -s SIGUSR2 $pid
267		wait $pid
268
269		cleanup
270		if [ $? -ne 0 ]; then
271			exit_status=1
272		elif [ $result_num -eq 0 ]; then
273			tst_resm TPASS "Cpuset memory spread page test succeeded."
274		fi
275	fi
276	TST_COUNT=$(($TST_COUNT + 1))
277}
278
279# test general spread page cache in a cpuset
280test_spread_page1()
281{
282	while read spread cpus nodes exp_nodes
283	do
284		base_test "$spread" "$cpus" "$nodes" "$exp_nodes"
285	done <<- EOF
286		0	0	0	0
287		1	0	0	0
288		0	0	1	1
289		1	0	1	1
290		0	0	0,1	0
291		1	0	0,1	0,1
292	EOF
293	# while read spread cpus nodes exp_nodes
294}
295
296test_spread_page2()
297{
298	local pid=
299	local result_num=
300
301	setup
302	if [ $? -ne 0 ]; then
303		exit_status=1
304	else
305		cpuset_mem_hog &
306		pid=$!
307		general_memory_spread_test "1" "$cpus_all" "0" "0" "$pid"
308		result_num=$?
309		if [ $result_num -ne 0 ]; then
310			exit_status=1
311		else
312			general_memory_spread_test "1" "$cpus_all" "1" "1" "$pid"
313			result_num=$?
314			if [ $result_num -ne 0 ]; then
315				exit_status=1
316			fi
317		fi
318
319		/bin/kill -s SIGUSR2 $pid
320		wait $pid
321
322		cleanup
323		if [ $? -ne 0 ]; then
324			exit_status=1
325		elif [ $result_num -eq 0 ]; then
326			tst_resm TPASS "Cpuset memory spread page test succeeded."
327		fi
328	fi
329}
330
331init_memsinfo_array
332freemem_check
333if [ $? -ne 0 ]; then
334	tst_brkm TCONF "Some node doesn't has enough free memory(100MB) to do test(MemFree_For_Nodes(KB): ${memsinfo[*]})."
335fi
336
337dd if=/dev/zero of=./DATAFILE bs=1M count=100
338if [ $? -ne 0 ]; then
339	tst_brkm TFAIL "Creating DATAFILE failed."
340fi
341
342mkfifo $FIFO
343if [ $? -ne 0 ]; then
344	rm -f DATAFILE
345	tst_brkm TFAIL "failed to mkfifo $FIFO"
346fi
347
348test_spread_page1
349test_spread_page2
350
351rm -f DATAFILE $FIFO
352
353exit $exit_status
354