xref: /spdk/test/setup/hugepages.sh (revision 32999ab917f67af61872f868585fd3d78ad6fb8a)
1#!/usr/bin/env bash
2testdir=$(readlink -f "$(dirname "$0")")
3rootdir=$(readlink -f "$testdir/../../")
4source "$testdir/common.sh"
5
6shopt -s extglob nullglob
7
8declare -a nodes_sys=()
9
10declare -i default_huges=0
11declare -i no_nodes=0
12declare -i nr_hugepages=0
13
14default_huges=$(get_meminfo Hugepagesize)
15default_huge_nr=/sys/kernel/mm/hugepages/hugepages-${default_huges}kB/nr_hugepages
16global_huge_nr=/proc/sys/vm/nr_hugepages
17
18get_nodes() {
19	local node
20
21	for node in /sys/devices/system/node/node+([0-9]); do
22		nodes_sys[${node##*node}]=$(< "$node/hugepages/hugepages-${default_huges}kB/nr_hugepages")
23	done
24	no_nodes=${#nodes_sys[@]}
25	((no_nodes > 0))
26}
27
28clear_hp() {
29	local node hp
30
31	for node in "${!nodes_sys[@]}"; do
32		for hp in "/sys/devices/system/node/node$node/hugepages/hugepages-"*; do
33			echo 0 > "$hp/nr_hugepages"
34		done
35	done
36
37	export CLEAR_HUGE=yes
38}
39
40get_test_nr_hugepages() {
41	local size=$1 # kB
42	if (($# > 1)); then
43		shift
44		local node_ids=("$@")
45	fi
46
47	((size >= default_huges))
48
49	nr_hugepages=$(((size + default_huges - 1) / default_huges))
50	get_test_nr_hugepages_per_node "${node_ids[@]}"
51}
52
53get_test_nr_hugepages_per_node() {
54	local user_nodes=("$@")
55
56	local _nr_hugepages=$nr_hugepages
57	local _no_nodes=$no_nodes
58
59	local -g nodes_test=()
60
61	if ((${#user_nodes[@]} > 0)); then
62		for _no_nodes in "${user_nodes[@]}"; do
63			nodes_test[_no_nodes]=$nr_hugepages
64		done
65		return 0
66	elif ((${#nodes_hp[@]} > 0)); then
67		for _no_nodes in "${!nodes_hp[@]}"; do
68			nodes_test[_no_nodes]=${nodes_hp[_no_nodes]}
69		done
70		return 0
71	fi
72
73	while ((_no_nodes > 0)); do
74		nodes_test[_no_nodes - 1]=$((_nr_hugepages / _no_nodes))
75		: $((_nr_hugepages -= nodes_test[_no_nodes - 1]))
76		: $((--_no_nodes))
77	done
78}
79
80verify_nr_hugepages() {
81	local node
82	local sorted_t
83	local sorted_s
84
85	echo "nr_hugepages=$nr_hugepages"
86	(($(< "$default_huge_nr") == nr_hugepages))
87	(($(< "$global_huge_nr") == nr_hugepages))
88	(($(get_meminfo HugePages_Total) == nr_hugepages))
89
90	get_nodes
91
92	# There's no obvious way of determining which NUMA node is going to end
93	# up with an odd number of hugepages in case such number was actually
94	# allocated by the kernel. Considering that, let's simply check if our
95	# expaction is met by sorting and comparing it with nr of hugepages that
96	# was actually allocated on each node.
97
98	for node in "${!nodes_test[@]}"; do
99		sorted_t[nodes_test[node]]=1 sorted_s[nodes_sys[node]]=1
100		echo "node$node=${nodes_sys[node]}"
101	done
102	[[ ${!sorted_s[*]} == "${!sorted_t[*]}" ]]
103}
104
105# Test cases
106default_setup() {
107	# Default HUGEMEM (8G) alloc on node0
108	get_test_nr_hugepages $((HUGEMEM * 1024)) 0
109	setup
110	verify_nr_hugepages
111}
112
113per_node_2G_alloc() {
114	# 2G alloc per node, total N*2G pages
115	local IFS=","
116
117	get_test_nr_hugepages $((2048 * 1024)) "${!nodes_sys[@]}"
118	NRHUGE=$nr_hugepages HUGENODE="${!nodes_sys[*]}" setup
119	nr_hugepages=$((nr_hugepages * ${#nodes_sys[@]})) verify_nr_hugepages
120}
121
122even_2G_alloc() {
123	# 2G alloc spread across N nodes
124	get_test_nr_hugepages $((2048 * 1024))
125	NRHUGE=$nr_hugepages HUGE_EVEN_ALLOC=yes setup
126	verify_nr_hugepages
127}
128
129odd_alloc() {
130	# Odd 2049MB alloc across N nodes
131	get_test_nr_hugepages $((2049 * 1024))
132	HUGEMEM=2049 HUGE_EVEN_ALLOC=yes setup
133	verify_nr_hugepages
134}
135
136custom_alloc() {
137	# Custom alloc: node0 == 512 pages [node1 == 1024 pages]
138
139	local IFS=","
140
141	local node
142	local nodes_hp=()
143
144	local nr_hugepages=0
145
146	nodes_hp[0]=512
147	if ((${#nodes_sys[@]} > 1)); then
148		nodes_hp[1]=1024
149	fi
150
151	for node in "${!nodes_hp[@]}"; do
152		HUGENODE+=("nodes_hp[$node]=${nodes_hp[node]}")
153		((nr_hugepages += nodes_hp[node]))
154	done
155
156	get_test_nr_hugepages_per_node
157	HUGENODE="${HUGENODE[*]}" setup
158	verify_nr_hugepages
159}
160
161hp_status() {
162	# Parse status from last verification
163
164	local node
165	local size free total
166
167	((${#nodes_sys[@]} > 0))
168
169	while read -r node size free _ total; do
170		size=${size/kB/} node=${node#node}
171		((size == default_huges)) || continue
172		((free == nodes_test[node]))
173		((total == nodes_test[node]))
174	done < <(setup output status |& grep "node[0-9]")
175}
176
177get_nodes
178clear_hp
179
180run_test "default_setup" default_setup
181run_test "per_node_2G_alloc" per_node_2G_alloc
182run_test "even_2G_alloc" even_2G_alloc
183run_test "odd_alloc" odd_alloc
184run_test "custom_alloc" custom_alloc
185run_test "hp_status" hp_status
186
187clear_hp
188