內核調度【六】【數據結構】【二】

1、struct cfs_rq

在rq中與cfs相關的字段

/* CFS-related fields in a runqueue */
struct cfs_rq {
/*
該cfs_rq的load,它只計算它本層下面的se的weight之和,並不是這個se的load,也不是遞歸到葉子節點上的所有se weight之和(理解這點非常重要)*/
	struct load_weight load;/*所有進程的累計負荷值*/
//h_nr_running只對於組纔有效,包括底層所有cfs_rq的nr_running之和
	unsigned int nr_running, h_nr_running;nr_running/*當前就緒隊列的進程數*/

	u64 exec_clock;//該cfs_rq總共佔用的cpu時間(物理),只累計本層
/*
     * 當前CFS隊列上最小運行時間,單調遞增
     * 兩種情況下更新該值: 
     * 1、更新當前運行任務的累計運行時間時
     * 2、當任務從隊列刪除去,如任務睡眠或退出,這時候會查看剩下的任務的vruntime是否大於min_vruntime,如果是則更新該值。
     */
//用於調整se的vruntime,它是遞增的,但不一定是該cfs_rq裏所有se最小
	u64 min_vruntime; //該cpu運行隊列的vruntime推進值, 一般是紅黑樹中最小的vruntime值
#ifndef CONFIG_64BIT
	u64 min_vruntime_copy;
#endif

	struct rb_root tasks_timeline;/*紅黑樹的頭結點*/
	struct rb_node *rb_leftmost;/*紅黑樹的最左面節點*/

	/*
	 * 'curr' points to currently running entity on this cfs_rq.
	 * It is set to NULL otherwise (i.e when none are currently running).
	 */
// current是正在被調用的實體對象
//當前運行的se(對於組雖然它不會在cpu上運行,但是當它的下層有一個task在cpu上運行,那麼它所在的cfs_rq就把它當做是該cfs_rq上當前正在運行的se)
	struct sched_entity *curr, *next, *last, *skip;
/*
     * 'curr' points to currently running entity on this cfs_rq.
     * It is set to NULL otherwise (i.e when none are currently running).
     * curr: 當前正在運行的sched_entity(對於組雖然它不會在cpu上運行,但是當它的下層有一個task在cpu上運行,那麼它所在的cfs_rq就把它當做是該cfs_rq上當前正在運行的sched_entity)
     * next: 表示有些進程急需運行,即使不遵從CFS調度也必須運行它,調度時會檢查是否next需要調度,有就調度next
     *
     * skip: 略過進程(不會選擇skip指定的進程調度)
     */

#ifdef	CONFIG_SCHED_DEBUG
	unsigned int nr_spread_over;
#endif

#ifdef CONFIG_SMP
	/*
	 * CFS load tracking
	 */
	struct sched_avg avg;
	u64 runnable_load_sum;
	unsigned long runnable_load_avg;
#ifdef CONFIG_64BIT_ONLY_CPU
	unsigned long runnable_load_avg_32bit;
#endif
#ifdef CONFIG_FAIR_GROUP_SCHED
	unsigned long tg_load_avg_contrib;
	unsigned long propagate_avg;
#endif
	atomic_long_t removed_load_avg, removed_util_avg;
#ifndef CONFIG_64BIT
	u64 load_last_update_time_copy;
#endif

#ifdef CONFIG_FAIR_GROUP_SCHED
	/*
	 *   h_load = weight * f(tg)
	 *
	 * Where f(tg) is the recursive weight fraction assigned to
	 * this group.
	 */
	unsigned long h_load;
	u64 last_h_load_update;
	struct sched_entity *h_load_next;
#endif /* CONFIG_FAIR_GROUP_SCHED */
#endif /* CONFIG_SMP */

#ifdef CONFIG_FAIR_GROUP_SCHED
    /* 所屬於的CPU rq */
	struct rq *rq;	/* cpu runqueue to which this cfs_rq is attached */

	/*
	 * leaf cfs_rqs are those that hold tasks (lowest schedulable entity in
	 * a hierarchy). Non-leaf lrqs hold other higher schedulable entities
	 * (like users, containers etc.)
	 *
	 * leaf_cfs_rq_list ties together list of leaf cfs_rq's in a cpu. This
	 * list is used during load balance.
	 */
	int on_list;
	struct list_head leaf_cfs_rq_list;
/*屬於這個cfs_rq的進程組*/ 
	struct task_group *tg;	/* group that "owns" this runqueue */

#ifdef CONFIG_SCHED_WALT
	u64 cumulative_runnable_avg;
#endif

#ifdef CONFIG_CFS_BANDWIDTH
	int runtime_enabled;
	u64 runtime_expires;
	s64 runtime_remaining;

	u64 throttled_clock, throttled_clock_task;
	u64 throttled_clock_task_time;
	int throttled, throttle_count, throttle_uptodate;
	struct list_head throttled_list;
#endif /* CONFIG_CFS_BANDWIDTH */
#endif /* CONFIG_FAIR_GROUP_SCHED */
};

2、task_struct

每個task對應一個se,但是反過去不一定成立,因爲有task_group的概念

struct task_struct
{
    ........
    /* 表示是否在運行隊列 */
    int on_rq;

    /* 進程優先級 
     * prio: 動態優先級,範圍爲100~139,與靜態優先級和補償(bonus)有關
     * static_prio: 靜態優先級,static_prio = 100 + nice + 20 (nice值爲-20~19,所以static_prio值爲100~139)
     * normal_prio: 沒有受優先級繼承影響的常規優先級,具體見normal_prio函數,跟屬於什麼類型的進程有關
     */
    int prio, static_prio, normal_prio;
    /* 實時進程優先級 */
    unsigned int rt_priority;

    /* 調度類,調度處理函數類 */
    const struct sched_class *sched_class;

    /* 調度實體(紅黑樹的一個結點) */
    struct sched_entity se; //通過這個調度實體可以找到對應的task
    /* 調度實體(實時調度使用) */
    struct sched_rt_entity rt;
    struct sched_dl_entity dl;

#ifdef CONFIG_CGROUP_SCHED
    /* 指向其所在進程組 */
    struct task_group *sched_task_group;
#endif
    ........
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章