xref: /spdk/test/scheduler/idle.sh (revision cc6920a4763d4b9a43aa40583c8397d8f14fa100)
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