linux sched init简介

调度器的初始化,前面的android 开机流程讲过,uboot(bootloader)执行完一些初始化动作后,会将kernel加载到内存,然后跳到kernel。
kernel在执行完一段汇编代码,准备好c的运行环境后,跳到 start_kernel()。

linux-4.10/init/main.c

linux-4.10/init/main.c
482  asmlinkage __visible void __init start_kernel(void)
483  {
...
542  	/*
543  	 * Set up the scheduler prior starting any interrupts (such as the
544  	 * timer interrupt). Full topology setup happens at smp_init()
545  	 * time - but meanwhile we still have a functioning scheduler.
546  	 */
547  	sched_init();  //调度器的初始化
...
672  	/* Do the rest non-__init'ed, we're now alive */
673  	rest_init();
674  }

sched_init() 初始化了很多调度相关的数据结构,下面只会把它们简单列出来

linux-4.10/kernel/sched/core.c

linux-4.10/kernel/sched/core.c
7543  void __init sched_init(void)
7544  {
7545  	int i, j;
7546  	unsigned long alloc_size = 0, ptr;
7547  
/*
 *  linux-4.10/include/linux/types.h
 *   struct list_head {    //双向链表
 *   	struct list_head *next, *prev;
 *  };
 *  linux-4.10/include/linux/wait.h
 *  struct __wait_queue_head {  //所以__wait_queue_head 是一个双向链表,用于保存 spinlock_t (自旋锁)
 *  	spinlock_t		lock;
 *  	struct list_head	task_list;
 *   };
   typedef struct __wait_queue_head wait_queue_head_t;
*/
7548  	for (i = 0; i < WAIT_TABLE_SIZE; i++) // #define WAIT_TABLE_BITS 8  #define WAIT_TABLE_SIZE (1 << WAIT_TABLE_BITS)  所以WAIT_TABLE_SIZE 等于 256
7549  		init_waitqueue_head(bit_wait_table + i);  //static wait_queue_head_t bit_wait_table[WAIT_TABLE_SIZE] __cacheline_aligned;  
7550  
7551  #ifdef CONFIG_FAIR_GROUP_SCHED   //普通进程调度
7552  	alloc_size += 2 * nr_cpu_ids * sizeof(void **);  //nr_cpu_ids 为支持的cpu核个数,也就是常说的几核,64位系统上 sizeof(void **) = 8
7553  #endif
7554  #ifdef CONFIG_RT_GROUP_SCHED   //实时进程调度
7555  	alloc_size += 2 * nr_cpu_ids * sizeof(void **);  
7556  #endif
7557  	if (alloc_size) {
7558  		ptr = (unsigned long)kzalloc(alloc_size, GFP_NOWAIT);  //申请内存
7559  
7560  #ifdef CONFIG_FAIR_GROUP_SCHED
7561  		root_task_group.se = (struct sched_entity **)ptr; //指向调度实体
7562  		ptr += nr_cpu_ids * sizeof(void **);//ptr指针移动nr_cpu_ids * sizeof(void **) nr_cpu_ids, 为支持的cpu核个数,64位系统上 sizeof(void **) = 8
7563  
7564  		root_task_group.cfs_rq = (struct cfs_rq **)ptr;  //指向调度队列指针,每个核有一个调度队列
7565  		ptr += nr_cpu_ids * sizeof(void **);//ptr指针移动nr_cpu_ids * sizeof(void **) nr_cpu_ids,为支持的cpu核个数,64位系统上 sizeof(void **) = 8
7566  
7567  #endif /* CONFIG_FAIR_GROUP_SCHED */
7568  #ifdef CONFIG_RT_GROUP_SCHED
7569  		root_task_group.rt_se = (struct sched_rt_entity **)ptr; //
7570  		ptr += nr_cpu_ids * sizeof(void **); //ptr指针移动nr_cpu_ids * sizeof(void **) nr_cpu_ids, 为支持的cpu核个数,64位系统上 sizeof(void **) = 8
7571  
7572  		root_task_group.rt_rq = (struct rt_rq **)ptr;  //
7573  		ptr += nr_cpu_ids * sizeof(void **);
7574  
7575  #endif /* CONFIG_RT_GROUP_SCHED */
7576  	}
7577  #ifdef CONFIG_CPUMASK_OFFSTACK
7578  	for_each_possible_cpu(i) {  // (1)...
7579  		per_cpu(load_balance_mask, i) = (cpumask_var_t)kzalloc_node(
7580  			cpumask_size(), GFP_KERNEL, cpu_to_node(i));
7581  		per_cpu(select_idle_mask, i) = (cpumask_var_t)kzalloc_node(
7582  			cpumask_size(), GFP_KERNEL, cpu_to_node(i));
7583  	}
7584  #endif /* CONFIG_CPUMASK_OFFSTACK */
7585    // (2)...
7586  	init_rt_bandwidth(&def_rt_bandwidth, //初始化实时进程对cpu的占有率 ,超过会有一定的惩罚机制(rt throttled)
7587  			global_rt_period(), global_rt_runtime());
7588  	init_dl_bandwidth(&def_dl_bandwidth,
7589  			global_rt_period(), global_rt_runtime());
7590  
7591  #ifdef CONFIG_SMP
7592  	init_defrootdomain();  // (3)...
7593  #endif
7594  
7595  #ifdef CONFIG_RT_GROUP_SCHED 
7596  	init_rt_bandwidth(&root_task_group.rt_bandwidth,/初始化root_task_group进程组实时进程对cpu的占有率
7597  			global_rt_period(), global_rt_runtime());
7598  #endif /* CONFIG_RT_GROUP_SCHED */
7599  
7600  #ifdef CONFIG_CGROUP_SCHED  //如果支持进程组,可以理解为多用户,每个用户下面的所有进程为一个进程组
7601  	task_group_cache = KMEM_CACHE(task_group, 0);
7602  
7603  	list_add(&root_task_group.list, &task_groups); //将root_task_group添加到task_groups队列中
7604  	INIT_LIST_HEAD(&root_task_group.children);
7605  	INIT_LIST_HEAD(&root_task_group.siblings);
7606  	autogroup_init(&init_task);
7607  #endif /* CONFIG_CGROUP_SCHED */
7608  
7609  	for_each_possible_cpu(i) {
7610  		struct rq *rq;
/*
 *  linux-4.10/kernel/sched/sched.h
 *  struct rq {
 *    	/* runqueue lock: */
 *    	raw_spinlock_t lock;  //自旋锁
 *  ...
 *  604  	unsigned int nr_running; //此CPU上总共就绪的进程数
 *  ...
 *   	u64 nr_switches; // 进行上下文切换次数
 *    
 *    	struct cfs_rq cfs; // cfs调度运行队列
 *    	struct rt_rq rt;   //实时调度运行队列
 *    	struct dl_rq dl;   //dl调度运行队列
 *  ...
 *    	struct task_struct *curr, *idle, *stop;
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值