假如有4个cpu 现在有5个进程 且都是密集型计算的任务 不会主动让出cpu
那么kernel怎么保证公平调度?
root@NYX-RK3568:/data# cat /proc/interrupts
CPU0 CPU1 CPU2 CPU3
5: 98148 61882 174660 91318 GICv3 26 Level arch_timer
#0 task_tick_fair (rq=0xffffffc0efec7080, curr=0xffffffc0e92863c0, queued=0) at kernel/sched/fair.c:10901
#1 0xffffff80080e4304 in scheduler_tick () at kernel/sched/core.c:3668
#2 0xffffff8008133d28 in update_process_times (user_tick=0) at kernel/time/timer.c:1655
#3 0xffffff8008144a84 in tick_sched_handle (ts=0xffffffc0efec3560, regs=<optimized out>) at kernel/time/tick-sched.c:169
#4 0xffffff8008144ae8 in tick_sched_timer (timer=0xffffffc0efec3560) at kernel/time/tick-sched.c:1292
#5 0xffffff8008134fb0 in __run_hrtimer (flags=<optimized out>, now=<optimized out>, timer=<optimized out>, base=<optimized out>, cpu_base=<optimized out>)
at kernel/time/hrtimer.c:1465
#6 __hrtimer_run_queues (cpu_base=0xffffffc0efec2ec0, now=<optimized out>, flags=128, active_mask=<optimized out>) at kernel/time/hrtimer.c:1527
#7 0xffffff8008135408 in hrtimer_interrupt (dev=<optimized out>) at kernel/time/hrtimer.c:1585
#8 0xffffff8008a74ef8 in timer_handler (evt=<optimized out>, access=<optimized out>) at drivers/clocksource/arm_arch_timer.c:645
#9 arch_timer_handler_phys (irq=<optimized out>, dev_id=0xffffffc0efecd900) at drivers/clocksource/arm_arch_timer.c:663
#10 0xffffff800811723c in handle_percpu_devid_irq (desc=0xffffffc0e99ef400) at kernel/irq/chip.c:926
#11 0xffffff8008111214 in generic_handle_irq_desc (desc=<optimized out>) at ./include/linux/irqdesc.h:155
#12 generic_handle_irq (irq=5) at kernel/irq/irqdesc.c:639
//以上是标记
do_notify_resume
...
if (thread_flags & _TIF_NEED_RESCHED) {
/* Unmask Debug and SError for the next task */
local_daif_restore(DAIF_PROCCTX_NOIRQ);
schedule(); ///
-->static void __sched notrace __schedule(bool preempt)
-->
static inline struct task_struct *
pick_next_task(struct rq *rq, struct task_struct *prev, struct rq_flags *rf)
{
const struct sched_class *class;
struct task_struct *p;
if (likely((prev->sched_class == &idle_sched_class ||
prev->sched_class == &fair_sched_class) &&
rq->nr_running == rq->cfs.h_nr_running)) {
p = fair_sched_class.pick_next_task(rq, prev, rf);
优先级
DL调度类(dl_sched_class)→ RT调度类(rt_sched_class)→ CFS调度类(fair_sched_class)→ idle调度类
/// stack info
work_pending:
mov x0, sp // 'regs'
bl do_notify_resume
#ifdef CONFIG_TRACE_IRQFLAGS
bl trace_hardirqs_on // enabled while in userspace
#endif
ldr x1, [tsk, #TSK_TI_FLAGS] // re-check for single-step
b finish_ret_to_user
ret_to_user:
disable_daif
ldr x1, [tsk, #TSK_TI_FLAGS]
and x2, x1, #_TIF_WORK_MASK
cbnz x2, work_pending
finish_ret_to_user:
enable_step_tsk x1, x2
#ifdef CONFIG_GCC_PLUGIN_STACKLEAK
bl stackleak_erase
#endif
kernel_exit 0
ENDPROC(ret_to_user)
el0_svc:
mov x0, sp
bl el0_svc_handler
b ret_to_user
ENDPROC(el0_svc)