1#!/bin/sh
2#
3# $NetBSD: smtoff,v 1.6 2020/09/08 12:52:18 martin Exp $
4#
5# Public Domain.
6#
7
8# PROVIDE: smtoff
9# REQUIRE: root bootconf CRITLOCALMOUNTED tty
10
11$_rc_subr_loaded . /etc/rc.subr
12
13name="smtoff"
14rcvar=$name
15
16start_cmd="smtoff_start"
17stop_cmd="smtoff_stop"
18
19# ------------------------------------------------------------------------------
20
21#
22# The format of the output is:
23#
24#     ...
25#     cpu0: SMT ID 1
26#     ...
27#
28# Return the value.
29#
30GetSmtId() {
31	cpuctl identify "$1" |
32	while read cpuN smt id N junk
33	do
34		test -n "$junk" && continue
35
36		case "${smt} ${id}" in
37		'SMT ID')
38			case "$N" in
39			[0-9]|[1-9][0-9]|[1-9][0-9]*[0-9])
40				printf %s "$N"
41				return
42				;;
43			esac
44			;;
45		esac
46	done
47}
48
49CountCPUs() {
50	sysctl -n hw.ncpu
51}
52
53# ------------------------------------------------------------------------------
54
55#
56# Disable SMT. We skip cpu0.
57#
58smtoff_start()
59{
60	ncpus=$(CountCPUs)
61	i=1
62
63	while [ "$i" -lt "$ncpus" ]
64	do
65		smtid=$(GetSmtId "$i" 2>/dev/null)
66
67		case "$smtid" in
68		'')			# Didn't get the ID? Then maybe no SMT.
69			;;
70
71		0)			# The first thread is never disabled.
72			;;
73
74		*)
75			cpuctl offline "$i"
76			;;
77		esac
78
79		i=$(($i+1))
80	done
81}
82
83#
84# Enable SMT. We basically turn on each CPU.
85#
86smtoff_stop()
87{
88	ncpus=$(CountCPUs)
89	i=1
90
91	while [ "$i" -lt "$ncpus" ]
92	do
93		cpuctl online "$i"
94		i=$(($i+1))
95	done
96}
97
98load_rc_config $name
99run_rc_command "$1"
100