xref: /openbmc/linux/kernel/sched/stop_task.c (revision 278002edb19bce2c628fafb0af936e77000f3a5b)
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)26b2f7d750SIngo 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 
pick_next_task_stop(struct rq * rq)4421f56ffeSPeter Zijlstra static struct task_struct *pick_next_task_stop(struct rq *rq)
4521f56ffeSPeter Zijlstra {
4621f56ffeSPeter Zijlstra 	struct task_struct *p = pick_task_stop(rq);
4721f56ffeSPeter Zijlstra 
4821f56ffeSPeter Zijlstra 	if (p)
4921f56ffeSPeter Zijlstra 		set_next_task_stop(rq, p, true);
5021f56ffeSPeter Zijlstra 
5121f56ffeSPeter Zijlstra 	return p;
5221f56ffeSPeter Zijlstra }
5321f56ffeSPeter Zijlstra 
54391e43daSPeter Zijlstra static void
enqueue_task_stop(struct rq * rq,struct task_struct * p,int flags)55391e43daSPeter Zijlstra enqueue_task_stop(struct rq *rq, struct task_struct *p, int flags)
56391e43daSPeter Zijlstra {
5772465447SKirill Tkhai 	add_nr_running(rq, 1);
58391e43daSPeter Zijlstra }
59391e43daSPeter Zijlstra 
60391e43daSPeter Zijlstra static void
dequeue_task_stop(struct rq * rq,struct task_struct * p,int flags)61391e43daSPeter Zijlstra dequeue_task_stop(struct rq *rq, struct task_struct *p, int flags)
62391e43daSPeter Zijlstra {
6372465447SKirill Tkhai 	sub_nr_running(rq, 1);
64391e43daSPeter Zijlstra }
65391e43daSPeter Zijlstra 
yield_task_stop(struct rq * rq)66391e43daSPeter Zijlstra static void yield_task_stop(struct rq *rq)
67391e43daSPeter Zijlstra {
68391e43daSPeter Zijlstra 	BUG(); /* the stop task should never yield, its pointless. */
69391e43daSPeter Zijlstra }
70391e43daSPeter Zijlstra 
put_prev_task_stop(struct rq * rq,struct task_struct * prev)716e2df058SPeter Zijlstra static void put_prev_task_stop(struct rq *rq, struct task_struct *prev)
72391e43daSPeter Zijlstra {
73*4db5988bSPeter Zijlstra 	update_curr_common(rq);
74391e43daSPeter Zijlstra }
75391e43daSPeter Zijlstra 
76d84b3131SFrederic Weisbecker /*
77d84b3131SFrederic Weisbecker  * scheduler tick hitting a task of our scheduling class.
78d84b3131SFrederic Weisbecker  *
79d84b3131SFrederic Weisbecker  * NOTE: This function can be called remotely by the tick offload that
80d84b3131SFrederic Weisbecker  * goes along full dynticks. Therefore no local assumption can be made
81d84b3131SFrederic Weisbecker  * and everything must be accessed through the @rq and @curr passed in
82d84b3131SFrederic Weisbecker  * parameters.
83d84b3131SFrederic Weisbecker  */
task_tick_stop(struct rq * rq,struct task_struct * curr,int queued)84391e43daSPeter Zijlstra static void task_tick_stop(struct rq *rq, struct task_struct *curr, int queued)
85391e43daSPeter Zijlstra {
86391e43daSPeter Zijlstra }
87391e43daSPeter Zijlstra 
switched_to_stop(struct rq * rq,struct task_struct * p)88391e43daSPeter Zijlstra static void switched_to_stop(struct rq *rq, struct task_struct *p)
89391e43daSPeter Zijlstra {
90391e43daSPeter Zijlstra 	BUG(); /* its impossible to change to this class */
91391e43daSPeter Zijlstra }
92391e43daSPeter Zijlstra 
93391e43daSPeter Zijlstra static void
prio_changed_stop(struct rq * rq,struct task_struct * p,int oldprio)94391e43daSPeter Zijlstra prio_changed_stop(struct rq *rq, struct task_struct *p, int oldprio)
95391e43daSPeter Zijlstra {
96391e43daSPeter Zijlstra 	BUG(); /* how!?, what priority? */
97391e43daSPeter Zijlstra }
98391e43daSPeter Zijlstra 
update_curr_stop(struct rq * rq)9990e362f4SThomas Gleixner static void update_curr_stop(struct rq *rq)
10090e362f4SThomas Gleixner {
10190e362f4SThomas Gleixner }
10290e362f4SThomas Gleixner 
103391e43daSPeter Zijlstra /*
104391e43daSPeter Zijlstra  * Simple, special scheduling class for the per-CPU stop tasks:
105391e43daSPeter Zijlstra  */
10643c31ac0SPeter Zijlstra DEFINE_SCHED_CLASS(stop) = {
107391e43daSPeter Zijlstra 
108391e43daSPeter Zijlstra 	.enqueue_task		= enqueue_task_stop,
109391e43daSPeter Zijlstra 	.dequeue_task		= dequeue_task_stop,
110391e43daSPeter Zijlstra 	.yield_task		= yield_task_stop,
111391e43daSPeter Zijlstra 
112b2f7d750SIngo Molnar 	.wakeup_preempt		= wakeup_preempt_stop,
113391e43daSPeter Zijlstra 
114391e43daSPeter Zijlstra 	.pick_next_task		= pick_next_task_stop,
115391e43daSPeter Zijlstra 	.put_prev_task		= put_prev_task_stop,
11603b7fad1SPeter Zijlstra 	.set_next_task          = set_next_task_stop,
117391e43daSPeter Zijlstra 
118391e43daSPeter Zijlstra #ifdef CONFIG_SMP
1196e2df058SPeter Zijlstra 	.balance		= balance_stop,
12021f56ffeSPeter Zijlstra 	.pick_task		= pick_task_stop,
121391e43daSPeter Zijlstra 	.select_task_rq		= select_task_rq_stop,
122c5b28038SPeter Zijlstra 	.set_cpus_allowed	= set_cpus_allowed_common,
123391e43daSPeter Zijlstra #endif
124391e43daSPeter Zijlstra 
125391e43daSPeter Zijlstra 	.task_tick		= task_tick_stop,
126391e43daSPeter Zijlstra 
127391e43daSPeter Zijlstra 	.prio_changed		= prio_changed_stop,
128391e43daSPeter Zijlstra 	.switched_to		= switched_to_stop,
12990e362f4SThomas Gleixner 	.update_curr		= update_curr_stop,
130391e43daSPeter Zijlstra };
131