美文网首页Linux知识点汇集
进程调度之就绪队列

进程调度之就绪队列

作者: vincent_0425 | 来源:发表于2019-03-13 22:22 被阅读0次

    核心调度器管理活动进程的主要数据结构是就绪队列rq, 每个cpu都有自己的就绪队列,而每个活动进程某一时刻只会在一个就绪队列中。
    对于调度器而言,由于支持多种调度算法,所以各种调度算法的就绪队列会嵌入到就绪队列的子队列中。
    就绪队列具体定义见rq定义

    成员名 类型 说明 备注
    raw_spinlock_t lock;
    

    访问就绪队列所使用的锁 , 可以使用函数raw_spin_lock_irq()获取锁后关闭中断,或者使用函数 raw_spin_unlock_irq()释放锁并开启中断

    unsigned int nr_running ;
    

    当前就绪队列可投入运行的调度实体个数,如进程、线程等调度实体,但当前正在运行 的调度实体不计入 nr_running 中,因为它已经从就绪队列中脱离. 函数nr_running()获取所有,同时文件文件 proc/loadavg也可了解相关信息

    #define CPU_LOAD_IDX_MAX 5
    unsigned long cpu_load[CPU_LOAD_IDX_MAX];
    

    用于跟踪 CPU 负载|大小为CPU_LOAD_IDX_MAX,值为5,也可通过文件proc/sched_debug了解负载信息.

    unsigned long last_load_update_tick;
    

    更新负载时的时间|在 cpu_load 得到更新时此成员记录了当前工作时间(jiffies 值)。

    unsigned long nohz_flags;
    

    用于在动态时钟模式开启时,记录当前时钟模式|不同模式切换会影响系统进 入不同的系统状态,通过先前系统状态和当前环境,系统决定进入不同的系统环境。

    unsigned long last_sched_tick;
    

    配置 CONFIG_NO_HZ_FULL 时,即动态时钟启用时,记录上一次调度 tick|动态时钟 管理中,调度并不周期性运行,因此需要成员记录调度时间。

    struct load_weight load;
    
    struct load_weight {  
        unsigned long weight; 
        u32 inv_weight;
    }
    

    用于跟踪就绪队列的负载,它是由 Local CPU 上所有可运行的调度实体共同作用的结果。成员 weight 用于记录具体权重,而 inv_weight 则用于优先级到权重的乘数因子. 一般来说,在每次 tick 中断到来时,系统更新就绪队列负载

    unsigned long nr_load_updates;
    

    当 rq->cpu_load[]成员更新时,该成员记录更新的次数。在函数 cpu_load_update ()中 更新此值,此函数由 cpu_load_update_periodic()调用,或者在配置 CONFIG_NO_HZ_COMMON 下由函数 cpu_load_update_nohz ()调用

    u64 nr_switches;
    

    用于跟踪就绪队列中进程上下文切换的次数。
    想了解某个具体进程的切换次数和调度信息则可以通过/proc/PID/schedstat 和/proc/PID/sched 两个文件了解详细信息|

    struct cfs_rq cfs;
    struct rt_rq rt;
    struct dl_rq dl;
    

    分别对应:
    CFS调度算法就绪队列
    RT调度算法就绪队列
    DL调度算法就绪队列

    struct list_head leaf_cfs_rq_list;
    

    如果需要 CFS 支持组调度管理,那就 得把所有 CFS 加入到一个链表当中,leaf_cfs_rq_list 成员就是负责把本 CPU 下的就绪队列 中各个 CFS 子队列关联起来。并且在 cfs_rq 里面有成员 on_list,其表示当前的 CFS 队列 leaf_cfs_rq_list 成员是否加入到就绪队列 rq 的 leaf_cfs_rq_list 管理的链表当中。

    unsigned long nr_uninterruptible;
    

    用于跟踪当前系统中队列里面不可信号中断的调度实体个数

     struct task_struct *curr, *idle, *stop
    

    分别用于描述当前正在运行的任务,空闲任务,刚刚停止运行的任务;

    unsigned long next_balance
    

    用于指示就绪队列进行下一次负载平衡的时间,该成员在初始化时被设置为当前系 统 jiffies。

     struct mm_struct *prev_mm
    

    就绪队列中用于保存先前执行任务使用的内存描述符 mm_struct 结构。此成员在发生调度时由内核函数 context_switch()来更新。

    u64 clock;
    

    描述的是队列的时间,一般在每个 tick 中 断到来时更新,其由上面提到的函数 update_rq_clock()对此成员更新。

    u64 clock_task
    

    clock_task 记录的是 队列中任务执行的时间,其由函数 update_rq_clock_task()负责更新。

     atomic_t nr_iowait
    

    描述当前就绪队列里面正在进行 IO 等待的进程个数,此成员一般和进程描述符 task_struct 中的 in_iowait 成员配合使用。
    可以通过 proc/stat 下的 procs_blocked 值了解 nr_iowait 的大小

    以上是rq基本成员,下面是SMP相关的成员:

    struct llist_head wake_list;
    

    描述了当前队列中需要唤醒的任务链表.
    这个成员在 SMP 下非常重要,其是负载均衡时任务迁移中间状态链表.
    对于那些需要迁移的任务来说,其会由本 CPU 下的就绪队列脱离出去,暂时的存 放到目标 CPU 下的就绪队列的 wake_list 链表当中。

    struct root_domain *rd;
    

    指示了当前 rq 运行队列可以工作的 CPU,即描述了可以为此就绪队列服务的 CPU。

    struct sched_domain *sd
    

    用于描述 rq 就绪队列所处的调度域。

    unsigned long cpu_capacity
    unsigned long cpu_capacity_orig
    

    两个成员都是用于 rq 就绪队列的 CPU 能力描述。在系统初始化时,两者都被设置为 SCHED_CAPACITY_SCALE 值,当前版本中值大小为 1024。cpu_capacity 是运行过程中使用 的能力,而 cpu_capacity_orig 则是保存最原始的能力。可以使用函数 capacity_of()或者 capacity_orig_of()获取 rq 就绪队列的 CPU 能力值。用户可以调用函数 update_cpu_capacity()更新此能力。

    struct callback_head *balance_callback;
    

    在调度(_schedule())函数末尾处的回调链表,每个回调函数只会执行一次。
    目前仅在RT/DL调度中使用。

     int active_balance
    

    用于指示是否需要开启负载均衡操作,在函数 load_balance()对其设置。在负载均衡操作中,如果此值被设置,则内核把任务迁移到空闲 CPU 上运行。

     int push_cpu
    

    用于指示可 push 任务所在的 CPU。在负载均衡操作中,对可 push 的 CPU 选取操 作是一个非常繁琐的计算过程,一般会选择空闲的 CPU 处理迁移的任务。

    int cpu
    

    多核环境中用于指示当前 rq 就绪队列所在的 CPU。

     int online
    

    rq 就绪队列是否处于工作状态,函数 set_rq_online()对其设置为 1,即表示为工作状态, 而函数 set_rq_offline()对其设置为 0,表示处于非工作状态。

     struct list_head cfs_tasks
    

    用于从就绪队列 rq 角度跟踪 CFS 就绪队列中的调度实体

    u64 idle_stamp
    

    用于记录负载平衡耗费的时间,这个时间是可以记录到空闲时间中去的。

    u64 avg_idle
    

    用于记录 CPU 空闲时间,此成员会与上面的 idle_stamp 配合使用。

    u64 max_idle_balance_cost
    

    此值与上面 avg_idle 作用类似,其用于跟踪 CPU 空闲的最大时间。

    相关文章

      网友评论

        本文标题:进程调度之就绪队列

        本文链接:https://www.haomeiwen.com/subject/ummxmqtx.html