啟動secondary cpu
內核在啟動secondary cpu之前當然需要為其準備好執行環境,因為內核中cpu最終都將由調度器管理,故此時調度子系統應該要初始化完成。
同時cpu啟動完成轉交給調度器之前,并沒有實際的業務進程,而我們知道內核中cpu在空閑時會執行idle進程。因此,在其啟動之前需要為每個cpu初始化一個idle進程。
另外,由于將一個cpu通過熱插拔方式移除后,再次啟動該cpu的流程,與secondary cpu的啟動流程是相同的,因此內核復用了cpu hotplug框架用于啟動secondary cpu。
而內核為每個cpu都分配了一個獨立的hotplug線程,用于執行本cpu相關的熱插拔流程。為此,內核通過以下流程執行secondary cpu啟動操作:
idle進程初始化
以下代碼為每個非boot cpu分配一個idle進程
void __init idle_threads_init(void)
{
…
boot_cpu = smp_processor_id();
for_each_possible_cpu(cpu) { (1)
if (cpu != boot_cpu)
idle_init(cpu); (2)
}
}
(1)遍歷系統中所有的possible cpu
(2)若該cpu為secondary cpu,則為其初始化一個idle進程
hotplug線程初始化
以下代碼為每個cpu初始化一個hotplug線程
void __init cpuhp_threads_init(void)
{
BUG_ON(smpboot_register_percpu_thread(&cpuhp_threads));
kthread_unpark(this_cpu_read(cpuhp_state.thread));
}
其中線程的描述結構體定義如下:
static struct smp_hotplug_thread cpuhp_threads = {
.store = &cpuhp_state.thread, (1)
.create = &cpuhp_create, (2)
.thread_should_run = cpuhp_should_run, (3)
.thread_fn = cpuhp_thread_fun, (4)
.thread_comm = "cpuhp/%u", (5)
.selfparking = true, (6)
}
(1)用于保存cpu上的task struct指針
(2)線程創建時調用的回調
(3)該回調用于獲取線程是否需要退出標志
(4)cpu hotplug主函數,執行實際的hotplug操作
(5)該線程的線程名
(6)用于設置線程創建完成后,是否將其設置為park狀態
-
內核
+關注
關注
3文章
1382瀏覽量
40372 -
cpu
+關注
關注
68文章
10901瀏覽量
212666 -
SMP
+關注
關注
0文章
76瀏覽量
19703
發布評論請先 登錄
相關推薦
評論