【內核調度】【enqueue_entity】

/*
 * MIGRATION
 *
 *	dequeue
 *	  update_curr()
 *	    update_min_vruntime()
 *	  vruntime -= min_vruntime
 *
 *	enqueue
 *	  update_curr()
 *	    update_min_vruntime()
 *	  vruntime += min_vruntime
 *
 * this way the vruntime transition(過渡) between RQs is done when both
 * min_vruntime are up-to-date.
 *
 * WAKEUP (remote)
 *
 *	->migrate_task_rq_fair() (p->state == TASK_WAKING)
 *	  vruntime -= min_vruntime
 *
 *	enqueue
 *	  update_curr()
 *	    update_min_vruntime()
 *	  vruntime += min_vruntime
 *
 * this way we don't have the most up-to-date min_vruntime on the originating
 * CPU and an up-to-date min_vruntime on the destination CPU.
 */

static void
enqueue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int flags)
{
	bool renorm = !(flags & ENQUEUE_WAKEUP) || (flags & ENQUEUE_MIGRATED);
	bool curr = cfs_rq->curr == se;

	/*
	 * If we're the current task, we must renormalise(重新規範化) before calling
	 * update_curr().
	 */
/* (4.1) 在enqueue時給se->vruntime重新加上cfs_rq->min_vruntime */
	if (renorm && curr)
		se->vruntime += cfs_rq->min_vruntime;
	
	/*更新cfs_rq調度實體的vruntime和相關調度的統計信息*/ 
//更新runtime和vruntime
	update_curr(cfs_rq);

	/*
	 * Otherwise, renormalise after, such that we're placed at the current
	 * moment in time, instead of some random moment in the past. Being
	 * placed in the past could significantly(顯著的) boost this task to the
	 * fairness detriment(有害的) of existing tasks.
	 */
	if (renorm && !curr)
		se->vruntime += cfs_rq->min_vruntime;

	/*
	 * When enqueuing a sched_entity, we must:
	 *   - Update loads to have both entity and cfs_rq synced with now.
	 *   - Add its load to cfs_rq->runnable_avg
	 *   - For group_entity, update its weight to reflect the new share of
	 *     its group cfs_rq
	 *   - Add its new weight to cfs_rq->load.weight
	 */
	 /*對新進程的調度實體進行util/load進行衰減,根據PELT算法*/
	update_load_avg(se, UPDATE_TG);
	/*更新cfs_rqrunnable_load_sum/avg負載信息已經struct sched_entity → 
    struct sched_avg成員變量數值累加到整個struct cfs_rq-->struct sched_avg上去並
    觸發頻率的調整.*/
	enqueue_entity_load_avg(cfs_rq, se);
	update_cfs_shares(se);
/* 更新cfs_rq隊列總權重(就是在原有基礎上加上se的權重) */
	account_entity_enqueue(cfs_rq, se);

/* 新建的進程flags爲0,不會執行這裏 */
	if (flags & ENQUEUE_WAKEUP)
		place_entity(cfs_rq, se, 0); //確定進程正確的虛擬時間

	check_schedstat_required();
	/*更新調度相關狀態和統計信息*/
	update_stats_enqueue(cfs_rq, se, flags);
	check_spread(cfs_rq, se);
	
	/*如果當前調度實體不是cfs_rq當前的調度實體,則將新進程的調度實體插入rb tree中,根據
    vruntime的大小加入rb tree*/ 
	if (!curr)
//將進程置於紅黑樹中。使用內核的標準方法將進程排序到紅黑樹中
		__enqueue_entity(cfs_rq, se);
	/*新進程在rq中*/ 
	se->on_rq = 1;

	if (cfs_rq->nr_running == 1) {
		list_add_leaf_cfs_rq(cfs_rq);
		check_enqueue_throttle(cfs_rq);
	}
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章