巫冠君

@Guanchun0803

Joined on Jan 11, 2025

  • 追蹤 suspend 階段 要優化系統的 suspend 和 resume 流程,首先要弄清楚:當我下命令讓電腦休眠時,Linux 內部到底呼叫了哪些函式?了解這整條流程,才能知道從哪裡開始優化。 我首先觀察最簡單的 suspend 模式 — freeze (Suspend-to-Idle)。當我執行下列指令後: echo "freeze" | sudo tee /sys/power/state 系統會開始進行 freeze 流程,首先系統會呼叫 linux/kernel/power/main.c 當中的 state_store() 這個函式,這個函式主要的效果是 根據使用者輸入的字串(如 echo mem > /sys/power/state),決定要讓系統進入哪種 suspend 模式,或是執行休眠(hibernate),並呼叫相對應的核心 API。 static ssize_t state_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t n)
     Like  Bookmark
  • 開發環境 $ gcc --version gcc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0 Copyright (C) 2021 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. $ lscpu Architecture: x86_64 CPU op-mode(s): 32-bit, 64-bit
     Like  Bookmark
  • 這個演講主要探討了優化 suspend/resume 的研究,並強調了它對手錶和手機等設備的重要影響。在一開始,Saravana Kannan 簡單介紹了 suspend/resume 的過程,並將其劃分為以下幾個階段: Suspend: * suspend enter * sync_filesystems * freeze_processes * dpm_prepare * dpm_suspend * dpm_suspend_late * dpm_suspend_noirq
     Like  Bookmark
  • Improvements of async suspend and resume of devices 這個 patch set 改進 Linux 核心中非同步(asynchronous) suspend/resume 的處理機制。 在一般情況下,系統在執行裝置 suspend 或 resume 時,會採用 同步(synchronous)方式,也就是: 同步(sync):每次僅處理一個裝置,必須等前一個裝置 suspend/resume 完成後,才會繼續下一個。 非同步(async):允許多個彼此沒有相依關係的裝置同時進行 suspend/resume,以提升整體處理效率。 這個 patch set 整體設計的核心想法是: 有些裝置即使還沒完全符合所有依賴條件,但只要部分條件已經滿足,就可以提早開始執行非同步 suspend/resume。
     Like  Bookmark
  • dpm_list 的結構與順序設計 在 Linux 核心的裝置電源管理(Device Power Management, DPM)中,dpm_list 是一個核心的全域 linked list,用於追蹤系統中所有需要參與 suspend/resume 操作的裝置。這個 list 的結構與插入順序,直接影響到 suspend/resume 過程的正確性與執行效率。 根據設計,dpm_list 中的條目是以深度優先順序 Depth-First Order 排列。其原因來自裝置初始化的時序特性:在裝置樹(Device Tree)或裝置模型建立過程中,父裝置會先於子裝置被探測與註冊,而每個裝置註冊進 DPM 系統時(透過 device_pm_add()),都會被插入 dpm_list 的尾端。因此,自然而然形成了「父裝置在前、子裝置在後」的鏈表結構,對應到 suspend 時「子裝置先關、父裝置後關」以及 resume 時「父裝置先開、子裝置後開」的邏輯順序。 void device_pm_add(struct device *dev) { ... device_pm_check_callbacks(dev); mutex_lock(&dpm_list_mtx);
     Like  Bookmark
  • Linux workqueue 如何建立和排程? 為什麼需要 Concurrency Managed Workqueue ? 在 CMWQ 之前的 workqueue 實作中,worker thread 的數量是與被建立的 workqueue 數量直接掛勾的,每個 workqueue 都有自己獨立的 work pool。意味著使用者每建立一個新的 workqueue,系統上的 worker thread 總量便會增加。實作中包含了兩種 worker thread 的建立方式: multi threaded (MT) wq : 在每個 CPU 上會有一個 worker thread,work item 可以分配不同的 CPU 上執行 single threaded (ST) wq : 僅以單一的 worker thread 來完成系統上所有的 work item 在 MT wq 的部份,這代表系統需要建立與 CPU 數量乘上 workqueue 總量等價的 worker thread,這是很嚴重的的問題,但 multi threaded (MT) wq 浪費了大量的資源,但所提供的並行度仍然不是讓人滿意,因為在 MT workqueue 中,每個 CPU核心 上的關於這個 workqueue 只有一個 work thread。這個 work thread 負責處理該核心上分配的所有 work item。換句話說,同一個 workqueue 上的 所有 work items 都需要 依次排隊 由該核心上的線程來處理,這些 work items 會「爭奪」這個核心上唯一的 execution context,從而影響並行度。而 ST wq 是為整個系統提供唯一的 context,因此所有的 work 都是一一排隊執行,造成 concurrency level 不佳,雖然對資源的使用量比較低。 總結:
     Like  Bookmark
  • contributed by < wurrrrrrrrrr > 測驗 1 程式碼運作原理 首先看到 ceil_div 是無條件進位除法: static size_t ceil_div(size_t n, size_t d) { return AAAA; }
     Like  Bookmark
  • contributed by < wurrrrrrrrrr > :::danger 注意書寫規範,重視細節! ::: 閱讀〈因為自動飲料機而延畢的那一年〉的啟發 看完文章後,我印象最深刻的是以下這兩句話:「大多數人一直活在本來就應該這樣嗎的童話世界裡,電視打開就可以看,機車買來就可以騎,手機買來就可以用,一切都理所當然,本來就應該這樣。偶爾買到不好用的商品我們就抱怨幾句,丟掉換其他更好用的牌子,卻很少意識到那個本來就該這樣,背後需要經過多少人月的投入與研發。」以及「你該學習的不是看到事情要完蛋了就去避免失敗,而是應該學習如何處理與承受失敗,你才能變得比以前更強大。」這兩句話讓我深深反思我們對日常事物的理所當然,其實背後藏著無數人的努力與付出,而我們卻常常忽略這些價值。同時,第二句話也提醒我,面對困難與挑戰時,與其一味逃避失敗,不如學會面對與承擔,因為真正的成長往往來自於一次次跌倒後的重新站起。這讓我意識到,改變自己的態度與思維,比逃避問題更為重要,失敗或許很難受但是每一次的失敗都能為自己帶來不一樣的啟發,就像在前六週的生活中,每天都有做不完的事,有實習面試的壓力,也有課業的負擔,一度讓我感到快要撐不下去、只想逃避。但後來我明白,就算真的失敗了也沒關係,重要的是,我在這些經歷中學到了什麼,並因此變得更加堅強。 課後創作
     Like  Bookmark
  • kernel 中的電源管理可以分為以下兩類: Static PM主要處理的是系統長時間處於非活動狀態時如何節省電量 目前沒有主要的開發工作 Dynamic PM 主要處理的是系統處於活動狀態時如何配置系統設備 隨著 soc 的發展這個框架在不斷的發展跟調整
     Like  Bookmark
  • contributed by < wurrrrrrrrrr > 縮減使用者和核心層級的通訊成本 開始改進程式碼之前,深入了解現有的程式碼架構和邏輯是第一步要做的。由作業要求可以看到我的任務是縮減使用者和核心層級的通訊成本,因此,第一步我先檢視了判定勝利的程式碼區段,以了解它如何根據棋盤狀態判斷哪一方獲勝或是否平局。 const line_t lines[4] 這個 lines 陣列定義了四個方向(橫向、縱向、主對角線、副對角線)的檢查規則還有起始位置跟邊界範圍。 char check_win(const char *t) 這段函式主要邏輯是先遍歷所有四個方向,對每個方向的每個可能起點進行檢查,一旦找到連線則返回勝者;若都沒找到,再根據棋盤是否填滿來決定是遊戲未完成還是平局。
     Like  Bookmark
  • contributed by < wurrrrrrrrrr > Reviewed by nyraa 部分 inline code 前後沒有插入空白。 依照規範,在英文單字建議都要插入空白 q_free() 中可以使用對於刪除節點友善的巨集 list_for_each_safe 這個巨集可以刪除當個節點而不影響迭代, q_release_element 這個巨集可以釋放一個節點的記憶體空間。
     Like  Bookmark
  • contributed by < wurrrrrrrrrr > 第一週測驗題 測驗一 一開始先提到以下程式碼運用 "a pointer to a pointer" 技巧,於是我開始思考什麼叫做 "a pointer to a pointer",於是我先閱讀了你所不知道的 C 語言: linked list 和非連續記憶體了解到間接指標的技巧,可以避免動態記憶體配置同時我也看了Linux 核心的 hash table 實作得知了間接指標也能用來消除特例使得程式碼更為優雅,比如說在上述文章中的例子: 探討針對典型雙向鏈結串列進行節點移去時,會產生的問題我們先使用典型的 doubly-linked list: struct dll_node { struct dll_node *next, *prev; }
     Like  Bookmark
  • contributed by < wurrrrrrrrrr > 還政於民的 sched_ext 及機器學習如何幫助 CPU 排程 在研讀過 Linux 核心專題: CPU 排程器 後我得知 Linux 排程器的演化,經歷了$O(n)$ $O(1)$ scheduler, CFS 到現在的 EEVDF。CPU 排程器的設計理念在於提供一種普遍適用的策略,以滿足各種不同的應用需求,但有些使用Linux 的公司來說,當他們的平台只涉及特定工作負載時,通用的排程器可能無法滿足他們的特殊需求,所以要是能自訂排程器的行為,將有機會帶來更多好處。 在閱讀過程中我看到了以下這段話:『開發人員探索在 Linux 中引入「可插拔」排程器的可能性』而要支持這向技術的基礎為 eBPF。 eBPF 不僅支持將程式碼動態加載到核心執行,還提供檢查器以減少程式對作業系統核心的損害風險。這樣一來,開發者便可輕鬆撰寫並植入客製化的 CPU 排程器。 在閱讀這篇文章之前,我一直認為一旦設定好 CPU 排程器後,就只能使用該排程方式,然而「可插拔」排程器的概念顛覆了我的想法,但 eBPF 到底是什麼呢?於是我先閱讀了 eBPF 在這篇文章中我了解到 eBPF 就是 BPF 的擴充,所以如果要如果了解 eBPF 是什麼的話就必須先了解什麼是 BPF 。
     Like  Bookmark
  • 輸入/輸出(I/O)是指在==記憶體與外部設備==之間複製數據的過程。 輸入(Input):將數據從 I/O 設備讀取到主記憶體中。 輸出(Output):將數據從記憶體寫入 I/O 設備。 所有程式語言的 Run-time System 都提供 高階的 I/O 介面 來簡化 I/O 操作。例如: ANSI C 提供標準 I/O 函式庫,包含 printf 和 scanf 等函式,這些函式使用 緩衝 I/O(buffered I/O) 來提高效能。 C++ 提供類似功能,透過 <<(put to)和 >>(get from)運算子 來操作輸入輸出。 在 Unix 系統,這些高階 I/O 函式最終是透過系統核心(Kernel)提供的低階 Unix I/O 函式來實作的。
     Like  Bookmark