diff options
Diffstat (limited to 'kernel/sched/stop_task.c')
| -rw-r--r-- | kernel/sched/stop_task.c | 102 |
1 files changed, 48 insertions, 54 deletions
diff --git a/kernel/sched/stop_task.c b/kernel/sched/stop_task.c index e08fbeeb54b9..4f9192be4b5b 100644 --- a/kernel/sched/stop_task.c +++ b/kernel/sched/stop_task.c @@ -1,5 +1,4 @@ -#include "sched.h" - +// SPDX-License-Identifier: GPL-2.0 /* * stop-task scheduling class. * @@ -8,43 +7,50 @@ * * See kernel/stop_machine.c */ +#include "sched.h" -#ifdef CONFIG_SMP static int -select_task_rq_stop(struct task_struct *p, int sd_flag, int flags) +select_task_rq_stop(struct task_struct *p, int cpu, int flags) { return task_cpu(p); /* stop tasks as never migrate */ } -#endif /* CONFIG_SMP */ + +static int +balance_stop(struct rq *rq, struct task_struct *prev, struct rq_flags *rf) +{ + return sched_stop_runnable(rq); +} static void -check_preempt_curr_stop(struct rq *rq, struct task_struct *p, int flags) +wakeup_preempt_stop(struct rq *rq, struct task_struct *p, int flags) { /* we're never preempted */ } -static struct task_struct *pick_next_task_stop(struct rq *rq) +static void set_next_task_stop(struct rq *rq, struct task_struct *stop, bool first) { - struct task_struct *stop = rq->stop; + stop->se.exec_start = rq_clock_task(rq); +} - if (stop && stop->on_rq) { - stop->se.exec_start = rq_clock_task(rq); - return stop; - } +static struct task_struct *pick_task_stop(struct rq *rq, struct rq_flags *rf) +{ + if (!sched_stop_runnable(rq)) + return NULL; - return NULL; + return rq->stop; } static void enqueue_task_stop(struct rq *rq, struct task_struct *p, int flags) { - inc_nr_running(rq); + add_nr_running(rq, 1); } -static void +static bool dequeue_task_stop(struct rq *rq, struct task_struct *p, int flags) { - dec_nr_running(rq); + sub_nr_running(rq, 1); + return true; } static void yield_task_stop(struct rq *rq) @@ -52,77 +58,65 @@ static void yield_task_stop(struct rq *rq) BUG(); /* the stop task should never yield, its pointless. */ } -static void put_prev_task_stop(struct rq *rq, struct task_struct *prev) +static void put_prev_task_stop(struct rq *rq, struct task_struct *prev, struct task_struct *next) { - struct task_struct *curr = rq->curr; - u64 delta_exec; - - delta_exec = rq_clock_task(rq) - curr->se.exec_start; - if (unlikely((s64)delta_exec < 0)) - delta_exec = 0; - - schedstat_set(curr->se.statistics.exec_max, - max(curr->se.statistics.exec_max, delta_exec)); - - curr->se.sum_exec_runtime += delta_exec; - account_group_exec_runtime(curr, delta_exec); - - curr->se.exec_start = rq_clock_task(rq); - cpuacct_charge(curr, delta_exec); + update_curr_common(rq); } +/* + * scheduler tick hitting a task of our scheduling class. + * + * NOTE: This function can be called remotely by the tick offload that + * goes along full dynticks. Therefore no local assumption can be made + * and everything must be accessed through the @rq and @curr passed in + * parameters. + */ static void task_tick_stop(struct rq *rq, struct task_struct *curr, int queued) { } -static void set_curr_task_stop(struct rq *rq) -{ - struct task_struct *stop = rq->stop; - - stop->se.exec_start = rq_clock_task(rq); -} - -static void switched_to_stop(struct rq *rq, struct task_struct *p) +static void switching_to_stop(struct rq *rq, struct task_struct *p) { BUG(); /* its impossible to change to this class */ } static void -prio_changed_stop(struct rq *rq, struct task_struct *p, int oldprio) +prio_changed_stop(struct rq *rq, struct task_struct *p, u64 oldprio) { + if (p->prio == oldprio) + return; + BUG(); /* how!?, what priority? */ } -static unsigned int -get_rr_interval_stop(struct rq *rq, struct task_struct *task) +static void update_curr_stop(struct rq *rq) { - return 0; } /* * Simple, special scheduling class for the per-CPU stop tasks: */ -const struct sched_class stop_sched_class = { - .next = &rt_sched_class, +DEFINE_SCHED_CLASS(stop) = { + + .queue_mask = 16, .enqueue_task = enqueue_task_stop, .dequeue_task = dequeue_task_stop, .yield_task = yield_task_stop, - .check_preempt_curr = check_preempt_curr_stop, + .wakeup_preempt = wakeup_preempt_stop, - .pick_next_task = pick_next_task_stop, + .pick_task = pick_task_stop, .put_prev_task = put_prev_task_stop, + .set_next_task = set_next_task_stop, -#ifdef CONFIG_SMP + .balance = balance_stop, .select_task_rq = select_task_rq_stop, -#endif + .set_cpus_allowed = set_cpus_allowed_common, - .set_curr_task = set_curr_task_stop, .task_tick = task_tick_stop, - .get_rr_interval = get_rr_interval_stop, - .prio_changed = prio_changed_stop, - .switched_to = switched_to_stop, + .switching_to = switching_to_stop, + .update_curr = update_curr_stop, }; |
