遷移執行緒migration

yooooooo發表於2024-10-23

每個處理器有一個遷移執行緒,執行緒名稱是“migration/<cpu_id>”,屬於停機排程類,可以搶佔所有其他程序,其他程序不可以搶佔它。遷移執行緒有兩個作用。

(1)排程器發出遷移請求,遷移執行緒處理遷移請求,把程序遷移到目標處理器。

(2)執行主動負載均衡。

如圖所示,每個處理器有一個停機工作管理器,成員thread指向遷移執行緒的程序描述符,成員works是停機工作佇列的頭節點,每個節點是一個停機工作,資料型別是結構體

cpu_stop_work。核心提供了兩個新增停機工作的函式。

stop_one_cpu
--cpu_stop_queue_work
---__cpu_stop_queue_work
----list_add_tail and wake_up_process

在stop_one_cpu中,遷移作業將打包為工作,並呼叫cpu_stop_queue_work以獲取CPU的停止執行緒。 然後,呼叫__cpu_stop_queue_work將此工作放入此CPU上的停止執行緒的工作佇列中。 最後,喚醒停止執行緒進行遷移。 停止器執行緒在Linux核心中稱為遷移執行緒(請參閱以下原始碼)。

504 static struct smp_hotplug_thread cpu_stop_threads = {
505         .store                  = &amp;cpu_stopper.thread,
506         .thread_should_run      = cpu_stop_should_run,
507         .thread_fn              = cpu_stopper_thread,
508         .thread_comm            = "migration/%u",
509         .create                 = cpu_stop_create,
510         .park                   = cpu_stop_park,
511         .selfparking            = true,
512 };
513 
514 static int __init cpu_stop_init(void)
515 {
516         unsigned int cpu;
517 
518         for_each_possible_cpu(cpu) {
519                 struct cpu_stopper *stopper = &amp;per_cpu(cpu_stopper, cpu);
520 
521                 spin_lock_init(&amp;stopper-&gt;lock);
522                 INIT_LIST_HEAD(&amp;stopper-&gt;works);
523         }
524 
525         BUG_ON(smpboot_register_percpu_thread(&amp;cpu_stop_threads));
526         stop_machine_unpark(raw_smp_processor_id());
527         stop_machine_initialized = true;
528         return 0;
529 }
530 early_initcall(cpu_stop_init);

我們發現每個CPU上的Linux Kernel遷移執行緒都是透過early_initcall初始化的,這是在啟動核心時完成的,如下所示。

start_kernel
--rest_init
---kernel_init
----kernel_init_freeable
-----do_pre_smp_initcalls
------do_one_initcall

Linux Kernel遷移執行緒守護程式是要初始化的early_initcall之一。 Linux核心有許多初始化呼叫,如下所示。

814 static char *initcall_level_names[] __initdata = {
815         "early",
816         "core",
817         "postcore",
818         "arch",
819         "subsys",
820         "fs",
821         "device",
822         "late",
823 };

到目前為止,我認為一切都已經清楚了,啟動核心後,Linux核心中的遷移守護程序執行緒將被初始化。 一旦完成遷移工作,它就會被喚醒以進行遷移工作(注意:在這裡,我只考慮sched_setaffinity的情況,也許Linux核心中還有其他方法可以喚醒遷移執行緒守護程式)。 此外,對於其他核心執行緒守護程式(例如softirqd,kworker等),它們具有由Linux Kernel建立的類似方式(例如遷移執行緒守護程式)。

結論在Linux核心中,每個CPU都有一個遷移執行緒守護程式來執行資源平衡作業。 如果我們呼叫sched_setaffinity系統呼叫將一個執行緒從源CPU遷移到目標CPU,並且該執行緒正在執行或處於TASK_WAKING狀態,則遷移作業將打包到源CPU的遷移執行緒的工作佇列中,然後,遷移執行緒將被喚醒以完成遷移工作。

相關文章