secondary cpu執(zhí)行流程
aarch64架構(gòu)secondary cpu的內(nèi)核入口函數(shù)為secondary_entry(arch/arm64/kernel/head.S),以下為其執(zhí)行主流程:
由于其底層相關(guān)初始化流程與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)由于內(nèi)核線程并沒有用于地址空間,因此其active_mm通常指向上一個用戶進程的地址空間。而cpu初始化時,由于之前并沒有運行過用戶進程,因此將其初始化為init_mm
(2)idmap地址映射僅僅是用于mmu使能時地址空間的平滑切換,在mmu使能完成后已經(jīng)沒有作用。更進一步,由于idmap頁表所使用的ttbr0_elx頁表基地址寄存器,正常情況下是用于用戶空間頁表的,在調(diào)度器接管該cpu之前也必須要將其歸還給用戶空間
(3)執(zhí)行cpu_postboot回調(diào)
(4)由secondary cpu已經(jīng)啟動成功,故將其設(shè)置為online狀態(tài)
(5)喚醒cpu hotplug線程
(6)讓cpu執(zhí)行idle線程,其代碼實現(xiàn)如下:
void cpu_startup_entry(enum cpuhp_state state)
{
arch_cpu_idle_prepare();
cpuhp_online_idle(state);
while (1)
do_idle();
}
至此,cpu已經(jīng)啟動完成,并開始執(zhí)行idle線程了。最后當然是要通知調(diào)度器,將該cpu的管理權(quán)限移交給調(diào)度器了。它是通過cpu hotplug的以下回調(diào)實現(xiàn)的:
static struct cpuhp_step cpuhp_hp_states[] = {
…
[CPUHP_AP_SCHED_STARTING] = {
.name = "sched:starting",
.startup.single = sched_cpu_starting,
.teardown.single = sched_cpu_dying,
}
…
}
以下為該函數(shù)的實現(xiàn):
int sched_cpu_starting(unsigned int cpu)
{
…
sched_rq_cpu_starting(cpu); (1)
sched_tick_start(cpu); (2)
…
}
(1)用于初始化負載均衡相關(guān)參數(shù),此后該cpu就可以在其后的負載均衡流程中拉取進程
(2)tick時鐘是內(nèi)核調(diào)度器的脈搏,啟動了該時鐘之后,cpu就會在時鐘中斷中執(zhí)行調(diào)度操作,從而讓cpu參與到系統(tǒng)的調(diào)度流程中
-
cpu
+關(guān)注
關(guān)注
68文章
10863瀏覽量
211782 -
SMP
+關(guān)注
關(guān)注
0文章
74瀏覽量
19667 -
線程
+關(guān)注
關(guān)注
0文章
504瀏覽量
19684
發(fā)布評論請先 登錄
相關(guān)推薦
評論