/* kernel/sched/core.c — context switch */
static void __sched notrace __schedule(unsigned int sched_mode)
{
struct task_struct *prev, *next;
unsigned long *switch_count;
struct rq_flags rf;
struct rq *rq;
int cpu;
cpu = smp_processor_id();
rq = cpu_rq(cpu);
prev = rq->curr;
schedule_debug(prev, !!sched_mode);
if (sched_feat(HRTICK) || sched_feat(HRTICK_DL))
hrtick_clear(rq);
local_irq_disable();
rcu_note_context_switch(!!sched_mode);
rq_lock(rq, &rf);
smp_mb__after_spinlock();
rq->clock_update_flags <<= 1;
update_rq_clock(rq);
next = pick_next_task(rq, prev, &rf);
clear_tsk_need_resched(prev);
clear_preempt_need_resched();
if (likely(prev != next)) {
rq->nr_switches++;
rq->curr = next;
++*switch_count;
migrate_disable_switch(rq, prev);
psi_account_irqtime(rq, prev, next);
rq = context_switch(rq, prev, next, &rf);
} else {
rq_unlock_irq(rq, &rf);
}
balance_callbacks(rq, head);
}
/* kernel/sched/core.c — context switch */
static void __sched notrace __schedule(unsigned int sched_mode)
{
struct task_struct *prev, *next;
unsigned long *switch_count;
struct rq_flags rf;
struct rq *rq;
int cpu;
cpu = smp_processor_id();
rq = cpu_rq(cpu);
prev = rq->curr;
schedule_debug(prev, !!sched_mode);
if (sched_feat(HRTICK) || sched_feat(HRTICK_DL))
hrtick_clear(rq);
local_irq_disable();
rcu_note_context_switch(!!sched_mode);
rq_lock(rq, &rf);
smp_mb__after_spinlock();
rq->clock_update_flags <<= 1;
update_rq_clock(rq);
next = pick_next_task(rq, prev, &rf);
clear_tsk_need_resched(prev);
clear_preempt_need_resched();
if (likely(prev != next)) {
rq->nr_switches++;
rq->curr = next;
++*switch_count;
migrate_disable_switch(rq, prev);
psi_account_irqtime(rq, prev, next);
rq = context_switch(rq, prev, next, &rf);
} else {
rq_unlock_irq(rq, &rf);
}
balance_callbacks(rq, head);
}