secondary cpu执行流程介绍

描述

secondary cpu执行流程

aarch64架构secondary cpu的内核入口函数为secondary_entry(arch/arm64/kernel/head.S),以下为其执行主流程:

SMP
由于其底层相关初始化流程与primary cpu类似,因此此处不再介绍。我们这里主要看一下它是如何通过secondary_start_kernel启动idle线程的:

asmlinkage notrace void secondary_start_kernel(void)
{
	struct mm_struct *mm = &init_mm;              			
	…
	current- >active_mm = mm;                               (1)

	cpu_uninstall_idmap();                                 (2)
	…
	ops = get_cpu_ops(cpu);
	if (ops- >cpu_postboot)
		ops- >cpu_postboot();                           (3)
	…
	set_cpu_online(cpu, true);                             (4)
	complete(&cpu_running);                                (5)
	…
	cpu_startup_entry(CPUHP_AP_ONLINE_IDLE);               (6)
}

(1)由于内核线程并没有用于地址空间,因此其active_mm通常指向上一个用户进程的地址空间。而cpu初始化时,由于之前并没有运行过用户进程,因此将其初始化为init_mm

(2)idmap地址映射仅仅是用于mmu使能时地址空间的平滑切换,在mmu使能完成后已经没有作用。更进一步,由于idmap页表所使用的ttbr0_elx页表基地址寄存器,正常情况下是用于用户空间页表的,在调度器接管该cpu之前也必须要将其归还给用户空间

(3)执行cpu_postboot回调

(4)由secondary cpu已经启动成功,故将其设置为online状态

(5)唤醒cpu hotplug线程

(6)让cpu执行idle线程,其代码实现如下:

void cpu_startup_entry(enum cpuhp_state state)
{
	arch_cpu_idle_prepare();
	cpuhp_online_idle(state);
	while (1)
		do_idle();
}

至此,cpu已经启动完成,并开始执行idle线程了。最后当然是要通知调度器,将该cpu的管理权限移交给调度器了。它是通过cpu hotplug的以下回调实现的:

static struct cpuhp_step cpuhp_hp_states[] = {
  …
  [CPUHP_AP_SCHED_STARTING] = {
		.name			= "sched:starting",
		.startup.single		= sched_cpu_starting,
		.teardown.single	= sched_cpu_dying,
  }
  …
}

以下为该函数的实现:

int sched_cpu_starting(unsigned int cpu)
{
  …
  sched_rq_cpu_starting(cpu);        (1)
  sched_tick_start(cpu);             (2)
  …
}

(1)用于初始化负载均衡相关参数,此后该cpu就可以在其后的负载均衡流程中拉取进程

(2)tick时钟是内核调度器的脉搏,启动了该时钟之后,cpu就会在时钟中断中执行调度操作,从而让cpu参与到系统的调度流程中

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分