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