调度子系统1_调度子系统初始化(一)

2014-11-24 02:49:03 · 作者: · 浏览: 8
unsigned int sysctl_sched_rt_period = 1000000;
int sysctl_sched_rt_runtime = 950000;

//	参考:
//		http://soft.chinabyte.com/os/22/12359522.shtml
//		http://hi.baidu.com/_kouu/item/0fe32610e493314be75e06d1
//		http://blog.chinaunix.net/uid-27052262-id-3239263.html
//		http://blog.csdn.net/wudongxu/article/details/8574749
//		http://lwn.net/Articles/296419/

//	调度初始化
//	函数任务:
//		1.初始化rootdomain
//			rootdomain指示rq可运行的cpu集合
//		2.初始化real-time task对cpu的占有率
//			sysctl_sched_rt_period代表rt进程的调度周期
//			sysctl_sched_rt_runtime代表rt进程在调度周期中可运行的时间
//		3.初始化per-cpu rq
//			3.1 初始化公平调度队列,实时调度队列
//			3.2 初始化cpu负载记录数组
//			3.3 初始化cpu使用的tick hrtimer
//		4.初始化current(init_task)为idle task
//			4.1 设置current由公平调度管理
1.1 void __init sched_init(void)
{
	int i, j;

#ifdef CONFIG_SMP
	//初始化默认的调度域
	init_defrootdomain();
#endif

	//rt_bandwidth表示实时进程对cpu的占有率
	init_rt_bandwidth(&def_rt_bandwidth,
			global_rt_period(), global_rt_runtime());

	//初始化per-cpu rq
	for_each_possible_cpu(i) {
		struct rq *rq;
		//per-cpu 运行队列
		rq = cpu_rq(i);
		raw_spin_lock_init(&rq->lock);
		rq->nr_running = 0;
		rq->calc_load_active = 0;
		rq->calc_load_update = jiffies + LOAD_FREQ;
		//初始化公平调度策略、实时调度策略队列
		init_cfs_rq(&rq->cfs, rq);
		init_rt_rq(&rq->rt, rq);
		//调度队列中,实时进程对cpu的占有率
		rq->rt.rt_runtime = def_rt_bandwidth.rt_runtime;
		//分5个等级记录cpu的负载情况
		for (j = 0; j < CPU_LOAD_IDX_MAX; j++)
			rq->cpu_load[j] = 0;
#ifdef CONFIG_SMP
		rq->sd = NULL;
		rq->rd = NULL;
		rq->post_schedule = 0;
		rq->active_balance = 0;
		rq->next_balance = jiffies;
		rq->push_cpu = 0;
		//rq运行的cpu
		rq->
cpu = i; rq->online = 0; rq->migration_thread = NULL; rq->idle_stamp = 0; rq->avg_idle = 2*sysctl_sched_migration_cost; INIT_LIST_HEAD(&rq->migration_queue); rq_attach_root(rq, &def_root_domain); #endif //初始化rq使用的hrtimer init_rq_hrtick(rq); atomic_set(&rq->nr_iowait, 0); } set_load_weight(&init_task); //load balancing软中断 #ifdef CONFIG_SMP open_softirq(SCHED_SOFTIRQ, run_rebalance_domains); #endif atomic_inc(&init_mm.mm_count); //通知底层体系结构不需要切换虚拟地址空间的用户空间部分 enter_lazy_tlb(&init_mm, current); //将当前进程,即init_task更新为idle thread init_idle(current, smp_processor_id()); //下次进行load balancing的时间戳 calc_load_update = jiffies + LOAD_FREQ; //当前进程关联的调度累 current->sched_class = &fair_sched_class; perf_event_init(); //标识调度器开始运行 scheduler_running = 1; } // 参考 http://blog.csdn.net/bullbat/article/details/7160246 1.2 struct rq { raw_spinlock_t lock; //就绪队列中进程数 unsigned long nr_running; #define CPU_LOAD_IDX_MAX 5 //分5个等级记录就绪队列的负载情况 //在系统初始化的时候sched_init把rq的cpu_load array初始化为0,之后通过函数update_cpu_load //公式如下: // cpu_load[0]等于rq中load.weight的值 // cpu_load[1]=(cpu_load[1]*(2-1)+cpu_load[0])/2 // cpu_load[2]=(cpu_load[2]*(4-1)+cpu_load[0])/4 // cpu_load[3]=(cpu_load[3]*(8-1)+cpu_load[0])/8 // cpu_load[4]=(cpu_load[4]*(16-1)+cpu_load[0]/16 //通过this_cpu_load返回的cpu load值是cpu_load[0] //进行cpu blance或migration时,通过调用source_load target_load取得对该处理器cpu_load index值。 unsigned long cpu_load[CPU_LOAD_IDX_MAX]; //本schedule entity的load->weight的总和 struct load_weight load; //scheduler tick中调用update_cpu_load时,这个值就增加一,可以用来反馈目前cpu load更新的次数。 unsig