1. 程式人生 > >cpu hotplug的流程

cpu hotplug的流程

以下內容參考: http://loda.hala01.com/2011/08/android-筆記-linux-kernel-smp-symmetric-multi-processors-開機流程解析-part3-linux-多核心啟動流/

1,cpu hotplug機制

Linux Kernel支援CPU hotplug機制,並可透過全域變數cpu_hotplug_disabled決定處理器Hot Plug機制的致能與否.參考檔案 kernel/cpu.c,如果全域變數cpu_hotplug_disabled被設定為1,cpu_up與cpu_down機制就會失效(返回-EBUSY). 在實作上,可以呼叫函式enable_nonboot_cpus致能CPU Up/Down機制,或呼叫函式disable_nonboot_cpus關閉CPU Up/Down機制.

2,cpu down的流程

CPU Down呼叫流程為cpu_down (in kernel/cpu.c) -> _cpu_down (in kernel/cpu.c) → __cpu_die (in arch/arm/kernel/smp.c)。

CPU DOWN流程 說明
1,”cpu_down”
(in kernel/cpu.c)
1,呼叫cpu_maps_update_begin 設定Mutex Lock “cpu_add_remove_lock”
2,確認cpu_hotplug_disabled是否有被設定
3,呼叫 _cpu_down(cpu, 0)
4,呼叫cpu_maps_update_done解開Mutex Lock “cpu_add_remove_lock”
2,”_cpu_down”
(in kernel/cpu.c)
1,呼叫函式num_online_cpus,確認如果目前Online的處理器只有一個,會直接返回錯誤 (mmmm,如果這個也Down下去就沒有處理器可用了…)
2,呼叫函式cpu_online,如果該CPU並非Online狀態,就返回錯誤

3,呼叫cpu_hotplug_begin,取得 Mutex Lock “cpu_hotplug.lock”.

4,呼叫__cpu_notify,透過函式__raw_notifier_call_chain,通知CPU Chain中的處理器,目前正在進行Online動作的處理器狀態為”CPU_DOWN_PREPARE”.

5,呼叫函式__stop_machine (in )

5.a,透過函式set_state設定struct stop_machine_data smdata 中的state為STOPMACHINE_PREPARE

5.b,透過函式stop_cpus,停止指定的處理器. 會在關閉Preemption的狀態下,透過cpu_stop_queue_work,讓要被停止的處理器執行函式take_cpu_down.

5.c,由於是由要被停止的處理器執行函式take_cpu_down,在這函式的實作中,會呼叫__cpu_disable(in arch/arm/kernel/smp.c),把自己Offline,Migrate IRQ給其他處理器,停止Local Timer,Flush Cache/TLB,透過cpumask_clear_cpu把自己從Memory Management CPU Mask中移除,最後透過cpu_notify通知自己處於CPU_DYING.

5.d,進入Callback函式migration_call中 (in kernel/sched.c),並透過函式migrate_tasks把要Offline處理器的Tasks轉移到其它處理器上. (在這之後,處理器就只剩下Idle Task.).

6,透過BUG_ON(cpu_online(cpu)),確認要停止的處理器,是否已經處於Offline的狀態. (若還是在Online狀態就會導致Kernel Panic)

7,呼叫函式idle_cpu (in kernel/shced.c),確認要Offline處理器是否正在執行idle task.(前面的migrate_tasks已經把要Offline處理器的所有Tasks都轉到其它處理器上了).若該處理器不是正在執行Idle Task,就會呼叫 cpu_relax (對應的實作為ARM的Memory Barrier),直到確認要Offline的處理器是處於Idle Task中.

8,呼叫 __cpu_die(cpu)

9,呼叫cpu_notify_nofail,通知完成Offline動作的處理器狀態為”CPU_DEAD”.

10,呼叫check_for_tasks,確認目前是否還有Tasks在被停止的處理器上,若有就會Printk出警告訊息…(ㄟ….就算有在這階段也來不及做啥了……@
[email protected]
)

11,呼叫cpu_hotplug_done,設定Active Write為NULL,解開Mutex Lock “cpu_hotplug.lock”.
3,”__cpu_die”

(in arch/arm/kernel/smp.c)

1,會執行函式wait_for_completion_timeout,等待函式cpu_die 透過函式 complete 設定“Completion”給 cpu_died物件,如果cpu_died物件有設定完成或是TimeOut就會繼續往後執行.有關cpu_die函式的執行,是在處理器初始化到最後時,會透過函式rest_init呼叫到函式cpu_idle (in arch/arm/kernel/process.c)中,由cpu_idle執行處理器的IDLE流程. 而在cpu_idle中,在有支援CPU HotPlug的組態下,會去確認處理器是否被Offiline,若是就會執行 cpu_die,如下所示
#ifdef CONFIG_HOTPLUG_CPU
if (cpu_is_offline(smp_processor_id()))
cpu_die();
#endif

2,呼叫platform_cpu_kill (in arch/arm/mach-tegra/hotplug.c),以Tegra方案來說,這函式為空函式.

3,而CPU Idle Task在執行cpu_die後,就會進入函式platform_cpu_die (in arch/arm/mach-tegra/hotplug.c),並透過platform_do_lowpower,讓處理器處於WFI Low Power的狀態,等待下一次的喚醒.

4,若處理器重新被喚醒,就會執行函式secondary_start_kernel (in arch/arm/kernel/smp.c),重新執行初始化流程.

3,cpu_idle()的流程

實作在檔案arch/arm/kernel/process.c中,當處理器沒有其它Task執行時,就會在這函式中運作,Linux Kernel支援 Tickless System (設定路徑在Kernel Features  —>Tickless System (Dynamic Ticks)),如果有選擇這能力,會在.config中設定CONFIG_NO_HZ=y. 當處理器執行IDLE Task時,可以停止系統的Scheduling Tick,也就是說進入pm_idle時,可以減少Timer中斷觸發(例如HZ=100,每秒就有一百次Tick Timer中斷觸發),減少系統醒來的機會.


有關CPU Idle的說明,也可以參考Linux Kernel檔案”Documentation/scheduler/sched-arch.txt”,如下簡述 CPU Idle的行為


1,Enable FIQ.
2,進入 while(1) 的 Loop
2-1,呼叫tick_nohz_stop_sched_tick,停止Scheduling Tick,包括會透過get_next_timer_interrupt取得下一次Timer中斷,跟現在的時間計算Delta delta_jiffies,如果delta_jiffies過小(=1),也就是說下個Timer中斷很快就會被觸發,就會直接結束這函式. (間隔過短,關閉Scheduling Tick所產生的效益就降低了.),由於系統時間所依賴的jiffies就是透過Scheduling Tick更新,因此在這函式中也會針對暫停Scheduling Tick引起的時間差,預備修正的機制.
2-2,進入while (!need_resched()) Loop  ,執行need_resched可以知道是否需要重新排程,或是要準備進入IDLE的省電機制中. Idle 流程不會Set或Clear 函式need_resched所參考的TIF_NEED_RESCHED,當Idle流程觸發排程時,才會Clear該狀態
2-2-1,如果目前的處理器已經被Offline,則呼叫cpu_die
2-2-2,Disable IRQ
2-2-3,如果hlt_counter不為0,就會Enable IRQ,執行cpu_relax. 如果有呼叫platform_suspend_ops中的 end 函式指標,就會呼叫enable_hlt,讓hlt_counter不為0,反之如果呼叫begin函式指標,就會透過disable_hlt,讓htl_counter減為0.  (並非所有ARM方案都有設定Platform Suspend Operation的機制,例如TI OMAP有,而Nvidia Tegra則無).
2-2-4,若hlt_counter為0,就會進入每個平臺差異化的pm_idle實作,在這個函式指標中,會依據每個平臺的實作不同,在系統初始化時,設定給不同的Power Management函式.例如:omap2_pm_idle,omap3_pm_idle或s5p64x0_idle,在這就可以根據每個平臺的差異,優化跟平臺有關的Power Saving機制,包括關閉PMU Power Group(LDO)或是停止PLL..等,讓系統可以進入更深度的省電模式. 執行完畢pm_idle後,就會Enable IRQ,往後繼續執行.
2-3,呼叫tick_nohz_restart_sched_tick,恢復Scheduling Tick,並更新jiffies
2-4,執行preempt_enable_no_resched,致能Preemptive排程 (Call dec_preempt_count())
2-5,進行Kernel Scheduling
2-6,執行preempt_disable,關閉Preemptive排程  (Call inc_preempt_count()),在cpu_idle中,除了要觸發排程外,多數的情況下Preemptive排程會被關閉,直到要重新觸發Linux Kernel排程才會致能Preemptive機制.

4,cpu_up()的流程

CPU Up呼叫流程為
cpu_up (in kernel/cpu.c) -> _cpu_up (in kernel/cpu.c) → __cpu_up (in arch/arm/kernel/smp.c)

CPU UP 流程 說明
1, “cpu_up”
(in kernel/cpu.c)
1,呼叫cpu_possible確認目前要Online的處理器是否可被啟用.
2,呼叫cpu_maps_update_begin 設定Mutex Lock “cpu_add_remove_lock”

3,確認cpu_hotplug_disabled是否有被設定 (也就是不允許動態的CPU Online動作)

4,呼叫 _cpu_up(cpu, 0)

5,呼叫cpu_maps_update_done解開Mutex Lock “cpu_add_remove_lock”
2, “_cpu_up”
(in kernel/cpu.c)
1,如果該CPU已經Online或是非Present的狀態,就返回錯誤
2,呼叫cpu_hotplug_begin,

2.a,設定Active Write為目前的Process (cpu_hotplug.active_writer = current),取得 Mutex Lock “cpu_hotplug.lock”.

2.b,如果 cpu_hotplug.refcount為0,表示目前沒有其它Reader,因此,可以結束函式cpu_hotplug_begin,讓_cpu_up後續工作繼續

2.c,反之,如果cpu_hotplug.不為0,就會把行程設定為TASK_UNINTERRUPTIBLE,並解開Mutex Lock “cpu_hotplug.lock”,觸發排程,讓其它的Reader把工作結束
(必須讓Write取得Mutex Lock “cpu_hotplug.lock”以及cpu_hotplug.refcount為0,才能讓函式cpu_hotplug_begin結束).

3,呼叫__cpu_notify,透過函式__raw_notifier_call_chain,通知CPU Chain中的處理器,目前正在進行Online動作的處理器狀態為”CPU_UP_PREPARE”.

4,呼叫 __cpu_up(cpu)

5,呼叫cpu_notify,透過函式__raw_notifier_call_chain,通知CPU Chain中的處理器,目前完成Online動作的處理器狀態為”CPU_ONLINE”.

6,呼叫cpu_hotplug_done,設定Active Write為NULL (cpu_hotplug.active_writer = NULL),解開Mutex Lock “cpu_hotplug.lock”.
3,  “__cpu_up”

(in arch/arm/kernel/smp.c)

1,呼叫per_cpu取得要Online處理器的cpuinfo_arm結構 (in arch/arm/include/asm/cpu.h),如下所示
struct cpuinfo_arm {
struct cpu      cpu;
#ifdef CONFIG_SMP
struct task_struct *idle; //會指向目前這個處理器的IDLE Task.
unsigned int    loops_per_jiffy;
#endif
};

2,如果目前處理器沒有指定Idle Task,就透過函式fork_idle (in kernel/fork.c)產生Idle Task後指定給這個處理器. 函式fork_idle會呼叫copy_process複製一個PID = init_struct_pid的行程,並執行函式init_idle_pids與init_idle把這Idle Task指定給要Online的處理器.

3,反之,如果這處理器已經有Idle Task,就呼叫函式init_idle (in kernel/sched.c)指定Idle Task給目前進行Online的處理器.

4,呼叫函式pgd_alloc (in arch/arm/mm/pgd.c),會以1MB TLB Settings (約需要16kbytes 記憶體),產生TLB Level 1的Page Table.

5,如果PHYS_OFFSET != PAGE_OFFSET (PHYS_OFFSET為Kernel Image在實體記憶體中的Offset,PAGE_OFFSET為Kernel Image在虛擬記憶體中的Offset,一般而言為0x8000),就會透過函式identity_mapping_add (in arch/arm/mm/idmap.c),把Linux Kernel Image 程式區段 (_stext 到_etext)與資料區段(_sdata到_edata)的記憶體分頁以1MB TLB與AP (Access Permission)為PMD_SECT_AP_WRITE  (1 << 10) 屬性設定到TLB分頁中.有關記憶體分頁的屬性與對應的Bits如下圖所示,以現有程式碼的配置來說,對Linux Kernel 的程式與資料區段是特權等級Privileged permissions為Read/Write,而一般應用程式User permissions為No Access.

至此就完成對新增處理器的初步MMU記憶體分頁與安全性的配置動作.

6,設定要Online處理器的Stack (secondary_data.stack)與Page Table(secondary_data.pgdir)位址到全域變數struct secondary_data.

7,呼叫函式__cpuc_flush_dcache_area進行 DCache Flush (範圍是全域變數struct secondary_data在記憶體的起點與大小)

8,呼叫函式outer_clean_range把Clean L2 Cache (範圍是全域變數struct secondary_data在記憶體的起點與大小)

9,透過函式boot_secondary (in arch/arm/mach-tegra/platsmp.c)帶起Online處理器.

10,secondary_data.stack = NULL;與secondary_data.pgdir = 0;

11, 如果PHYS_OFFSET != PAGE_OFFSET,就會透過函式identity_mapping_del把之前配置的Linux Kernel Image 程式區段 (_stext 到_etext)與資料區段(_sdata到_edata)記憶體分頁刪除.

12, 呼叫函式pgd_free釋放Page Table.

相關推薦

cpu hotplug流程

/#  /# echo 0 > /sys/devices/system/cpu/cpu1/online cpu_subsys_offline     cpu_down         do_cpu_down             _cpu_down       

cpu hotplug流程

以下內容參考: http://loda.hala01.com/2011/08/android-筆記-linux-kernel-smp-symmetric-multi-processors-開機流程解析-part3-linux-多核心啟動流/ 1,cpu hotplug機制

RTK8370N報文上CPU處理流程梳理

一、報文上CPU目的 前提:由於原先裝置使用管理VLAN1來實現裝置管理,但是這樣實現的缺陷是大量二層資料報文會廣播到CPU上,對CPU的效能影響較大,所以我們希望使用ACL的方式進行處理上CPU報文。       裝置上CPU報文的型別: 首先ARP廣播 報文會上CP

CPU卡充值消 費流程

充值 離線充值 1、  選擇要充值的應用目錄。 2、  驗證口令金鑰。 3、  取得充值金鑰(這裡使用加密機提供的分散指令,用ATS作為分散因子對00B0金鑰進行分散得到充值金鑰)。 4、  圈存交易初始化。 5、&nbs

記一次伺服器CPU異常處理流程

上線新版本後cpu飆升,配置什麼都沒變! 1,著手調查馬上檢視慢查詢,沒有慢查詢 2,檢視慢php程序tail -f log.slow,定位到方法函式圖片轉指令方法耗時大,和cpu損耗掛鉤,基本猜測這個函式方法,但沒有優化空間 3,不死心,查一下程序耗損掛起點:ll /proc/PID號/f

nu-lb-nuc140 RTX 流程 分析(四) CPU模式切換總結

nu-lb-nuc140 RTX 流程 分析(四) 系統啟動的時候: os_set_env 之後: 進入 __asm void SVC_Handler (void) { 之後 進入:任務 #define os_evt_set(evt_flags,task_id

一條指令在cpu中的執行流程(理解CPU組成)

幾乎所有的馮·諾伊曼型計算機的CPU,其工作都可以分為5個階段:取指令、指令譯碼、執行指令、訪存取數、結果寫回。 1.取指令階段 取指令(Instruction Fetch,IF)階段是將一條指令從主存中取到指令暫存器的過程。 程式計數器PC中的數值,用來指示當前指令在主存中的位置。當一條指令被取出後,PC

復旦微電子CPU卡髮卡流程

前言 指令列表 髮卡 卡片擦除 目錄檔案及使用者金鑰的建立及寫入 命令報文資料域 指令集列表 指令集說明 資料(二進位制資料

CPU卡校驗MAC1、計算MAC2、校驗TAC的方式及流程

前言 mac1驗證、mac2計算、tac驗證流程 執行結果如下 涉及的幫助類

Caffe-windows筆記(一)——windows(64位)+VS2013下的Caffe(CPU Only)安裝流程

一、環境準備 windows 7 64位(非必須) visual studio 2013(推薦此版本) 筆者使用的作業系統為win7 64位,在其他版本的64位windows系統上應該同樣可行。 visual studio 2013(以下簡稱vs2013)中需要安裝NuGet,安

一條指令在cpu中的執行流程

幾乎所有的馮·諾伊曼型計算機的CPU,其工作都可以分為5個階段:取指令、指令譯碼、執行指令、訪存取數、結果寫回。 1.取指令階段 取指令(Instruction Fetch,IF)階段是將一條指令從主存中取到指令暫存器的過程。 程式計數器PC中的數值,用來指示當前指令在主存中的位置。當一條指令被取出

網站需要備案?對這個流程表示呵呵噠- -快速免備案方法

支持 content lang order borde 惡心 doc 適合 src 對於備案流程,惡心到我了??即將完成的時候,發現真尼瑪麻煩!!!!!菜鳥還沒工作不舍得買好服務器,還是等以後穩定了再備案吧~~ 僅僅適合用於個人網站,且對於搜索引擎不友好,本人主要用於快速訪

SpringMVC請求流程

響應 bsp logs -1 wid 執行 map resp resolve Spring結構圖 SpringMVC請求流程圖 SpringMVC請求流程圖語述: request--->DispatcherServler(中央調度器/前端控制器)--

(轉)web開發流程

ctu 圖片 hit 處理 隨著 使用 一個bug 原型開發 href a、項目經理與公司決策層的溝通,以確定這個需求有沒有足夠的人手和可行性去實現,以及與現有產品的依存關系。  b、公司決策層與市場/策劃部門的交流,這個過程將進行的相當充分,並且是反復、長期的,它致力於

在阿裏雲申請Symantec免費SSL證書操作流程

詳細 二級域名 tle 文件 http aliyun 一段 dns 服務 2016年阿裏雲與國內證書頒發機構天威誠信推出了基於Symantec(賽門鐵克)的免費SSL證書,有需要免費SSL證書產品的可以前往阿裏雲進行申請。 申請地址:阿裏雲雲盾證書服務—Symantec免費

LaTeX-手動安裝宏包(package)以及生成幫助文檔的整套流程

tor hang width 下載地址 ner file href win 7 blog 我使用的是ctex套裝,本來已經自帶了許多package,但是有時候還是需要使用一些沒有預裝的宏包,這時就需要自己安裝package了。下載package可以從CTAN(Compreh

十六.監控系統cpu.內存,磁盤等,自動報警,發送郵件

subject sub percent tmp 工具 exc sendmai join pri 發送郵箱小工具,將它放在#/usr/bin/mail chmod +x /usr/bin/mail #!/usr/bin/python #-*- coding: UTF-8 -

yii開發第一部分之執行流程

soap active def 情況 bug 控制 actions 時也 哈希 一 目錄文件 |-framework 框架核心庫 |--base 底層類庫文件夾,包含CApplication(應用類,負責全局的用戶請求處理,它管理的應用

使用performance monitor 查看 每一個cpu core的cpu time

images cor 使用 man 100% cnblogs tor for img 使用performance monitor 查看 每一個cpu core的cpu time: 打開performance monitor,添加 counter 如下

win7下編譯Microsoft版的caffe包的MATLAB接口(CPU模式)

第三方庫 blank res tps setting 後綴名 www .exe 系統路徑 本博客是基於http://www.cnblogs.com/njust-ycc/p/5776286.html這篇博客修改的,做出了更正與補充。 本人機器的環境:Win7+MATLAB2