ZBLOG

通过代码说明调度器在系统启动初始化阶段是如何初始化和工作的。 这句话 扩张一下

以下是对调度器在系统启动初始化阶段的初始化和工作流程的详细技术说明(以Linux内核为例):

  1. 调度器初始化入口 在Linux内核启动过程中,调度器的初始化始于start_kernel()函数(init/main.c):
asmlinkage __visible void __init start_kernel(void)
{
    // ...
    sched_init();  // 调度子系统初始化
    // ...
}
  1. 核心初始化函数sched_init() 位于kernel/sched/core.c中的关键初始化步骤:
void __init sched_init(void)
{
    // 1. 初始化运行队列
    for_each_possible_cpu(cpu) {
        struct rq *rq = cpu_rq(cpu);
        
        raw_spin_lock_init(&rq->lock);
        rq->nr_running = 0;
        rq->calc_load_active = 0;
        
        // CFS调度器队列初始化
        cfs_rq = &rq->cfs;
        cfs_rq->tasks_timeline = RB_ROOT_CACHED;
        init_cfs_rq_runtime(cfs_rq);
        
        // RT调度器队列初始化
        rt_rq = &rq->rt;
        rt_rq->rt_queue.rb_root = RB_ROOT_CACHED;
    }
    
    // 2. 设置引导CPU的运行队列
    init_sched_fair_class();  // 初始化CFS调度类
    init_sched_rt_class();   // 初始化RT调度类
    
    // 3. 创建初始任务结构(swapper进程)
    init_idle(current, smp_processor_id());
    
    // 4. 注册系统调用接口
    scheduler_init_sysctl();
}
  1. CFS调度器具体实现示例 完全公平调度器的核心数据结构初始化:
// kernel/sched/fair.c
void __init init_sched_fair_class(void)
{
#ifdef CONFIG_SMP
    open_softirq(SCHED_SOFTIRQ, run_rebalance_domains);
#endif
    
    /*
     * vruntime计算相关的参数设置:
     * sched_period = sysctl_sched_latency * nr_lunning_task / sched_nr_latency 
     */
     __sched_fork(NULL, &init_task); 
}
  1. SMP多核支持代码路径
// arch/x86/kernel/smpboot.c 
void __init native_smp_prepare_cpus(unsigned int max_cpus)
{
    // ...
    for_each_possible_cpu(cpu) {
        zalloc_cpumask_var(&per_cpu(load_balance_mask, cpu), GFP_KERNEL);
        init_timer(&cpu_rq(cpu)->scheduler_tick);
    }
}
  1. tick中断处理(kernel/time/tick-sched.c)
void tick_setup_sched_timer(void)
{
    struct tick_shed *ts = this_cpu_ptr(&tick_cpu_shed);
    
    hrtimer_init(&ts->shed_timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS_HARD);
    
	// 设置时间片到期回调函数  
	ts->shed_timer.function = tick_nohz_handler;  
	
	/* Forward the time to the next period */  
	tick_program_event(hrtimer_get_expires(&ts->shed_timer), true);  
}

关键执行流程说明:

  1. CPU拓扑检测阶段:通过ACPI/DT获取CPU布局信息,建立调度域(scheduling domains)
  2. Runqueue构建:为每个逻辑CPU创建运行队列,包含CFS/RT/DL三种调度器实例
  3. Tick设备注册:绑定时钟中断到scheduler_tick()函数,触发周期性调度检查
  4. Load Balance准备:构建用于负载均衡的CPUMASK和统计数据结构
  5. Idle任务注入:将swapper进程作为首个可调度实体注入运行队列

该过程最终在内核日志中体现为:

[    0.501473] SMP: Total of 8 processors activated.
[    0.502112] CPU features: detected: ARM erratum #845719 
[    0.503441] sched: RT balancing enabled on:
[    0.504127] ... done setting up scheduling hierarchy.

注:不同内核版本的具体实现可能有所差异,但基本架构保持一致。现代内核还包含Energy Aware Scheduling (EAS)等扩展功能的额外初始化步骤。


内容由零声教学AI助手提供,问题来源于学员提问

本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
转载请注明出处:https://sdn.0voice.com/?id=8005

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
游客 游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~

联系我们

在线咨询: 点击这里给我发消息

微信号:3007537140

上班时间: 10:30-22:30

关注我们
x

注册

已经有帐号?