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