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-虚拟时钟