|
| 1 | +# Test balloons with certain CPU c-states disabled |
| 2 | + |
| 3 | +helm-terminate |
| 4 | +helm_config=$TEST_DIR/balloons-cstates.cfg helm-launch balloons |
| 5 | + |
| 6 | +# cpuids-of-container returns CPU ids a container is allowed to use, e.g. "1 2 4" |
| 7 | +cpuids-of() { |
| 8 | + local ctr=$1 # e.g. pod0c0 |
| 9 | + # return only cpu ids without zero-fill: replace cpu01 -> 1, cpu11 -> 11 |
| 10 | + pyexec "for cpu in cpus['$ctr']: print(cpu.replace('cpu0','').replace('cpu',''))" |
| 11 | +} |
| 12 | + |
| 13 | +# verify-cstates checks the last writes to "disable" files in the |
| 14 | +# override fs. |
| 15 | +verify-cstates() { |
| 16 | + local cpu_ids=$1 # e.g. "1 2 4" |
| 17 | + local enabled_cstates=$2 # e.g. "C1E C2" |
| 18 | + local disabled_cstates=$3 # e.g. "C6 C8" |
| 19 | + local last_n_writes=$4 # expect the write within last N writes, e.g. 6 |
| 20 | + |
| 21 | + vm-command "kubectl -n kube-system logs ds/nri-resource-policy-balloons | nl | grep 'cstates override fs: wrote' | tail -n $last_n_writes | nl" |
| 22 | + for cpu_id in $cpu_ids; do |
| 23 | + for cstate in $enabled_cstates; do |
| 24 | + echo "verify last write to cpu$cpu_id cstate=$cstate disable is 0" |
| 25 | + grep "cpu${cpu_id} cstate=$cstate disable=" <<< $COMMAND_OUTPUT | tail -n 1 | grep -q 'disable="0"' || { |
| 26 | + command-error "expected write 0 not found" |
| 27 | + } |
| 28 | + done |
| 29 | + for cstate in $disabled_cstates; do |
| 30 | + echo "verify last write to cpu$cpu_id cstate=$cstate disable is 1" |
| 31 | + grep "cpu${cpu_id} cstate=$cstate disable=" <<< $COMMAND_OUTPUT | tail -n 1 | grep -q 'disable="1"' || { |
| 32 | + command-error "expected write 1 not found" |
| 33 | + } |
| 34 | + done |
| 35 | + done |
| 36 | +} |
| 37 | + |
| 38 | +# verify-cstates-no-writes checks that any c-states of given CPUs have not been written |
| 39 | +verify-cstates-no-writes() { |
| 40 | + local cpu_ids=$1 # e.g. "1 2 4" |
| 41 | + local last_n_writes=$2 # e.g. 100 |
| 42 | + echo "verify no writes to c-states of CPUs $cpu_ids" |
| 43 | + cpu_ids="(${cpu_ids// /|})" |
| 44 | + vm-command "kubectl -n kube-system logs ds/nri-resource-policy-balloons | nl | grep -E 'cstates override fs: wrote cpu${cpu_ids} cstate='" |
| 45 | + grep -q wrote <<< $COMMAND_OUTPUT && { |
| 46 | + command-error "writes to forbidden CPUs found" |
| 47 | + } |
| 48 | +} |
| 49 | + |
| 50 | +cleanup() { |
| 51 | + vm-command "kubectl delete pods --all --now" |
| 52 | +} |
| 53 | + |
| 54 | +echo "verify that all c-states of all available CPUs are enabled" |
| 55 | +verify-cstates "2 3 4 5 6 7 11 12 13" "C1E C2 C4 C8" "" 36 |
| 56 | + |
| 57 | +echo "verify that c-states of CPUs outside AvailableResources have not been written" |
| 58 | +verify-cstates-no-writes "0 1 8 9 14 15" |
| 59 | + |
| 60 | +CPUREQ="750m" MEMREQ="100M" CPULIM="750m" MEMLIM="" |
| 61 | +POD_ANNOTATION="balloon.balloons.resource-policy.nri.io: lowlatency-bln" CONTCOUNT=1 create balloons-busybox |
| 62 | +report allowed |
| 63 | +verify 'len(cpus["pod0c0"]) == 1' |
| 64 | +echo "verify that CPUs of low-latency pod0 cannot enter C4 or C8" |
| 65 | +verify-cstates "$(cpuids-of pod0c0)" "C1E C2" "C4 C8" 4 |
| 66 | + |
| 67 | +CPUREQ="3" MEMREQ="100M" CPULIM="" MEMLIM="" |
| 68 | +POD_ANNOTATION="balloon.balloons.resource-policy.nri.io: lowlatency-bln" CONTCOUNT=1 create balloons-busybox |
| 69 | +report allowed |
| 70 | +verify 'cpus["pod0c0"] == cpus["pod1c0"]' \ |
| 71 | + 'len(cpus["pod0c0"]) == 4' |
| 72 | +echo "verify that CPUs of low-latency pods pod0 and pod1 cannot enter C4 or C8" |
| 73 | +verify-cstates "$(cpuids-of pod1c0)" "C1E C2" "C4 C8" 16 |
| 74 | + |
| 75 | +# store CPU ids of maximal cpuset before deleting pods |
| 76 | +max_lowlatency_cpus="$(echo $(cpuids-of pod1c0) )" |
| 77 | + |
| 78 | +vm-command 'kubectl delete pod pod1' |
| 79 | +report allowed |
| 80 | +verify 'len(cpus["pod0c0"]) == 1' |
| 81 | + |
| 82 | +# spaces around each id helps ensuring grep " 1 " never matches cpu 11 but always matches cpu 1 |
| 83 | +pod0cpus=" $(echo $(cpuids-of pod0c0) ) " |
| 84 | + |
| 85 | +echo "verify that c-states of freed CPUs are enabled again after balloon was deflated" |
| 86 | +freed_cpus="" |
| 87 | +for cpu_id in $max_lowlatency_cpus; do |
| 88 | + grep -q " $cpu_id " <<< $pod0cpus || freed_cpus+=" $cpu_id" |
| 89 | +done |
| 90 | +echo "verify that all c-states of freed CPUs $freed_cpus (= {$max_lowlatency_cpus} - {$pod0cpus}) are enabled after the balloon got deflated" |
| 91 | +verify-cstates "$freed_cpus" "C1E C2 C4 C8" "" 24 |
| 92 | + |
| 93 | +echo "verify that c-states of the remaining CPU $(cpuids-of pod0c0) are still configured for low-latency" |
| 94 | +verify-cstates "$(cpuids-of pod0c0)" "C1E C2" "C4 C8" 16 |
| 95 | + |
| 96 | +vm-command 'kubectl delete pod pod0' |
| 97 | +report allowed |
| 98 | + |
| 99 | +echo "verify that after all containers are gone and their destroyed, c-states of all used CPUs are enabled again" |
| 100 | +verify-cstates "$max_lowlatency_cpus" "C1E C2 C4 C8" "" 32 |
0 commit comments