1#!/usr/bin/env bash 2 3testdir=$(readlink -f "$(dirname "$0")") 4rootdir=$(readlink -f "$testdir/../../") 5 6source "$rootdir/test/common/autotest_common.sh" 7source "$testdir/common.sh" 8 9trap 'killprocess "$spdk_pid"' EXIT 10 11thread_stats() { 12 local thread 13 local busy_threads=0 14 15 get_thread_stats 16 17 # Simply verify if threads stay idle 18 for thread in "${!thread_map[@]}"; do 19 if ((idle[thread] < busy[thread])); then 20 printf 'Waiting for %s to become idle\n' "${thread_map[thread]}" 21 ((++busy_threads)) 22 elif ((idle[thread] > busy[thread])); then 23 printf '%s is idle\n' "${thread_map[thread]}" 24 fi 25 done 26 27 ((busy_threads == 0)) 28} 29 30idle() { 31 local reactor_framework 32 local reactors thread 33 local cpusmask thread_cpumask 34 local threads 35 36 exec_under_dynamic_scheduler "${SPDK_APP[@]}" -m "$spdk_cpusmask" --main-core "$spdk_main_core" 37 38 # The expectation here is that when SPDK app is idle the following is true: 39 # - all threads are assigned to main lcore 40 # - threads are not being moved between lcores 41 42 xtrace_disable 43 while ((samples++ < 5)); do 44 cpusmask=0 45 reactor_framework=$(rpc_cmd framework_get_reactors | jq -r '.reactors[]') 46 threads=($( 47 jq -r "select(.lcore == $spdk_main_core) | .lw_threads[].name" <<< "$reactor_framework" 48 )) 49 50 for thread in "${threads[@]}"; do 51 thread_cpumask=0x$(jq -r "select(.lcore == $spdk_main_core) | .lw_threads[] | select(.name == \"$thread\") | .cpumask" <<< "$reactor_framework") 52 ((cpusmask |= thread_cpumask)) 53 done 54 55 printf 'SPDK cpumask: %x Threads cpumask: %x\n' "$spdk_cpusmask" "$cpusmask" 56 thread_stats 57 done 58 59 xtrace_restore 60} 61 62idle 63