linux核心2.6.28調度相關的資料結構分析

來源:互聯網
上載者:User

 

struct task_struct {

//進程的當前運行狀態

 volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */
  unsigned int flags; /* per process flags, defined below */
//動態優先順序,靜態優先順序和常規優先順序

 int prio, static_prio, normal_prio;

//即時優先順序
 unsigned int rt_priority;
 const struct sched_class *sched_class;/*調度類指標,一堆指向函數的指標*/

//CFS 調度實體
 struct sched_entity se;

//即時調度實體
 struct sched_rt_entity rt;

 unsigned int policy;/*進程的調度類型*/

struct list_head tasks;/*進程組織鏈表*/

/*環境切換次數*/
 unsigned long nvcsw, nivcsw; /* context switch counts */

}

 

2 sched_class,進程調度類:

 包括fair_sched_class,rt_sched_class和idle_sched_class,它們調用的順序是:

(1)rq->nr_running == rq->cfs.nr_running說明沒有即時進程,就去執行fair_sched_class的pick_next_task()

if (likely(rq->nr_running == rq->cfs.nr_running)) {
  p = fair_sched_class.pick_next_task(rq);
  if (likely(p))
   return p;
 }

 (2)

/*有即時進程,切換到即時調度類*/
 class = sched_class_highest;/*這裡就預設即時進程類了*/
 for ( ; ; ) {
  p = class->pick_next_task(rq);
  /*是什麼導致了rq->nr_running != rq->cfs.nr_running,
  但是rt_rq->rt_nr_running=0呢*/
  if (p)
   return p;
  /*
   * Will never be NULL as the idle class always
   * returns a non-NULL p:
   */
   /**/

(3)沒有即時進程就切換調度類
  class = class->next;/*這是指向了fair_sched_class*/

(4)在即時調度類裡面也沒有進程,即cfs_rq->nr_running = 0;就切換到idle_sched_class,它又調用pick_next_task_idle();選擇idle進程來運行。
 }

3 每CPU運行隊列rq

struct rq {
 /* runqueue lock: */
 spinlock_t lock;

 /*
  * nr_running and cpu_load should be in the same cacheline because
  * remote CPUs use both these fields when doing load calculation.
  */

//rq中進程的數目,是否是即時進程和完全公平進程的總數目,有待驗證????
 unsigned long nr_running;
 #define CPU_LOAD_IDX_MAX 5
 unsigned long cpu_load[CPU_LOAD_IDX_MAX];
 unsigned char idle_at_tick;
#ifdef CONFIG_NO_HZ
 unsigned long last_tick_seen;
 unsigned char in_nohz_recently;
#endif
 /* capture load from *all* tasks on this cpu: */
 struct load_weight load;
 unsigned long nr_load_updates;

//這個運行隊列的切換次數
 u64 nr_switches;

//注意這兩個資料結構,他們表明了rq 和cf_rq、rt_rq之間的關係,即實際的調度實體是在cf_rq、rt_rq上

//rq只是記錄了一些全域的資訊

 struct cfs_rq cfs;
 struct rt_rq rt;

#ifdef CONFIG_FAIR_GROUP_SCHED
 /* list of leaf cfs_rq on this cpu: */
 struct list_head leaf_cfs_rq_list;
#endif
#ifdef CONFIG_RT_GROUP_SCHED
 struct list_head leaf_rt_rq_list;
#endif

 /*
  * This is part of a global counter where only the total sum
  * over(統計) all CPUs matters. A task can increase this counter on
  * one CPU and if it got migrated afterwards it may decrease
  * it on another CPU. Always updated under the runqueue lock:
  */
 unsigned long nr_uninterruptible;

 struct task_struct *curr, *idle;
 unsigned long next_balance;
 struct mm_struct *prev_mm;

 u64 clock;

 atomic_t nr_iowait;

#ifdef CONFIG_SMP
 struct root_domain *rd;
 struct sched_domain *sd;

 /* For active balancing */
 int active_balance;
 int push_cpu;
 /* cpu of this runqueue: */
 int cpu;
 int online;

 unsigned long avg_load_per_task;

 struct task_struct *migration_thread;
 struct list_head migration_queue;
#endif

#ifdef CONFIG_SCHED_HRTICK
#ifdef CONFIG_SMP
 int hrtick_csd_pending;
 struct call_single_data hrtick_csd;
#endif
 struct hrtimer hrtick_timer;
#endif

#ifdef CONFIG_SCHEDSTATS
 /* latency stats */
 struct sched_info rq_sched_info;

 /* sys_sched_yield() stats */
 unsigned int yld_exp_empty;
 unsigned int yld_act_empty;
 unsigned int yld_both_empty;
 unsigned int yld_count;

 /* schedule() stats */
 unsigned int sched_switch;
 unsigned int sched_count;
 unsigned int sched_goidle;

 /* try_to_wake_up() stats */
 unsigned int ttwu_count;
 unsigned int ttwu_local;

 /* BKL stats */
 unsigned int bkl_count;
#endif
};

 

4 sched_entity 調度實體,它又分cfs調度實體和即時調度實體

(1)cfs調度實體

struct sched_entity {

//當前調度實體所佔的權重
 struct load_weight load;  /* for load-balancing *//*nice 對應的load值*/

//調度實體在紅/黑樹狀結構中的記錄資訊
 struct rb_node  run_node;

//當前調度實體屬於哪一個調度組
 struct list_head group_node;

//當前的調度實體是否在運行隊列上
 unsigned int  on_rq;

 u64   exec_start;/*上次開始調度時的已耗用時間*/
 u64   sum_exec_runtime;/*總的已耗用時間*/
 u64   vruntime;//當前調度實體的虛擬已耗用時間
 u64   prev_sum_exec_runtime;

 u64   last_wakeup;
 u64   avg_overlap;

#ifdef CONFIG_SCHEDSTATS
 u64   wait_start;
 u64   wait_max;
 u64   wait_count;
 u64   wait_sum;

 u64   sleep_start;
 u64   sleep_max;
 s64   sum_sleep_runtime;

 u64   block_start;
 u64   block_max;
 u64   exec_max;
 u64   slice_max;

 u64   nr_migrations;
 u64   nr_migrations_cold;
 u64   nr_failed_migrations_affine;
 u64   nr_failed_migrations_running;
 u64   nr_failed_migrations_hot;
 u64   nr_forced_migrations;
 u64   nr_forced2_migrations;

 u64   nr_wakeups;
 u64   nr_wakeups_sync;
 u64   nr_wakeups_migrate;
 u64   nr_wakeups_local;
 u64   nr_wakeups_remote;
 u64   nr_wakeups_affine;
 u64   nr_wakeups_affine_attempts;
 u64   nr_wakeups_passive;
 u64   nr_wakeups_idle;
#endif

#ifdef CONFIG_FAIR_GROUP_SCHED
 struct sched_entity *parent;
 /* rq on which this entity is (to be) queued: */
 struct cfs_rq  *cfs_rq;
 /* rq "owned" by this entity/group: */
 struct cfs_rq  *my_q;
#endif
};

(2)sched_rt_entity

struct sched_rt_entity {
 struct list_head run_list;

//到期時間
 unsigned long timeout;

//時間片
 unsigned int time_slice;

//cpu的數量
 int nr_cpus_allowed;

 struct sched_rt_entity *back;
#ifdef CONFIG_RT_GROUP_SCHED
 struct sched_rt_entity *parent;
 /* rq on which this entity is (to be) queued: */
 struct rt_rq  *rt_rq;
 /* rq "owned" by this entity/group: */
 struct rt_rq  *my_q;
#endif
};

 

5 cfs_rq 公平調度隊列

/* CFS-related fields in a runqueue */
struct cfs_rq {

//這個和sched_entity的權重有什麼區別????
 struct load_weight load;

//cfs_rq中進程的數目
 unsigned long nr_running;

 u64 exec_clock;

//最小的虛擬已耗用時間,不一定是最小的調度實體的虛擬已耗用時間,但相差無幾
 u64 min_vruntime;

 struct rb_root tasks_timeline;
 struct rb_node *rb_leftmost;

 struct list_head tasks;
 struct list_head *balance_iterator;

 /*
  * 'curr' points to currently running entity on this cfs_rq.
  * It is set to NULL otherwise (i.e when none are currently running).
  */
 struct sched_entity *curr, *next, *last;

 unsigned int nr_spread_over;

#ifdef CONFIG_FAIR_GROUP_SCHED
 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.
  */
 struct list_head leaf_cfs_rq_list;
 struct task_group *tg; /* group that "owns" this runqueue */

#ifdef CONFIG_SMP
 /*
  * the part of load.weight contributed by tasks
  */
 unsigned long task_weight;

 /*
  *   h_load = weight * f(tg)
  *
  * Where f(tg) is the recursive weight fraction assigned to
  * this group.
  */
 unsigned long h_load;

 /*
  * this cpu's part of tg->shares
  */
 unsigned long shares;

 /*
  * load.weight at the time we set shares
  */
 unsigned long rq_weight;
#endif
#endif
};

 

6 即時隊列

struct rt_rq {
 struct rt_prio_array active;
 unsigned long rt_nr_running;
#if defined CONFIG_SMP || defined CONFIG_RT_GROUP_SCHED
 int highest_prio; /* highest queued rt task prio */
#endif
#ifdef CONFIG_SMP
 unsigned long rt_nr_migratory;
 int overloaded;
#endif
 int rt_throttled;
 u64 rt_time;
 u64 rt_runtime;
 /* Nests inside the rq lock: */
 spinlock_t rt_runtime_lock;

#ifdef CONFIG_RT_GROUP_SCHED
 unsigned long rt_nr_boosted;

 struct rq *rq;
 struct list_head leaf_rt_rq_list;
 struct task_group *tg;
 struct sched_rt_entity *rt_se;
#endif
};

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.