目录
1. 前言
本专题我们开始学习进程管理部分。本文主要参考了《奔跑吧, Linux内核》、ULA、ULK的相关内容。本文只是作为学习笔记以用于构建知识框架,可能存在一些理解不恰当或不到位的地方,后续会随着学习的深入,逐步进行迭代。
在进程管理概述部分介绍过,进程的抢占分为触发抢占(设置TIF_NEED_RESCHED标记)和执行抢占,执行抢占的过程就是调用了schedule,其核心函数为__schedule。
kernel版本:5.10
平台:arm64
2. __schedule

这段注释翻译成中文如下:
__schedule()是调度器的主函数
让调度器执行调度,并进入到__schedule()函数的方法主要有:
1.调用block的函数,如: mutex, semaphore, waitqueue等等。
2.在中断时返回用户空间时会检查TIF_NEED_RESCHED标志。例如:可以参考arch/x86/entry_64.S:
为了触发抢占,在定时器中断处理函数scheduler_tick()中,调度器会设置TIF_NEED_RESCHED 抢占标志;
3.唤醒一个进程并不真正会引发执行schedule()。唤醒只是添加一个进程到run-queue,仅此而已;
假设,如果一个新的进程被添加到run-queue, 如果抢占当前运行的进程,唤醒操作会设置当前进程的TIF_NEED_RESCHED 标志,
在第一次发生如下情形时,schedule()会被调用:
(1)如果kernel允许抢占(CONFIG_PREEMPT=y)
- 在系统调用或异常上下文,preempt_enable()中会执行schedule()抢占调度(这种情形一般是在wake_up()后执行spin_unlock()时);
- 在中断上下文,从中断处理函数返回到被中断的上下文
(2)如果kernel抢占被禁用 (CONFIG_PREEMPT is not set),那么在下一次遇到如下情形时会执行schedule()抢占调度
- cond_resched()调用
- schedule()调用
- 从系统调用或异常返回到用户空间时
- 从中断处理函数返回到用户空间时
对如上注释进行简单总结为:
- 如果内核允许抢占,如下时机可以执行抢占:
(1)preempt_enable
(2)异常上下文返回到用户空间
(3)异常上下文返回到内核空间 - 如果内核禁用抢占,如下时机可以执行抢占:
(1)显式调用schedule()函数(mutex也属于此情况)
(2)异常返回用户空间
asmlinkage __visible void __sched schedule(void)
|--struct task_struct *tsk = current;
|--sched_submit_work(tsk);//进程的plug队列泄洪操作
|--do {
| preempt_disable();//关闭内核抢占
| __schedule(false); //调度核心实现
| sched_preempt_enable_no_resched();//打开内核抢占
| } while (need_resched());//判断当前进程的TIF_NEED_RESCHED是否置位
\--sched_update_worker(tsk);
static void __sched notrace __schedule(bool preempt)
|--cpu = smp_processor_id();
| rq = cpu_rq(cpu);
| prev = rq->curr;//prev指向当前进程
|--schedule_debug(prev, preempt)//判断当前进程是否处于原子上下文
|--if (!preempt && prev->state)//发生了非抢占调度,如主动调用schedule
| deactivate_task(rq, prev, DEQUEUE_SLEEP | DEQUEUE_NOCLOCK);//当前进程移出就绪队列
|--next = pick_next_task(rq, prev, &rf);//选择下个合适的进程开始运行
|--clear_tsk_need_resched(prev);//清除进程的TIF_NEED_RESCHED
| clear_preempt_need

本文详细介绍了Linux内核中的进程调度器__schedule函数,包括抢占时机、调度流程、上下文切换等关键步骤。重点讨论了__schedule函数内部如何选择下一个进程、上下文切换的实现以及deactivate_task的处理。通过对源码的分析,揭示了内核抢占和进程切换的机制。
最低0.47元/天 解锁文章
7186

被折叠的 条评论
为什么被折叠?



