From e6f778bc78c58f8fa979e53b51c42e165aad4541 Mon Sep 17 00:00:00 2001 From: gatieme Date: Sun, 26 Jun 2016 19:20:18 +0800 Subject: [PATCH] =?UTF-8?q?=E8=BF=9B=E7=A8=8B=E8=B0=83=E5=BA=A6=E4=B9=8B?= =?UTF-8?q?=E8=BF=9B=E7=A8=8B=E4=B8=8A=E4=B8=8B=E6=96=87=E5=88=87=E6=8D=A2?= =?UTF-8?q?=E8=AF=A6=E8=A7=A3...?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../03-design/{ => 01-design}/README.md | 0 .../{ => 01-design}/images/schedler.jpg | Bin .../02-periodic_scheduler}/README.md | 0 .../03-main_scheduler}/README.md | 0 .../03-main_scheduler}/__schedule.c | 0 .../03-main_scheduler}/context_switch.c | 0 .../03-main_scheduler}/pick_next_task.c | 0 .../03-main_scheduler}/schedule.c | 0 .../04-preempt}/README.md | 0 .../images/NonPreemptiveKernel.png | Bin .../04-preempt}/images/PreemptiveKernel.png | Bin .../05-context_switch}/README.md | 4 + .../05-context_switch}/context_switch.c | 0 .../05-context_switch}/finish_task_switch.c | 0 .../05-context_switch}/prepare_task_switch.c | 0 .../05-context_switch}/switch_mm.c | 0 .../05-context_switch}/switch_to.c | 0 .../06-priority}/README.md | 0 .../05-schedule/04-cfs/01-cfs/README.md | 136 ++++++++++++++++++ .../05-schedule/04-cfs/01-cfs/fail.c | 43 ++++++ .../01-load_weight}/README.md | 0 study/kernel/01-process/05-schedule/README.md | 1 + 22 files changed, 184 insertions(+) rename study/kernel/01-process/05-schedule/03-design/{ => 01-design}/README.md (100%) rename study/kernel/01-process/05-schedule/03-design/{ => 01-design}/images/schedler.jpg (100%) rename study/kernel/01-process/05-schedule/{04-periodic_scheduler => 03-design/02-periodic_scheduler}/README.md (100%) rename study/kernel/01-process/05-schedule/{05-main_scheduler => 03-design/03-main_scheduler}/README.md (100%) rename study/kernel/01-process/05-schedule/{05-main_scheduler => 03-design/03-main_scheduler}/__schedule.c (100%) rename study/kernel/01-process/05-schedule/{05-main_scheduler => 03-design/03-main_scheduler}/context_switch.c (100%) rename study/kernel/01-process/05-schedule/{05-main_scheduler => 03-design/03-main_scheduler}/pick_next_task.c (100%) rename study/kernel/01-process/05-schedule/{05-main_scheduler => 03-design/03-main_scheduler}/schedule.c (100%) rename study/kernel/01-process/05-schedule/{06-preempt => 03-design/04-preempt}/README.md (100%) rename study/kernel/01-process/05-schedule/{06-preempt => 03-design/04-preempt}/images/NonPreemptiveKernel.png (100%) rename study/kernel/01-process/05-schedule/{06-preempt => 03-design/04-preempt}/images/PreemptiveKernel.png (100%) rename study/kernel/01-process/05-schedule/{07-context_switch => 03-design/05-context_switch}/README.md (98%) rename study/kernel/01-process/05-schedule/{07-context_switch => 03-design/05-context_switch}/context_switch.c (100%) rename study/kernel/01-process/05-schedule/{07-context_switch => 03-design/05-context_switch}/finish_task_switch.c (100%) rename study/kernel/01-process/05-schedule/{07-context_switch => 03-design/05-context_switch}/prepare_task_switch.c (100%) rename study/kernel/01-process/05-schedule/{07-context_switch => 03-design/05-context_switch}/switch_mm.c (100%) rename study/kernel/01-process/05-schedule/{07-context_switch => 03-design/05-context_switch}/switch_to.c (100%) rename study/kernel/01-process/05-schedule/{08-priority => 03-design/06-priority}/README.md (100%) create mode 100644 study/kernel/01-process/05-schedule/04-cfs/01-cfs/README.md create mode 100644 study/kernel/01-process/05-schedule/04-cfs/01-cfs/fail.c rename study/kernel/01-process/05-schedule/{09-load_weight => 04-cfs/01-load_weight}/README.md (100%) diff --git a/study/kernel/01-process/05-schedule/03-design/README.md b/study/kernel/01-process/05-schedule/03-design/01-design/README.md similarity index 100% rename from study/kernel/01-process/05-schedule/03-design/README.md rename to study/kernel/01-process/05-schedule/03-design/01-design/README.md diff --git a/study/kernel/01-process/05-schedule/03-design/images/schedler.jpg b/study/kernel/01-process/05-schedule/03-design/01-design/images/schedler.jpg similarity index 100% rename from study/kernel/01-process/05-schedule/03-design/images/schedler.jpg rename to study/kernel/01-process/05-schedule/03-design/01-design/images/schedler.jpg diff --git a/study/kernel/01-process/05-schedule/04-periodic_scheduler/README.md b/study/kernel/01-process/05-schedule/03-design/02-periodic_scheduler/README.md similarity index 100% rename from study/kernel/01-process/05-schedule/04-periodic_scheduler/README.md rename to study/kernel/01-process/05-schedule/03-design/02-periodic_scheduler/README.md diff --git a/study/kernel/01-process/05-schedule/05-main_scheduler/README.md b/study/kernel/01-process/05-schedule/03-design/03-main_scheduler/README.md similarity index 100% rename from study/kernel/01-process/05-schedule/05-main_scheduler/README.md rename to study/kernel/01-process/05-schedule/03-design/03-main_scheduler/README.md diff --git a/study/kernel/01-process/05-schedule/05-main_scheduler/__schedule.c b/study/kernel/01-process/05-schedule/03-design/03-main_scheduler/__schedule.c similarity index 100% rename from study/kernel/01-process/05-schedule/05-main_scheduler/__schedule.c rename to study/kernel/01-process/05-schedule/03-design/03-main_scheduler/__schedule.c diff --git a/study/kernel/01-process/05-schedule/05-main_scheduler/context_switch.c b/study/kernel/01-process/05-schedule/03-design/03-main_scheduler/context_switch.c similarity index 100% rename from study/kernel/01-process/05-schedule/05-main_scheduler/context_switch.c rename to study/kernel/01-process/05-schedule/03-design/03-main_scheduler/context_switch.c diff --git a/study/kernel/01-process/05-schedule/05-main_scheduler/pick_next_task.c b/study/kernel/01-process/05-schedule/03-design/03-main_scheduler/pick_next_task.c similarity index 100% rename from study/kernel/01-process/05-schedule/05-main_scheduler/pick_next_task.c rename to study/kernel/01-process/05-schedule/03-design/03-main_scheduler/pick_next_task.c diff --git a/study/kernel/01-process/05-schedule/05-main_scheduler/schedule.c b/study/kernel/01-process/05-schedule/03-design/03-main_scheduler/schedule.c similarity index 100% rename from study/kernel/01-process/05-schedule/05-main_scheduler/schedule.c rename to study/kernel/01-process/05-schedule/03-design/03-main_scheduler/schedule.c diff --git a/study/kernel/01-process/05-schedule/06-preempt/README.md b/study/kernel/01-process/05-schedule/03-design/04-preempt/README.md similarity index 100% rename from study/kernel/01-process/05-schedule/06-preempt/README.md rename to study/kernel/01-process/05-schedule/03-design/04-preempt/README.md diff --git a/study/kernel/01-process/05-schedule/06-preempt/images/NonPreemptiveKernel.png b/study/kernel/01-process/05-schedule/03-design/04-preempt/images/NonPreemptiveKernel.png similarity index 100% rename from study/kernel/01-process/05-schedule/06-preempt/images/NonPreemptiveKernel.png rename to study/kernel/01-process/05-schedule/03-design/04-preempt/images/NonPreemptiveKernel.png diff --git a/study/kernel/01-process/05-schedule/06-preempt/images/PreemptiveKernel.png b/study/kernel/01-process/05-schedule/03-design/04-preempt/images/PreemptiveKernel.png similarity index 100% rename from study/kernel/01-process/05-schedule/06-preempt/images/PreemptiveKernel.png rename to study/kernel/01-process/05-schedule/03-design/04-preempt/images/PreemptiveKernel.png diff --git a/study/kernel/01-process/05-schedule/07-context_switch/README.md b/study/kernel/01-process/05-schedule/03-design/05-context_switch/README.md similarity index 98% rename from study/kernel/01-process/05-schedule/07-context_switch/README.md rename to study/kernel/01-process/05-schedule/03-design/05-context_switch/README.md index 8167d72..c408f3e 100644 --- a/study/kernel/01-process/05-schedule/07-context_switch/README.md +++ b/study/kernel/01-process/05-schedule/03-design/05-context_switch/README.md @@ -868,3 +868,7 @@ static struct rq *finish_task_switch(struct task_struct *prev) ``` +#4 linux下进程切换性能分析 +------- + + diff --git a/study/kernel/01-process/05-schedule/07-context_switch/context_switch.c b/study/kernel/01-process/05-schedule/03-design/05-context_switch/context_switch.c similarity index 100% rename from study/kernel/01-process/05-schedule/07-context_switch/context_switch.c rename to study/kernel/01-process/05-schedule/03-design/05-context_switch/context_switch.c diff --git a/study/kernel/01-process/05-schedule/07-context_switch/finish_task_switch.c b/study/kernel/01-process/05-schedule/03-design/05-context_switch/finish_task_switch.c similarity index 100% rename from study/kernel/01-process/05-schedule/07-context_switch/finish_task_switch.c rename to study/kernel/01-process/05-schedule/03-design/05-context_switch/finish_task_switch.c diff --git a/study/kernel/01-process/05-schedule/07-context_switch/prepare_task_switch.c b/study/kernel/01-process/05-schedule/03-design/05-context_switch/prepare_task_switch.c similarity index 100% rename from study/kernel/01-process/05-schedule/07-context_switch/prepare_task_switch.c rename to study/kernel/01-process/05-schedule/03-design/05-context_switch/prepare_task_switch.c diff --git a/study/kernel/01-process/05-schedule/07-context_switch/switch_mm.c b/study/kernel/01-process/05-schedule/03-design/05-context_switch/switch_mm.c similarity index 100% rename from study/kernel/01-process/05-schedule/07-context_switch/switch_mm.c rename to study/kernel/01-process/05-schedule/03-design/05-context_switch/switch_mm.c diff --git a/study/kernel/01-process/05-schedule/07-context_switch/switch_to.c b/study/kernel/01-process/05-schedule/03-design/05-context_switch/switch_to.c similarity index 100% rename from study/kernel/01-process/05-schedule/07-context_switch/switch_to.c rename to study/kernel/01-process/05-schedule/03-design/05-context_switch/switch_to.c diff --git a/study/kernel/01-process/05-schedule/08-priority/README.md b/study/kernel/01-process/05-schedule/03-design/06-priority/README.md similarity index 100% rename from study/kernel/01-process/05-schedule/08-priority/README.md rename to study/kernel/01-process/05-schedule/03-design/06-priority/README.md diff --git a/study/kernel/01-process/05-schedule/04-cfs/01-cfs/README.md b/study/kernel/01-process/05-schedule/04-cfs/01-cfs/README.md new file mode 100644 index 0000000..db47abb --- /dev/null +++ b/study/kernel/01-process/05-schedule/04-cfs/01-cfs/README.md @@ -0,0 +1,136 @@ +Linux进程调度器的设计 +======= + + +| 日期 | 内核版本 | 架构| 作者 | GitHub| CSDN | +| ------- |:-------:|:-------:|:-------:|:-------:|:-------:| +| 2016-06-14 | [Linux-4.6](http://lxr.free-electrons.com/source/?v=4.6) | X86 & arm | [gatieme](http://blog.csdn.net/gatieme) | [LinuxDeviceDrivers](https://github.com/gatieme/LDD-LinuxDeviceDrivers) | [Linux进程管理与调度](http://blog.csdn.net/gatieme/article/category/6225543) | + + +#前景回顾 +------- + + +##进程调度 +------- + +linux把进程区分为实时进程和非实时进程, 其中非实时进程进一步划分为交互式进程和批处理进程 + + + +根据进程的不同分类Linux采用不同的调度策略. + +对于实时进程,采用FIFO或者Round Robin的调度策略. + +对于普通进程,则采用CFS完全功能公平调度器 + +##linux调度器的演变 +------- + +一开始的调度器是复杂度为**$O(n)$的始调度算法**(实际上每次会遍历所有任务,所以复杂度为O(n)), 这个算法的缺点是当内核中有很多任务时,调度器本身就会耗费不少时间,所以,从linux2.5开始引入赫赫有名的**$O(1)$调度器** + + + +| 字段 | 版本 | +| ------------- |:-------------:| +| O(n)的始调度算法 | linux-0.11~2.4 | +| O(1)调度器 | linux-2.5 | +| CFS调度器 | linux-2.6~至今 | + + +#Linux的调度器组成 +------- + + +##2个调度器 +------- + +可以用两种方法来激活调度 + +* 一种是直接的, 比如进程打算睡眠或出于其他原因放弃CPU + +* 另一种是通过周期性的机制, 以固定的频率运行, 不时的检测是否有必要 + +因此当前linux的调度程序由两个调度器组成:**主调度器**,**周期性调度器**(两者又统称为**通用调度器(generic scheduler)**或**核心调度器(core scheduler)**) + +并且每个调度器包括两个内容:**调度框架**(其实质就是两个函数框架)及**调度器类** + + + +##6种调度策略 +------- + + +linux内核目前实现了6中调度策略(即调度算法), 用于对不同类型的进程进行调度, 或者支持某些特殊的功能 + +比如SCHED_NORMAL和SCHED_BATCH调度普通的非实时进程, SCHED_FIFO和SCHED_RR和SCHED_DEADLINE则采用不同的调度策略调度实时进程, SCHED_IDLE则在系统空闲时调用idle进程. + + + + +##5个调度器类 +------- + +而依据其调度策略的不同实现了5个调度器类, 一个调度器类可以用一种种或者多种调度策略调度某一类进程, 也可以用于特殊情况或者调度特殊功能的进程. + + + +其所属进程的优先级顺序为 +````c +stop_sched_class -> dl_sched_class -> rt_sched_class -> fair_sched_class -> idle_sched_class +``` + +##3个调度实体 +------- + +调度器不限于调度进程, 还可以调度更大的实体, 比如实现组调度: 可用的CPUI时间首先在一半的进程组(比如, 所有进程按照所有者分组)之间分配, 接下来分配的时间再在组内进行二次分配. + +这种一般性要求调度器不直接操作进程, 而是处理可调度实体, 因此需要一个通用的数据结构描述这个调度实体,即seched_entity结构, 其实际上就代表了一个调度对象,可以为一个进程,也可以为一个进程组. + +linux中针对当前可调度的实时和非实时进程, 定义了类型为seched_entity的3个调度实体 + + +* sched_dl_entity 采用EDF算法调度的DEADLINE实时调度实体 + +* sched_rt_entity 采用Roound-Robin或者FIFO算法调度的实时调度实体 + +* sched_entity 采用CFS算法调度的普通非实时进程的调度实体 + + +每个进程都属于某个调度器类(由字段task_struct->sched_class标识), 由调度器类采用进程对应的调度策略调度(由task_struct->policy )进行调度, task_struct也存储了其对应的调度实体标识 + +linux实现了6种调度策略, 依据其调度策略的不同实现了5个调度器类, 一个调度器类可以用一种或者多种调度策略调度某一类进程, 也可以用于特殊情况或者调度特殊功能的进程. + + +调度器类, 调度策略, 调度实体他们之间的关系如下表 + +| 调度器类 | 调度策略 | 调度策略对应的调度算法 | 调度实体 | 调度实体对应的调度对象 | +| ------- |:-------:|:-------:|:-------:||:-------:| +| stop_sched_class | 无 | 无 | 无 | 特殊情况, 发生在cpu_stop_cpu_callback 进行cpu之间任务迁移migration或者HOTPLUG_CPU的情况下关闭任务 | +| dl_sched_class | SCHED_DEADLINE | Earliest-Deadline-First最早截至时间有限算法 | sched_dl_entity | 采用DEF最早截至时间有限算法调度实时进程 | +| rt_sched_class | SCHED_RR

SCHED_FIFO | Roound-Robin时间片轮转算法

FIFO先进先出算法 | sched_rt_entity | 采用Roound-Robin或者FIFO算法调度的实时调度实体 | +| fair_sched_class | SCHED_NORMAL

SCHED_BATCH | CFS完全公平懂调度算法 |sched_entity | 采用CFS算法普通非实时进程 | +| idle_sched_class | SCHED_IDLE | 无 | 无 | 特殊进程, 用于cpu空闲时调度空闲进程idle | + +#cfs完全公平调度器 +------- + +##CFS调度器类fair_sched_class +------- + +CFS完全公平调度器的调度器类叫fair_sched_class, 其定义在[kernel/sched/fair.c, line 8521](http://lxr.free-electrons.com/source/kernel/sched/fair.c#L8521), 它是我们熟知的是struct sched_class调度器类类型, 将我们的CFS调度器与一些特定的函数关联起来 + + + +| sched_class字段 | fair_sched_class函数| 描述 | +| ------------- |:-------------:| +| load | 指定了权重, 决定了各个实体占队列总负荷的比重, 计算负荷权重是调度器的一项重任, 因为CFS所需的虚拟时钟的速度最终依赖于负荷, 权重通过优先级转换而成,是vruntime计算的关键 | +| run_node | 调度实体在红黑树对应的结点信息, 使得调度实体可以在红黑树上排序 | +| sum_exec_runtime | 记录程序运行所消耗的CPU时间, 以用于完全公平调度器CFS | +| on_rq | 调度实体是否在就绪队列上接受检查, 表明是否处于CFS红黑树运行队列中,需要明确一个观点就是,CFS运行队列里面包含有一个红黑树,但这个红黑树并不是CFS运行队列的全部,因为红黑树仅仅是用于选择出下一个调度程序的算法。很简单的一个例子,普通程序运行时,其并不在红黑树中,但是还是处于CFS运行队列中,其on_rq为真。只有准备退出、即将睡眠等待和转为实时进程的进程其CFS运行队列的on_rq为假 | +| vruntime | 虚拟运行时间,调度的关键,其计算公式:一次调度间隔的虚拟运行时间 = 实际运行时间 * (NICE_0_LOAD / 权重)。可以看出跟实际运行时间和权重有关,红黑树就是以此作为排序的标准,优先级越高的进程在运行时其vruntime增长的越慢,其可运行时间相对就长,而且也越有可能处于红黑树的最左结点,调度器每次都选择最左边的结点为下一个调度进程。注意其值为单调递增,在每个调度器的时钟中断时当前进程的虚拟运行时间都会累加。单纯的说就是进程们都在比谁的vruntime最小,最小的将被调度 | +| cfs_rq | 此调度实体所处于的CFS运行队列 | +| my_q | 如果此调度实体代表的是一个进程组,那么此调度实体就包含有一个自己的CFS运行队列,其CFS运行队列中存放的是此进程组中的进程,这些进程就不会在其他CFS运行队列的红黑树中被包含(包括顶层红黑树也不会包含他们,他们只属于这个进程组的红黑树) | + + + diff --git a/study/kernel/01-process/05-schedule/04-cfs/01-cfs/fail.c b/study/kernel/01-process/05-schedule/04-cfs/01-cfs/fail.c new file mode 100644 index 0000000..e890999 --- /dev/null +++ b/study/kernel/01-process/05-schedule/04-cfs/01-cfs/fail.c @@ -0,0 +1,43 @@ +8518 /* +8519 * All the scheduling class methods: +8520 */ +8521 const struct sched_class fair_sched_class = { +8522 .next = &idle_sched_class, +8523 .enqueue_task = enqueue_task_fair, +8524 .dequeue_task = dequeue_task_fair, +8525 .yield_task = yield_task_fair, +8526 .yield_to_task = yield_to_task_fair, +8527 +8528 .check_preempt_curr = check_preempt_wakeup, +8529 +8530 .pick_next_task = pick_next_task_fair, +8531 .put_prev_task = put_prev_task_fair, +8532 +8533 #ifdef CONFIG_SMP +8534 .select_task_rq = select_task_rq_fair, +8535 .migrate_task_rq = migrate_task_rq_fair, +8536 +8537 .rq_online = rq_online_fair, +8538 .rq_offline = rq_offline_fair, +8539 +8540 .task_waking = task_waking_fair, +8541 .task_dead = task_dead_fair, +8542 .set_cpus_allowed = set_cpus_allowed_common, +8543 #endif +8544 +8545 .set_curr_task = set_curr_task_fair, +8546 .task_tick = task_tick_fair, +8547 .task_fork = task_fork_fair, +8548 +8549 .prio_changed = prio_changed_fair, +8550 .switched_from = switched_from_fair, +8551 .switched_to = switched_to_fair, +8552 +8553 .get_rr_interval = get_rr_interval_fair, +8554 +8555 .update_curr = update_curr_fair, +8556 +8557 #ifdef CONFIG_FAIR_GROUP_SCHED +8558 .task_move_group = task_move_group_fair, +8559 #endif +8560 }; \ No newline at end of file diff --git a/study/kernel/01-process/05-schedule/09-load_weight/README.md b/study/kernel/01-process/05-schedule/04-cfs/01-load_weight/README.md similarity index 100% rename from study/kernel/01-process/05-schedule/09-load_weight/README.md rename to study/kernel/01-process/05-schedule/04-cfs/01-load_weight/README.md diff --git a/study/kernel/01-process/05-schedule/README.md b/study/kernel/01-process/05-schedule/README.md index 171c951..e0c7ef1 100644 --- a/study/kernel/01-process/05-schedule/README.md +++ b/study/kernel/01-process/05-schedule/README.md @@ -14,6 +14,7 @@ Linux进程退出详解 6. 优先级priority 7. 抢占-内核抢占和用户抢占以及抢占的时机preempt 8. 进程切换context_switch + 9. 完全公平调度器cfs-设计 10. cfs-负荷权重 11. cfs-虚拟时钟