xref: /spdk/test/scheduler/idle.sh (revision 19377d66d6d823c7965bcdb9c329034abb2f35fd)
1c313f1b2SMichal Berger#!/usr/bin/env bash
2eb53c232Spaul luse#  SPDX-License-Identifier: BSD-3-Clause
3eb53c232Spaul luse#  Copyright (C) 2020 Intel Corporation
4eb53c232Spaul luse#  All rights reserved.
5eb53c232Spaul luse#
6c313f1b2SMichal Berger
7c313f1b2SMichal Bergertestdir=$(readlink -f "$(dirname "$0")")
8c313f1b2SMichal Bergerrootdir=$(readlink -f "$testdir/../../")
9c313f1b2SMichal Berger
10c313f1b2SMichal Bergersource "$rootdir/test/common/autotest_common.sh"
11c313f1b2SMichal Bergersource "$testdir/common.sh"
12c313f1b2SMichal Berger
13c313f1b2SMichal Bergertrap 'killprocess "$spdk_pid"' EXIT
14c313f1b2SMichal Berger
15c313f1b2SMichal Bergerthread_stats() {
16*19377d66STomasz Zawadzki	local thread load
17822325caSRichael Zhuang	busy_threads=0
18c313f1b2SMichal Berger
19*19377d66STomasz Zawadzki	get_thread_stats_current
20c313f1b2SMichal Berger
21c313f1b2SMichal Berger	# Simply verify if threads stay idle
22c313f1b2SMichal Berger	for thread in "${!thread_map[@]}"; do
23*19377d66STomasz Zawadzki		printf '[load:%3u%%, idle:%10u, busy:%10u] ' \
24*19377d66STomasz Zawadzki			$((busy[thread] * 100 / (busy[thread] + idle[thread]))) \
25*19377d66STomasz Zawadzki			"${idle[thread]}" "${busy[thread]}"
26c313f1b2SMichal Berger		if ((idle[thread] < busy[thread])); then
27c313f1b2SMichal Berger			printf 'Waiting for %s to become idle\n' "${thread_map[thread]}"
28c313f1b2SMichal Berger			((++busy_threads))
29*19377d66STomasz Zawadzki		else
30c313f1b2SMichal Berger			printf '%s is idle\n' "${thread_map[thread]}"
31c313f1b2SMichal Berger		fi
32c313f1b2SMichal Berger	done
33c313f1b2SMichal Berger}
34c313f1b2SMichal Berger
35c313f1b2SMichal Bergeridle() {
36c313f1b2SMichal Berger	local reactor_framework
37c313f1b2SMichal Berger	local reactors thread
385ad2877dSMichal Berger	local thread_cpumask
39c313f1b2SMichal Berger	local threads
40c313f1b2SMichal Berger
41c9c7c281SJosh Soref	exec_under_dynamic_scheduler "${SPDK_APP[@]}" -m "$spdk_cpumask" --main-core "$spdk_main_core"
42c313f1b2SMichal Berger
43c313f1b2SMichal Berger	# The expectation here is that when SPDK app is idle the following is true:
44c313f1b2SMichal Berger	# - all threads are assigned to main lcore
45c313f1b2SMichal Berger	# - threads are not being moved between lcores
46c313f1b2SMichal Berger
47*19377d66STomasz Zawadzki	# Get first set of stats, to exclude initialization from the busy/idle
48*19377d66STomasz Zawadzki	get_thread_stats_current
49*19377d66STomasz Zawadzki
50c313f1b2SMichal Berger	xtrace_disable
51c313f1b2SMichal Berger	while ((samples++ < 5)); do
52c9c7c281SJosh Soref		cpumask=0
53c313f1b2SMichal Berger		reactor_framework=$(rpc_cmd framework_get_reactors | jq -r '.reactors[]')
54c313f1b2SMichal Berger		threads=($(
55c313f1b2SMichal Berger			jq -r "select(.lcore == $spdk_main_core) | .lw_threads[].name" <<< "$reactor_framework"
56c313f1b2SMichal Berger		))
57c313f1b2SMichal Berger
58c313f1b2SMichal Berger		for thread in "${threads[@]}"; do
59c313f1b2SMichal Berger			thread_cpumask=0x$(jq -r "select(.lcore == $spdk_main_core) | .lw_threads[] | select(.name == \"$thread\") | .cpumask" <<< "$reactor_framework")
605ad2877dSMichal Berger			printf 'SPDK cpumask: %s Thread %s cpumask: %s\n' "$spdk_cpumask" "$thread" "$thread_cpumask"
61c313f1b2SMichal Berger		done
62c313f1b2SMichal Berger
6347c4304dSTomasz Zawadzki		thread_stats
64822325caSRichael Zhuang
65*19377d66STomasz Zawadzki		((busy_threads == 0))
66c313f1b2SMichal Berger	done
67c313f1b2SMichal Berger
68c313f1b2SMichal Berger	xtrace_restore
69c313f1b2SMichal Berger}
70c313f1b2SMichal Berger
71c313f1b2SMichal Bergeridle
72