1 // SPDX-License-Identifier: GPL-2.0
2 #include "sched.h"
3 #include "walt.h"
4
5 /*
6 * stop-task scheduling class.
7 *
8 * The stop task is the highest priority task in the system, it preempts
9 * everything and will be preempted by nothing.
10 *
11 * See kernel/stop_machine.c
12 */
13
14 #ifdef CONFIG_SMP
15 static int
select_task_rq_stop(struct task_struct * p,int cpu,int sd_flag,int flags,int sibling_count_hint)16 select_task_rq_stop(struct task_struct *p, int cpu, int sd_flag, int flags,
17 int sibling_count_hint)
18 {
19 return task_cpu(p); /* stop tasks as never migrate */
20 }
21 #endif /* CONFIG_SMP */
22
23 static void
check_preempt_curr_stop(struct rq * rq,struct task_struct * p,int flags)24 check_preempt_curr_stop(struct rq *rq, struct task_struct *p, int flags)
25 {
26 /* we're never preempted */
27 }
28
29 static struct task_struct *
pick_next_task_stop(struct rq * rq,struct task_struct * prev,struct rq_flags * rf)30 pick_next_task_stop(struct rq *rq, struct task_struct *prev, struct rq_flags *rf)
31 {
32 struct task_struct *stop = rq->stop;
33
34 if (!stop || !task_on_rq_queued(stop))
35 return NULL;
36
37 put_prev_task(rq, prev);
38
39 stop->se.exec_start = rq_clock_task(rq);
40
41 return stop;
42 }
43
44 static void
enqueue_task_stop(struct rq * rq,struct task_struct * p,int flags)45 enqueue_task_stop(struct rq *rq, struct task_struct *p, int flags)
46 {
47 add_nr_running(rq, 1);
48 walt_inc_cumulative_runnable_avg(rq, p);
49 }
50
51 static void
dequeue_task_stop(struct rq * rq,struct task_struct * p,int flags)52 dequeue_task_stop(struct rq *rq, struct task_struct *p, int flags)
53 {
54 sub_nr_running(rq, 1);
55 walt_dec_cumulative_runnable_avg(rq, p);
56 }
57
yield_task_stop(struct rq * rq)58 static void yield_task_stop(struct rq *rq)
59 {
60 BUG(); /* the stop task should never yield, its pointless. */
61 }
62
put_prev_task_stop(struct rq * rq,struct task_struct * prev)63 static void put_prev_task_stop(struct rq *rq, struct task_struct *prev)
64 {
65 struct task_struct *curr = rq->curr;
66 u64 delta_exec;
67
68 delta_exec = rq_clock_task(rq) - curr->se.exec_start;
69 if (unlikely((s64)delta_exec < 0))
70 delta_exec = 0;
71
72 schedstat_set(curr->se.statistics.exec_max,
73 max(curr->se.statistics.exec_max, delta_exec));
74
75 curr->se.sum_exec_runtime += delta_exec;
76 account_group_exec_runtime(curr, delta_exec);
77
78 curr->se.exec_start = rq_clock_task(rq);
79 cpuacct_charge(curr, delta_exec);
80 }
81
task_tick_stop(struct rq * rq,struct task_struct * curr,int queued)82 static void task_tick_stop(struct rq *rq, struct task_struct *curr, int queued)
83 {
84 }
85
set_curr_task_stop(struct rq * rq)86 static void set_curr_task_stop(struct rq *rq)
87 {
88 struct task_struct *stop = rq->stop;
89
90 stop->se.exec_start = rq_clock_task(rq);
91 }
92
switched_to_stop(struct rq * rq,struct task_struct * p)93 static void switched_to_stop(struct rq *rq, struct task_struct *p)
94 {
95 BUG(); /* its impossible to change to this class */
96 }
97
98 static void
prio_changed_stop(struct rq * rq,struct task_struct * p,int oldprio)99 prio_changed_stop(struct rq *rq, struct task_struct *p, int oldprio)
100 {
101 BUG(); /* how!?, what priority? */
102 }
103
104 static unsigned int
get_rr_interval_stop(struct rq * rq,struct task_struct * task)105 get_rr_interval_stop(struct rq *rq, struct task_struct *task)
106 {
107 return 0;
108 }
109
update_curr_stop(struct rq * rq)110 static void update_curr_stop(struct rq *rq)
111 {
112 }
113
114 /*
115 * Simple, special scheduling class for the per-CPU stop tasks:
116 */
117 const struct sched_class stop_sched_class = {
118 .next = &dl_sched_class,
119
120 .enqueue_task = enqueue_task_stop,
121 .dequeue_task = dequeue_task_stop,
122 .yield_task = yield_task_stop,
123
124 .check_preempt_curr = check_preempt_curr_stop,
125
126 .pick_next_task = pick_next_task_stop,
127 .put_prev_task = put_prev_task_stop,
128
129 #ifdef CONFIG_SMP
130 .select_task_rq = select_task_rq_stop,
131 .set_cpus_allowed = set_cpus_allowed_common,
132 #endif
133
134 .set_curr_task = set_curr_task_stop,
135 .task_tick = task_tick_stop,
136
137 .get_rr_interval = get_rr_interval_stop,
138
139 .prio_changed = prio_changed_stop,
140 .switched_to = switched_to_stop,
141 .update_curr = update_curr_stop,
142 };
143