cfs_req 什么时候创建的
时间: 2024-04-06 21:30:25 浏览: 16
CFS 运行队列(cfs_rq)是在进程(task)被创建时动态创建的。具体来说,当进程被创建时,Linux 内核会分配一个调度实体(sched_entity)结构体来表示该进程的调度状态和属性,然后将其插入到相应的 CFS 运行队列中。如果该进程是第一次被创建,Linux 会为该进程所在的 CPU 核心(或 NUMA 节点)创建一个新的 CFS 运行队列,并将该进程的调度实体插入到该队列中。如果该进程所在的 CPU 核心(或 NUMA 节点)已经有了对应的 CFS 运行队列,Linux 就会将该进程的调度实体插入到对应的队列中,然后根据 CFS 调度算法来进行调度。
需要注意的是,CFS 运行队列是动态创建和销毁的,当某个 CPU 核心(或 NUMA 节点)上没有可运行的进程时,对应的 CFS 运行队列就会被销毁,以释放内存和其他资源。
相关问题
每个核心上的cfs_req 只有一个吗
不完全正确。在 Linux CFS 中,每个 CPU 核心(或 SMT 线程)都会有一个 CFS 运行队列,但是对于多个核心之间共享一个运行队列的情况也是存在的。具体来说,当系统中存在一些可运行的进程或线程个数较少时,Linux CFS 会将它们放置在一个全局运行队列中,所有的核心都会从该队列中获取可运行的进程或线程来执行。这种情况下每个核心上的 cfs_rq 就不是唯一的了,而是共享同一个全局运行队列。当系统中存在大量的可运行进程或线程时,为了避免竞争和干扰,Linux CFS 会为每个 CPU 核心都创建一个专属的 CFS 运行队列,来维护本地的可运行进程或线程。
cfs_rq 创建的源码
CFS 运行队列的创建主要是在 Linux 内核的调度器代码中实现的。下面是 CFS 运行队列的创建源码示例:
```c
static inline void
enqueue_task_cfs_rq(struct sched_entity *se, bool head)
{
struct cfs_rq *cfs_rq;
cfs_rq = task_cfs_rq(se->task);
update_curr(cfs_rq);
__enqueue_entity(cfs_rq, se, head);
}
```
上述代码实现了将一个调度实体(sched_entity)插入到相应 CFS 运行队列(cfs_rq)的操作,其中 `task_cfs_rq` 函数用于获取该调度实体所在的 CFS 运行队列。在将调度实体插入到队列时,会调用 `__enqueue_entity` 函数进行实际的操作。同时,还会调用 `update_curr` 函数更新队列中每个调度实体的当前 CPU 时间片(vruntime)和动态权重(load.weight),以便后续的调度决策。