xref: /freebsd/share/man/man9/mi_switch.9 (revision 9768746b)
1.\"	$NetBSD: ctxsw.9,v 1.2 1996/12/02 00:11:31 tls Exp $
2.\"
3.\" Copyright (c) 1996 The NetBSD Foundation, Inc.
4.\" All rights reserved.
5.\" Copyright (c) 2023 The FreeBSD Foundation
6.\"
7.\" This code is derived from software contributed to The NetBSD Foundation
8.\" by Paul Kranenburg.
9.\"
10.\" Portions of this documentation were written by Mitchell Horne
11.\" under sponsorship from the FreeBSD Foundation.
12.\"
13.\" Redistribution and use in source and binary forms, with or without
14.\" modification, are permitted provided that the following conditions
15.\" are met:
16.\" 1. Redistributions of source code must retain the above copyright
17.\"    notice, this list of conditions and the following disclaimer.
18.\" 2. Redistributions in binary form must reproduce the above copyright
19.\"    notice, this list of conditions and the following disclaimer in the
20.\"    documentation and/or other materials provided with the distribution.
21.\"
22.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
23.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
24.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
25.\" PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
26.\" LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32.\" POSSIBILITY OF SUCH DAMAGE.
33.\"
34.\" $FreeBSD$
35.\"
36.Dd January 9, 2023
37.Dt MI_SWITCH 9
38.Os
39.Sh NAME
40.Nm mi_switch ,
41.Nm cpu_switch ,
42.Nm cpu_throw
43.Nd switch to another thread context
44.Sh SYNOPSIS
45.In sys/param.h
46.In sys/proc.h
47.Ft void
48.Fn mi_switch "int flags"
49.Ft void
50.Fn cpu_switch "struct thread *oldtd" "struct thread *newtd" "struct mtx *lock"
51.Ft void
52.Fn cpu_throw "struct thread *oldtd" "struct thread *newtd"
53.Sh DESCRIPTION
54The
55.Fn mi_switch
56function implements the machine-independent prelude to a thread context
57switch.
58It is the single entry point for every context switch and is called from only
59a few distinguished places in the kernel.
60The context switch is, by necessity, always performed by the switched thread,
61even when the switch is initiated from elsewhere; e.g. preemption requested via
62Inter-Processor Interrupt (IPI).
63.Pp
64The various major uses of
65.Fn mi_switch
66can be enumerated as follows:
67.Bl -enum -offset indent
68.It
69From within a function such as
70.Xr sleepq_wait 9
71or
72.Fn turnstile_wait
73when the current thread
74voluntarily relinquishes the CPU to wait for some resource or lock to become
75available.
76.It
77Involuntary preemption due to arrival of a higher-priority thread.
78.It
79At the tail end of
80.Xr critical_exit 9 ,
81if preemption was deferred due to the critical section.
82.It
83Within the TDA_SCHED AST handler, when rescheduling before the return to
84usermode was requested.
85There are several reasons for this, a notable one coming from
86.Fn sched_clock
87when the running thread has exceeded its time slice.
88.It
89In the signal handling code
90(see
91.Xr issignal 9 )
92if a signal is delivered that causes a process to stop.
93.It
94In
95.Fn thread_suspend_check
96where a thread needs to stop execution due to the suspension state of
97the process as a whole.
98.It
99In
100.Xr kern_yield 9
101when a thread wants to voluntarily relinquish the processor.
102.El
103.Pp
104The
105.Va flags
106argument to
107.Fn mi_switch
108indicates the context switch type.
109One of the following must be passed:
110.Bl -tag -offset indent -width "SWT_REMOTEWAKEIDLE"
111.It Dv SWT_OWEPREEMPT
112Switch due to delayed preemption after exiting a critical section.
113.It Dv SWT_TURNSTILE
114Switch after propagating scheduling priority to the owner of a resource.
115.It Dv SWT_SLEEPQ
116Begin waiting on a
117.Xr sleepqueue 9 .
118.It Dv SWT_RELINQUISH
119Yield call.
120.It Dv SWT_NEEDRESCHED
121Rescheduling was requested.
122.It Dv SWT_IDLE
123Switch from the idle thread.
124.It Dv SWT_IWAIT
125A kernel thread which handles interrupts has finished work and must wait for
126interrupts to schedule additional work.
127.It Dv SWT_SUSPEND
128Thread suspended.
129.It Dv SWT_REMOTEPREEMPT
130Preemption by a higher-priority thread, initiated by a remote processor.
131.It Dv SWT_REMOTEWAKEIDLE
132Idle thread preempted, initiated by a remote processor.
133.It Dv SWT_BIND
134The running thread has been bound to another processor and must be switched
135out.
136.El
137.Pp
138In addition to the switch type, callers must specify the nature of the
139switch by performing a bitwise OR with one of the
140.Dv SW_VOL
141or
142.Dv SW_INVOL
143flags, but not both.
144Respectively, these flags denote whether the context switch is voluntary or
145involuntary on the part of the current thread.
146For an involuntary context switch in which the running thread is
147being preempted, the caller should also pass the
148.Dv SW_PREEMPT
149flag.
150.Pp
151Upon entry to
152.Fn mi_switch ,
153the current thread must be holding its assigned thread lock.
154It may be unlocked as part of the context switch.
155After they have been rescheduled and execution resumes, threads will exit
156.Fn mi_switch
157with their thread lock unlocked.
158.Pp
159.Fn mi_switch
160records the amount of time the current thread has been running before handing
161control over to the scheduler, via
162.Fn sched_switch .
163After selecting a new thread to run, the scheduler will call
164.Fn cpu_switch
165to perform the low-level context switch.
166.Pp
167.Fn cpu_switch
168is the machine-dependent function that performs the actual switch from the
169running thread
170.Fa oldtd
171to the chosen thread
172.Fa newtd .
173First, it saves the context of
174.Fa oldtd
175to its Process Control Block,
176.Po
177PCB
178.Vt struct pcb
179.Pc ,
180pointed at by
181.Va oldtd->td_pcb .
182The function then updates important per-CPU state such as the
183.Dv curthread
184variable, and activates
185.Fa newtd\&'s
186virtual address space using its associated
187.Xr pmap 9
188structure.
189Finally, it reads in the saved context from
190.Fa newtd\&'s
191PCB.
192CPU instruction flow continues in the new thread context, on
193.Fa newtd\&'s
194kernel stack.
195The return from
196.Fn cpu_switch
197can be understood as a completion of the function call initiated by
198.Fa newtd
199when it was previously switched out, at some point in the distant (relative to
200CPU time) past.
201.Pp
202The
203.Fa mtx
204argument to
205.Fn cpu_switch
206is used to pass the mutex which will be stored as
207.Fa oldtd\&'s
208thread lock at the moment that
209.Fa oldtd
210is completely switched out.
211This is an implementation detail of
212.Fn sched_switch .
213.Pp
214.Fn cpu_throw
215is similar to
216.Fn cpu_switch
217except that it does not save the context of the old thread.
218This function is useful when the kernel does not have an old thread
219context to save, such as when CPUs other than the boot CPU perform their
220first task switch, or when the kernel does not care about the state of the
221old thread, such as in
222.Xr thread_exit 9
223when the kernel terminates the current thread and switches into a new
224thread,
225.Fa newtd .
226The
227.Fa oldtd
228argument is unused.
229.Sh SEE ALSO
230.Xr critical_exit 9 ,
231.Xr issignal 9 ,
232.Xr kern_yield 9 ,
233.Xr mutex 9 ,
234.Xr pmap 9 ,
235.Xr sleepqueue 9 ,
236.Xr thread_exit 9
237