1. 程式人生 > 其它 >核心orc-unwinder.txt文件

核心orc-unwinder.txt文件

翻譯核心文件重點部分,難免有誤,請見諒

核心版本4.19.190

 

核心 CONFIG_UNWINDER_ORC 選項啟用 ORC 展開器,它在概念上類似於 DWARF 展開器。 不同的是,ORC 資料的格式比 DWARF 簡單得多,這反過來又使 ORC unwinder 更簡單、更快。

ORC 資料由 objtool 生成的展開表組成.它們包含核心內 ORC 使用的帶外資料開卷機, Objtool 生成ORC 資料通過首次編譯時的(stack metadata validation) (CONFIG_STACK_VALIDATION)。之後分析
所有程式碼路徑的.o 檔案。,它確定有關檔案中每個指令地址的堆疊狀態資訊並輸出這些資訊到.orc_unwind 和 .orc_unwind_ip 段。

每個物件的 ORC 部分在連結時合併,並在引導時進行排序和後續處理。展開器在執行時使用結果資料將指令地址與其堆疊狀態相關聯


ORC vs frame pointers
---------------------

啟用幀指標後,GCC 將檢測程式碼新增到每個核心中的函式。 核心的 .text 大小增加了大約
3.2%,會導致核心範圍的廣泛變緩。 Mel Gorman [1] 的測量表明,某些工作負載的速度降低了 5-10%。

相比之下,ORC unwinder 對文字大小或執行時間沒有影響效能,因為 debuginfo 是帶外的。所以如果你禁用幀指標並啟用 ORC 展開器,您可以獲得全面的效能改進,並且仍然具有可靠的堆疊跟蹤。

Ingo Molnar 說:

“請注意,這不僅是效能改進,也是指令快取區域性性改進:3.2% .text 節省幾乎直接轉換成類似大小的減少快取腳印。 這可以使其快取位置處於臨界狀態的工作負載轉化為更高速率。


與幀指標相比,ORC 的另一個好處是它可以跨中斷和異常可靠地展開。基於幀指標unwinds 有時可以跳過被中斷函式的呼叫者,如果它是葉函式,或者如果在幀指標之前中斷命中儲存。


與幀指標相比,ORC 展開器的主要缺點是它需要更多記憶體來儲存 ORC 展開表:大約 2-4MB取決於核心配置。

ORC vs DWARF
------------


ORC debuginfo 相對於 DWARF 本身的優勢在於它更簡單。它擺脫了複雜的 DWARF CFI 狀態機,也擺脫了跟蹤不必要的暫存器。這允許開卷機更簡單,意味著更少的錯誤,這對於
關鍵任務 oops 程式碼是非常重要的。

更簡單的 debuginfo 格式也使展開器比 DWARF更快,這對於 perf 和 lockdep 很重要,一個基本由 Jiri Slaby [2] 進行的效能測試,ORC 開卷機大約
比樹外 DWARF 展開器快20 倍(注:那個測量是在新增一些效能調整之前做的,這翻了一番效能,因此比DWARF 的速率提高可能接近 40 倍。)

與 DWARF 相比,ORC 資料格式確實有一些缺點。 ORC 展開表比基於 DWARF 的 eh_frame 表佔用的 RAM 多約 50%(在 x86 defconfig 核心上為 +1.3MB)。

另一個潛在的缺點是,隨著 GCC 的發展,這是可以想象的,ORC 資料可能最終會變得*太*簡單地描述堆疊的狀態為了特定的優化。但是 IMO 這不太可能,因為 GCC 會為任何不尋常的堆疊調整儲存幀指標
所以我懷疑我們真的只需要跟蹤呼叫幀之間的堆疊指標和幀指標,但即使我們最終不得不跟蹤 DWARF 跟蹤的所有暫存器,至少我們仍然能夠控制格式,例如 沒有複雜的狀態機。


ORC unwind table generation
---------------------------

ORC 資料由 objtool 生成。 使用現有的編譯時堆疊元資料驗證功能,objtool 已經跟隨了所有程式碼路徑,因此它已經擁有生成 ORC 資料所需的所有資訊。 因此,從堆疊驗證到 ORC 資料生成是一個簡單的步驟。


應該可以用一個簡單將DWARF換為ORC資料的工具的方法來代替生成 ORC 資料,由於核心廣泛使用 asm、內聯 asm 以及異常表等特殊部分,這樣的解決方案將是不完整的

這可以通過手動註釋那些特殊的程式碼路徑來糾正在 .S 檔案中使用 GNU 彙編器的 .cfi 註釋,並自行開發.c 檔案中的內聯 asm 註釋。 但是嘗試了asm註釋在過去並且被發現是不可維護的。 他們經常
不正確/不完整,使程式碼更難閱讀和保持更新。並基於檢視 glibc 程式碼,在 .c 檔案中註釋內聯 asm 可能更糟。

Objtool 仍然需要一些註釋,但只是程式碼中對於堆疊來說不尋常的東西,例如入口程式碼。 即便如此,需要的註釋比 DWARF 需要的少得多,所以它們要比 DWARF CFI 註釋更易於維護。

所以使用 objtool 生成 ORC 資料的好處是提供更準確的除錯資訊,註釋很少。它也是將核心與可能要在核心中處理的非常痛苦的工具鏈錯誤隔離開來,因為我們經常需要解決多年的舊版本工具鏈問題。

缺點是展開器現在變得依賴於 objtool 對 GCC 程式碼流進行逆向工程的能力。如果 GCC 優化變得過於複雜以至於 objtool 無法遵循,ORC 資料生成可能會停止工作或變得不完整。
(值得注意的是,livepatch 已經對 objtool 遵循 GCC 程式碼流的能力有這樣的依賴。)

如果較新版本的 GCC 提出了一些破壞 objtool 的優化,我們可能需要重新審視當前的實現。 一些可能的解決方案是要求 GCC 使優化更容易接受,或者讓 objtool 使用 DWARF 作為附加輸入,或者建立一個 GCC 外掛來幫助 objtool 進行分析。 但就目前而言,objtool 很好地遵循了 GCC 程式碼。


Unwinder implementation details
-------------------------------


Objtool 通過編譯時整合的堆疊元資料驗證功能生成 ORC 資料。詳細描述在工具/objtool/文件/stack-validation.txt。分析全部程式碼路徑的
.o 檔案後。它建立一個 orc_entry 結構陣列,以及與這些結構關聯的指令地址的並行陣列,並將它們分別寫入 .orc_unwind 和 .orc_unwind_ip 段。

出於效能原因,ORC 資料被分成兩個陣列,以使資料的可搜尋部分 (.orc_unwind_ip) 更緊湊。 陣列在引導時並行排序。

通過使用在執行時建立的快速查詢表進一步提高了效能。 快速查詢表將給定地址與 .orc_unwind 表的索引範圍相關聯,因此只需要搜尋表的一小部分。

 

Etymology(詞源)
---------

獸人,中世紀民間傳說中的可怕生物,是矮人天生的敵人,同樣的,ORC 開卷機的建立是為了反對DWARF 的複雜性和緩慢性。

“雖然獸人很少考慮一個問題的多種解決方案,但他們確實 擅長把事情做好,因為它們是行動的生物,而不是思想。” 同樣,與深奧的 DWARF 展開器不同,真實的 ORC 展開器不浪費時間或 siloconic 去解碼
基於狀態機的可變長度零擴充套件無符號整數字節編碼的除錯資訊條目。

類似於獸人經常解開他們的他們的對手的善意計劃。ORC 開卷機經常用殘酷,不屈不撓的效率來解開棧。

ORC 代表Oops的倒帶能力。

[1] https://lkml.kernel.org/r/[email protected]
[2] https://lkml.kernel.org/r/[email protected]
[3] http://dustin.wikidot.com/half-orcs-and-orcs