# 2.6.3.2 组调度 - 调度逻辑

其实从总体思路上讲，引入任务组并不会对CFS的调度模型产生根本性的改变，只是在时间分配与任务挑选时增加了递归层级：如果目标se代表一个任务组，则需要下层到该任务组的cfsrq中去，把对应的操作再做一遍；如此循环直到最终拿到一个代表任务的se为止。

我们先来看CFS 在挑选下一个任务时如何处理任务组的：

```
/* file: kernel/sched/fair.c */
struct task_struct *pick_next_task_fair(struct rq *rq, struct task_struct *prev,
                                struct rq_flags *rf) {
struct cfs_rq *cfs_rq = &rq->cfs;
struct sched_entity *se;
struct task_struct *p;

do {
se = pick_next_entity(cfs_rq, NULL);
set_next_entity(cfs_rq, se);
cfs_rq = group_cfs_rq(se);
} while (cfs_rq);

p = task_of(se);
}

#ifdef CONFIG_FAIR_GROUP_SCHED
static inline struct cfs_rq *group_cfs_rq(struct sched_entity *grp) {
return grp->my_q;
}
#endif
```

这里仅留下了挑选下一个se的逻辑，对任务组的处理通过一个while循环搞定：如果没有开启组调度，则函数 `group_cfs_rq` 返回NULL, 只会遍历一次；如果开启了组调度，则会返回se指向的cfsrq继续遍历，直到找到最终代表一个具体任务的se为止。
