xref: /linux-6.15/kernel/sched/stop_task.c (revision b2d70222)
1b2441318SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0
2391e43daSPeter Zijlstra /*
3391e43daSPeter Zijlstra  * stop-task scheduling class.
4391e43daSPeter Zijlstra  *
5391e43daSPeter Zijlstra  * The stop task is the highest priority task in the system, it preempts
6391e43daSPeter Zijlstra  * everything and will be preempted by nothing.
7391e43daSPeter Zijlstra  *
8391e43daSPeter Zijlstra  * See kernel/stop_machine.c
9391e43daSPeter Zijlstra  */
10391e43daSPeter Zijlstra 
11391e43daSPeter Zijlstra #ifdef CONFIG_SMP
12391e43daSPeter Zijlstra static int
select_task_rq_stop(struct task_struct * p,int cpu,int flags)133aef1551SValentin Schneider select_task_rq_stop(struct task_struct *p, int cpu, int flags)
14391e43daSPeter Zijlstra {
15391e43daSPeter Zijlstra 	return task_cpu(p); /* stop tasks as never migrate */
16391e43daSPeter Zijlstra }
176e2df058SPeter Zijlstra 
186e2df058SPeter Zijlstra static int
balance_stop(struct rq * rq,struct task_struct * prev,struct rq_flags * rf)196e2df058SPeter Zijlstra balance_stop(struct rq *rq, struct task_struct *prev, struct rq_flags *rf)
206e2df058SPeter Zijlstra {
216e2df058SPeter Zijlstra 	return sched_stop_runnable(rq);
226e2df058SPeter Zijlstra }
23391e43daSPeter Zijlstra #endif /* CONFIG_SMP */
24391e43daSPeter Zijlstra 
25391e43daSPeter Zijlstra static void
wakeup_preempt_stop(struct rq * rq,struct task_struct * p,int flags)26e23edc86SIngo Molnar wakeup_preempt_stop(struct rq *rq, struct task_struct *p, int flags)
27391e43daSPeter Zijlstra {
28391e43daSPeter Zijlstra 	/* we're never preempted */
29391e43daSPeter Zijlstra }
30391e43daSPeter Zijlstra 
set_next_task_stop(struct rq * rq,struct task_struct * stop,bool first)31a0e813f2SPeter Zijlstra static void set_next_task_stop(struct rq *rq, struct task_struct *stop, bool first)
3203b7fad1SPeter Zijlstra {
3303b7fad1SPeter Zijlstra 	stop->se.exec_start = rq_clock_task(rq);
3403b7fad1SPeter Zijlstra }
3503b7fad1SPeter Zijlstra 
pick_task_stop(struct rq * rq)3621f56ffeSPeter Zijlstra static struct task_struct *pick_task_stop(struct rq *rq)
37391e43daSPeter Zijlstra {
386e2df058SPeter Zijlstra 	if (!sched_stop_runnable(rq))
39391e43daSPeter Zijlstra 		return NULL;
40606dba2eSPeter Zijlstra 
416e2df058SPeter Zijlstra 	return rq->stop;
42391e43daSPeter Zijlstra }
43391e43daSPeter Zijlstra 
44391e43daSPeter Zijlstra static void
enqueue_task_stop(struct rq * rq,struct task_struct * p,int flags)45391e43daSPeter Zijlstra enqueue_task_stop(struct rq *rq, struct task_struct *p, int flags)
46391e43daSPeter Zijlstra {
4772465447SKirill Tkhai 	add_nr_running(rq, 1);
48391e43daSPeter Zijlstra }
49391e43daSPeter Zijlstra 
50863ccdbbSPeter Zijlstra static bool
dequeue_task_stop(struct rq * rq,struct task_struct * p,int flags)51391e43daSPeter Zijlstra dequeue_task_stop(struct rq *rq, struct task_struct *p, int flags)
52391e43daSPeter Zijlstra {
5372465447SKirill Tkhai 	sub_nr_running(rq, 1);
54863ccdbbSPeter Zijlstra 	return true;
55391e43daSPeter Zijlstra }
56391e43daSPeter Zijlstra 
yield_task_stop(struct rq * rq)57391e43daSPeter Zijlstra static void yield_task_stop(struct rq *rq)
58391e43daSPeter Zijlstra {
59391e43daSPeter Zijlstra 	BUG(); /* the stop task should never yield, its pointless. */
60391e43daSPeter Zijlstra }
61391e43daSPeter Zijlstra 
put_prev_task_stop(struct rq * rq,struct task_struct * prev,struct task_struct * next)62*b2d70222SPeter Zijlstra static void put_prev_task_stop(struct rq *rq, struct task_struct *prev, struct task_struct *next)
63391e43daSPeter Zijlstra {
645d69eca5SPeter Zijlstra 	update_curr_common(rq);
65391e43daSPeter Zijlstra }
66391e43daSPeter Zijlstra 
67d84b3131SFrederic Weisbecker /*
68d84b3131SFrederic Weisbecker  * scheduler tick hitting a task of our scheduling class.
69d84b3131SFrederic Weisbecker  *
70d84b3131SFrederic Weisbecker  * NOTE: This function can be called remotely by the tick offload that
71d84b3131SFrederic Weisbecker  * goes along full dynticks. Therefore no local assumption can be made
72d84b3131SFrederic Weisbecker  * and everything must be accessed through the @rq and @curr passed in
73d84b3131SFrederic Weisbecker  * parameters.
74d84b3131SFrederic Weisbecker  */
task_tick_stop(struct rq * rq,struct task_struct * curr,int queued)75391e43daSPeter Zijlstra static void task_tick_stop(struct rq *rq, struct task_struct *curr, int queued)
76391e43daSPeter Zijlstra {
77391e43daSPeter Zijlstra }
78391e43daSPeter Zijlstra 
switched_to_stop(struct rq * rq,struct task_struct * p)79391e43daSPeter Zijlstra static void switched_to_stop(struct rq *rq, struct task_struct *p)
80391e43daSPeter Zijlstra {
81391e43daSPeter Zijlstra 	BUG(); /* its impossible to change to this class */
82391e43daSPeter Zijlstra }
83391e43daSPeter Zijlstra 
84391e43daSPeter Zijlstra static void
prio_changed_stop(struct rq * rq,struct task_struct * p,int oldprio)85391e43daSPeter Zijlstra prio_changed_stop(struct rq *rq, struct task_struct *p, int oldprio)
86391e43daSPeter Zijlstra {
87391e43daSPeter Zijlstra 	BUG(); /* how!?, what priority? */
88391e43daSPeter Zijlstra }
89391e43daSPeter Zijlstra 
update_curr_stop(struct rq * rq)9090e362f4SThomas Gleixner static void update_curr_stop(struct rq *rq)
9190e362f4SThomas Gleixner {
9290e362f4SThomas Gleixner }
9390e362f4SThomas Gleixner 
94391e43daSPeter Zijlstra /*
95391e43daSPeter Zijlstra  * Simple, special scheduling class for the per-CPU stop tasks:
96391e43daSPeter Zijlstra  */
9743c31ac0SPeter Zijlstra DEFINE_SCHED_CLASS(stop) = {
98391e43daSPeter Zijlstra 
99391e43daSPeter Zijlstra 	.enqueue_task		= enqueue_task_stop,
100391e43daSPeter Zijlstra 	.dequeue_task		= dequeue_task_stop,
101391e43daSPeter Zijlstra 	.yield_task		= yield_task_stop,
102391e43daSPeter Zijlstra 
103e23edc86SIngo Molnar 	.wakeup_preempt		= wakeup_preempt_stop,
104391e43daSPeter Zijlstra 
105fd03c5b8SPeter Zijlstra 	.pick_task		= pick_task_stop,
106391e43daSPeter Zijlstra 	.put_prev_task		= put_prev_task_stop,
10703b7fad1SPeter Zijlstra 	.set_next_task          = set_next_task_stop,
108391e43daSPeter Zijlstra 
109391e43daSPeter Zijlstra #ifdef CONFIG_SMP
1106e2df058SPeter Zijlstra 	.balance		= balance_stop,
111391e43daSPeter Zijlstra 	.select_task_rq		= select_task_rq_stop,
112c5b28038SPeter Zijlstra 	.set_cpus_allowed	= set_cpus_allowed_common,
113391e43daSPeter Zijlstra #endif
114391e43daSPeter Zijlstra 
115391e43daSPeter Zijlstra 	.task_tick		= task_tick_stop,
116391e43daSPeter Zijlstra 
117391e43daSPeter Zijlstra 	.prio_changed		= prio_changed_stop,
118391e43daSPeter Zijlstra 	.switched_to		= switched_to_stop,
11990e362f4SThomas Gleixner 	.update_curr		= update_curr_stop,
120391e43daSPeter Zijlstra };
121