iT邦幫忙

2021 iThome 鐵人賽

DAY 9
0
自我挑戰組

當你凝視linux, linux也在凝視你系列 第 9

Day9 初探CFS 下

前言

昨天講到了利用兩個查表的方式來計算,會比直接計算來的節省運算資源,今天就來看看到底要vruntime到底要怎麼計算。

vruntime

vruntime 的公式如下

將2^32 / weight 用 inv_weight取代,就變成以下的式子

這部分的計算出現在 kernel/sched/fair.c 內的cal_delta_fair()

static inline u64 calc_delta_fair(u64 delta, struct sched_entity *se)
{
	if (unlikely(se->load.weight != NICE_0_LOAD))
		delta = __calc_delta(delta, NICE_0_LOAD, &se->load);

	return delta;
}

static u64 __calc_delta(u64 delta_exec, unsigned long weight, struct load_weight *lw) /// calculate delta
{
	u64 fact = scale_load_down(weight);
	u32 fact_hi = (u32)(fact >> 32);
	int shift = WMULT_SHIFT;
	int fs;

	__update_inv_weight(lw);

	if (unlikely(fact_hi)) {
		fs = fls(fact_hi);
		shift -= fs;
		fact >>= fs;
	}

	fact = mul_u32_u32(fact, lw->inv_weight);

	fact_hi = (u32)(fact >> 32);
	if (fact_hi) {
		fs = fls(fact_hi);
		shift -= fs;
		fact >>= fs;
	}

	return mul_u64_u32_shr(delta_exec, fact, shift);
}

以上的部分就是就是vruntime的計算方式,以及其相關的函數。

以上的部分就是就是vruntime的計算方式,以及其相關的函數。

最後提一下在 task_struct裡面關於排程的重要數據結構 sched_entity ,在這個結構裡面包含了所有排程所需要的資訊。

struct sched_entity {
	/* For load-balancing: */
	struct load_weight		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				nr_migrations;

	struct sched_statistics		statistics;

#ifdef CONFIG_FAIR_GROUP_SCHED
	int				depth;
	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;
	/* cached value of my_q->h_nr_running */
	unsigned long			runnable_weight;
#endif

#ifdef CONFIG_SMP
	/*
	 * Per entity load average tracking.
	 *
	 * Put into separate cache line so it does not
	 * collide with read-mostly values above.
	 */
	struct sched_avg		avg;
#endif
};

上一篇
Day8 初探CFS 中
下一篇
Day10 分頁與分段的記憶體管理
系列文
當你凝視linux, linux也在凝視你30

尚未有邦友留言

立即登入留言