xref: /spdk/test/scheduler/rpc.sh (revision 3a02df0b15619023c86fd608f37d8adedabb7103)
1#!/usr/bin/env bash
2#  SPDX-License-Identifier: BSD-3-Clause
3#  Copyright (C) 2024 Intel Corporation
4#  All rights reserved.
5#
6
7testdir=$(readlink -f "$(dirname "$0")")
8rootdir=$(readlink -f "$testdir/../../")
9
10source "$rootdir/test/common/autotest_common.sh"
11source "$testdir/common.sh"
12
13rpc=rpc_cmd
14
15function framework_get_governor() {
16	"${SPDK_APP[@]}" -m "$spdk_cpumask" &
17	spdk_pid=$!
18	trap 'killprocess $spdk_pid; exit 1' SIGINT SIGTERM EXIT
19	waitforlisten $spdk_pid
20
21	# Static scheduler does not use any governor
22	[[ "$($rpc framework_get_scheduler | jq -r '.scheduler_name')" == "static" ]]
23	[[ -z "$($rpc framework_get_governor | jq -r '.[]')" ]]
24
25	# gscheduler uses the only currently implemented governor - dpdk_governor
26	$rpc framework_set_scheduler gscheduler
27	[[ "$($rpc framework_get_scheduler | jq -r '.scheduler_name')" == "gscheduler" ]]
28	[[ "$($rpc framework_get_governor | jq -r '.governor_name')" == "dpdk_governor" ]]
29
30	# Check that core length matches the cpumask and first one is the main core
31	[[ "$($rpc framework_get_governor | jq -r '.cores | length')" -eq "$spdk_cpus_no" ]]
32	[[ "$($rpc framework_get_governor | jq -r '.cores[0].lcore_id')" -eq "$spdk_main_core" ]]
33	[[ -n "$($rpc framework_get_governor | jq -r '.cores[0].current_frequency')" ]]
34
35	# dpdk_governor always has an env it uses
36	[[ -n "$($rpc framework_get_governor | jq -r '.module_specific.env')" ]]
37
38	trap - SIGINT SIGTERM EXIT
39	killprocess $spdk_pid
40}
41
42function scheduler_opts() {
43	"${SPDK_APP[@]}" -m "$spdk_cpumask" --wait-for-rpc &
44	spdk_pid=$!
45	trap 'killprocess $spdk_pid; exit 1' SIGINT SIGTERM EXIT
46	waitforlisten $spdk_pid
47
48	# It is possible to change settings generic scheduler opts for schedulers in event framework
49	$rpc framework_set_scheduler dynamic -p 424242
50	[[ "$($rpc framework_get_scheduler | jq -r '. | select(.scheduler_name == "dynamic") | .scheduler_period')" -eq 424242 ]]
51
52	# Verify that the scheduler is changed and the non-default value is set
53	$rpc framework_set_scheduler dynamic --core-limit 42
54	[[ "$($rpc framework_get_scheduler | jq -r '. | select(.scheduler_name == "dynamic") | .core_limit')" -eq 42 ]]
55
56	# Switch scheduler back and forth and verify values are kept (scheduler implementation specific)
57	$rpc framework_set_scheduler gscheduler
58	[[ "$($rpc framework_get_scheduler | jq -r '.scheduler_name')" == "gscheduler" ]]
59	$rpc framework_set_scheduler dynamic
60	[[ "$($rpc framework_get_scheduler | jq -r '. | select(.scheduler_name == "dynamic") | .core_limit')" -eq 42 ]]
61
62	# All the above configuration can happen before subsystems initialize
63	$rpc framework_start_init
64
65	trap - SIGINT SIGTERM EXIT
66	killprocess $spdk_pid
67}
68
69function static_as_default() {
70	"${SPDK_APP[@]}" -m "$spdk_cpumask" --wait-for-rpc &
71	spdk_pid=$!
72	trap 'killprocess $spdk_pid; exit 1' SIGINT SIGTERM EXIT
73	waitforlisten $spdk_pid
74
75	# Before initialization scheduler is set to NULL. If unchanged, set to static
76	# during subsystem initialization.
77	[[ "$($rpc framework_get_scheduler | jq -r '. | select(.scheduler_name == null)')" ]]
78	$rpc framework_start_init
79	[[ "$($rpc framework_get_scheduler | jq -r '.scheduler_name')" == "static" ]]
80
81	# We should be able to return to static scheduler after changing it
82	# We also need to check that threads revert to their original core
83
84	main_cpu=$($rpc framework_get_reactors | jq -r '.reactors[0].lcore')
85	other_cpu=$($rpc framework_get_reactors | jq -r '.reactors[1].lcore')
86
87	# Find a thread that starts on a core other than main core
88	thread_id=$($rpc framework_get_reactors \
89		| jq -r ".reactors[] | select(.lcore == $other_cpu).lw_threads[0].id")
90
91	$rpc framework_set_scheduler dynamic
92	[[ "$($rpc framework_get_scheduler | jq -r '.scheduler_name')" == "dynamic" ]]
93
94	# Check that this thread is now on main core
95	$rpc framework_get_reactors \
96		| jq -e -r ".reactors[] | select(.lcore == $main_cpu).lw_threads[] | select(.id == $thread_id)"
97
98	$rpc framework_set_scheduler static
99	[[ "$($rpc framework_get_scheduler | jq -r '.scheduler_name')" == "static" ]]
100
101	# Check that this thread is back on its original core
102	$rpc framework_get_reactors \
103		| jq -e -r ".reactors[] | select(.lcore == $other_cpu).lw_threads[] | select(.id == $thread_id)"
104
105	# Explicitly move that thread to the main core
106	$rpc framework_set_scheduler static --mappings "$thread_id:$main_cpu"
107
108	# Check that this thread is now on main core
109	$rpc framework_get_reactors \
110		| jq -e -r ".reactors[] | select(.lcore == $main_cpu).lw_threads[] | select(.id == $thread_id)"
111
112	trap - SIGINT SIGTERM EXIT
113	killprocess $spdk_pid
114}
115
116run_test "scheduler_opts" scheduler_opts
117run_test "static_as_default" static_as_default
118run_test "framework_get_governor" framework_get_governor
119