xref: /freebsd/share/man/man9/mi_switch.9 (revision e0c4386e)
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.Dd January 9, 2023
35.Dt MI_SWITCH 9
36.Os
37.Sh NAME
38.Nm mi_switch ,
39.Nm cpu_switch ,
40.Nm cpu_throw
41.Nd switch to another thread context
42.Sh SYNOPSIS
43.In sys/param.h
44.In sys/proc.h
45.Ft void
46.Fn mi_switch "int flags"
47.Ft void
48.Fn cpu_switch "struct thread *oldtd" "struct thread *newtd" "struct mtx *lock"
49.Ft void
50.Fn cpu_throw "struct thread *oldtd" "struct thread *newtd"
51.Sh DESCRIPTION
52The
53.Fn mi_switch
54function implements the machine-independent prelude to a thread context
55switch.
56It is the single entry point for every context switch and is called from only
57a few distinguished places in the kernel.
58The context switch is, by necessity, always performed by the switched thread,
59even when the switch is initiated from elsewhere; e.g. preemption requested via
60Inter-Processor Interrupt (IPI).
61.Pp
62The various major uses of
63.Fn mi_switch
64can be enumerated as follows:
65.Bl -enum -offset indent
66.It
67From within a function such as
68.Xr sleepq_wait 9
69or
70.Fn turnstile_wait
71when the current thread
72voluntarily relinquishes the CPU to wait for some resource or lock to become
73available.
74.It
75Involuntary preemption due to arrival of a higher-priority thread.
76.It
77At the tail end of
78.Xr critical_exit 9 ,
79if preemption was deferred due to the critical section.
80.It
81Within the TDA_SCHED AST handler, when rescheduling before the return to
82usermode was requested.
83There are several reasons for this, a notable one coming from
84.Fn sched_clock
85when the running thread has exceeded its time slice.
86.It
87In the signal handling code
88(see
89.Xr issignal 9 )
90if a signal is delivered that causes a process to stop.
91.It
92In
93.Fn thread_suspend_check
94where a thread needs to stop execution due to the suspension state of
95the process as a whole.
96.It
97In
98.Xr kern_yield 9
99when a thread wants to voluntarily relinquish the processor.
100.El
101.Pp
102The
103.Va flags
104argument to
105.Fn mi_switch
106indicates the context switch type.
107One of the following must be passed:
108.Bl -tag -offset indent -width "SWT_REMOTEWAKEIDLE"
109.It Dv SWT_OWEPREEMPT
110Switch due to delayed preemption after exiting a critical section.
111.It Dv SWT_TURNSTILE
112Switch after propagating scheduling priority to the owner of a resource.
113.It Dv SWT_SLEEPQ
114Begin waiting on a
115.Xr sleepqueue 9 .
116.It Dv SWT_RELINQUISH
117Yield call.
118.It Dv SWT_NEEDRESCHED
119Rescheduling was requested.
120.It Dv SWT_IDLE
121Switch from the idle thread.
122.It Dv SWT_IWAIT
123A kernel thread which handles interrupts has finished work and must wait for
124interrupts to schedule additional work.
125.It Dv SWT_SUSPEND
126Thread suspended.
127.It Dv SWT_REMOTEPREEMPT
128Preemption by a higher-priority thread, initiated by a remote processor.
129.It Dv SWT_REMOTEWAKEIDLE
130Idle thread preempted, initiated by a remote processor.
131.It Dv SWT_BIND
132The running thread has been bound to another processor and must be switched
133out.
134.El
135.Pp
136In addition to the switch type, callers must specify the nature of the
137switch by performing a bitwise OR with one of the
138.Dv SW_VOL
139or
140.Dv SW_INVOL
141flags, but not both.
142Respectively, these flags denote whether the context switch is voluntary or
143involuntary on the part of the current thread.
144For an involuntary context switch in which the running thread is
145being preempted, the caller should also pass the
146.Dv SW_PREEMPT
147flag.
148.Pp
149Upon entry to
150.Fn mi_switch ,
151the current thread must be holding its assigned thread lock.
152It may be unlocked as part of the context switch.
153After they have been rescheduled and execution resumes, threads will exit
154.Fn mi_switch
155with their thread lock unlocked.
156.Pp
157.Fn mi_switch
158records the amount of time the current thread has been running before handing
159control over to the scheduler, via
160.Fn sched_switch .
161After selecting a new thread to run, the scheduler will call
162.Fn cpu_switch
163to perform the low-level context switch.
164.Pp
165.Fn cpu_switch
166is the machine-dependent function that performs the actual switch from the
167running thread
168.Fa oldtd
169to the chosen thread
170.Fa newtd .
171First, it saves the context of
172.Fa oldtd
173to its Process Control Block
174.Po
175PCB,
176.Vt struct pcb
177.Pc ,
178pointed at by
179.Va oldtd->td_pcb .
180The function then updates important per-CPU state such as the
181.Dv curthread
182variable, and activates
183.Fa newtd\&'s
184virtual address space using its associated
185.Xr pmap 9
186structure.
187Finally, it reads in the saved context from
188.Fa newtd\&'s
189PCB.
190CPU instruction flow continues in the new thread context, on
191.Fa newtd\&'s
192kernel stack.
193The return from
194.Fn cpu_switch
195can be understood as a completion of the function call initiated by
196.Fa newtd
197when it was previously switched out, at some point in the distant (relative to
198CPU time) past.
199.Pp
200The
201.Fa mtx
202argument to
203.Fn cpu_switch
204is used to pass the mutex which will be stored as
205.Fa oldtd\&'s
206thread lock at the moment that
207.Fa oldtd
208is completely switched out.
209This is an implementation detail of
210.Fn sched_switch .
211.Pp
212.Fn cpu_throw
213is similar to
214.Fn cpu_switch
215except that it does not save the context of the old thread.
216This function is useful when the kernel does not have an old thread
217context to save, such as when CPUs other than the boot CPU perform their
218first task switch, or when the kernel does not care about the state of the
219old thread, such as in
220.Xr thread_exit 9
221when the kernel terminates the current thread and switches into a new
222thread,
223.Fa newtd .
224The
225.Fa oldtd
226argument is unused.
227.Sh SEE ALSO
228.Xr critical_exit 9 ,
229.Xr issignal 9 ,
230.Xr kern_yield 9 ,
231.Xr mutex 9 ,
232.Xr pmap 9 ,
233.Xr sleepqueue 9 ,
234.Xr thread_exit 9
235