0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

BPF為內核編程提供了一個新的參考模型

Linux閱碼場 ? 來源:Linux閱碼場 ? 作者:Linux閱碼場 ? 2022-10-19 11:27 ? 次閱讀

無論好壞,C語言已經是內核開發(fā)領域的通用語言了。Linux 內核的核心邏輯完全是用 C 語言編寫的(加上一點匯編),它的驅動程序和 module 也是如此。雖然 C 語言因其強大而簡單的語義而受到贊譽,但它是一種古老的語言,缺乏現(xiàn)代語言(如 Rust)中的許多特性。另一方面,BPF 子系統(tǒng)也提供了一個編程環(huán)境,工程師能夠編寫可以在內核空間安全運行的程序。在愛爾蘭都柏林舉行的 2022 年 Linux Plumbers Conference 上,Alexei Starovoitov 概述了 BPF 多年來的發(fā)展,為內核編程提供了一個新的參考模型。

BPF的使命

Starovoitov 首先描述了他對 BPF 的 "mission statement, 使命宣言":"創(chuàng)新、并啟發(fā)大家創(chuàng)新"。內核中的編程歷來是在兩種情況下進行的:

core kernel 開發(fā),包括主要的核心子系統(tǒng),如內存管理、調度器、read-copy-update,等等。

kernel-module 開發(fā),指的是構建那些不被編譯到 main kernel image 里的內容,由 module loader 在后續(xù)加載。例如,驅動程序被寫成一些內核 module,也有其他功能是這么做的,如文件系統(tǒng)、網絡協(xié)議等等。

這是內核在很長一段時間內的狀態(tài),直到 3.15 版的內核中加入了最早版本的 extended BPF(eBPF)虛擬機。有了它之后,BPF program 可以用一個受到嚴格限制的 C 語言來編寫,并被編譯成 BPF 字節(jié)碼,這將允許用戶編寫的代碼可以經過驗證確保安全,然后再在內核空間運行。

從那時起,BPF 在代碼的規(guī)模、用戶及貢獻者社區(qū)的規(guī)模方面都穩(wěn)步增長。根據 Starovoitov 的說法,BPF 郵件列表上每天都會收到 50-70 條信息,每月大約收到 2000 封郵件。平均每月里活躍貢獻的 BPF 貢獻者的數(shù)量也在同步增長,截至 2022 年 9 月,已達到約 140 人。目前來說,對 BPF 子系統(tǒng)的大部分貢獻都不是來自 Meta BPF 小組了。

BPF編程環(huán)境

雖然大多數(shù) BPF 程序是用 C 語言編寫的,并用 LLVM Clang 編譯器編譯,但 BPF program 只是二進制 BPF 字節(jié)碼對象文件,并未規(guī)定要用某種特定的語言來寫。比如說,BPF 程序可以使用 Aya 來采用 Rust 編寫,甚至可以直接用 BPF 匯編語言編寫。也就是說,C是 BPF 程序的典型(canonical)編程語言;Starovoitov 的演講繼續(xù)概述了 BPF program 開發(fā)中 C 編程環(huán)境是如何演進的。

這個新的編程環(huán)境混合使用了 C 語言擴展以及運行時環(huán)境的組合實現(xiàn)的,這個運行時環(huán)境包含了 Clang、用戶空間的 BPF 加載器庫(libbpf)和內核中的 BPF 子系統(tǒng)。要想創(chuàng)建一個 BPF 程序,用戶只要用 C 語言寫一個程序,由 Clang 的 backend 實現(xiàn)來轉換成 BPF 指令。在運行程序時,libbpf 將 BPF 程序加載到內存中,對程序進行重定位以使其可以跨平臺以及不同的內核版本從而具備良好的可移植性,然后調用 kernel 來加載程序。最后在內核中,verifier 會采用靜態(tài)方式驗證該程序是否可以安全運行,然后啟用之。

然而,BPF 的編程環(huán)境并不是一上來就這么豐富的。在 BPF 的早期,程序被要求使用 Starovoitov 所說的 "restricted C"。BPF 程序中的所有函數(shù)都必須完全是 inline 的,loop 循環(huán)、靜態(tài)變量和全局變量以及內存分配都是不允許的。也沒有類型信息(type information),所以 BPF 程序只能接收單一的、固定的 input context,用于 tracing 以及 network-filtering 相關功能。

盡管在這樣一個高度限制性的環(huán)境中編寫 BPF 程序也是很有用的,但很明顯, BPF 所支持的使用場景還可以得到很大的擴展。其中一個擴展就是允許在 BPF 程序中使用靜態(tài)函數(shù)。這樣做需要使用 libbpf 在程序加載時對內核 BPF 程序進行重定位。經過多年的設計和嘗試,最終也增加了對有限循環(huán)的支持,此外也支持了 iterator。

Extending the programming environment past full C

雖然這些使得 BPF 更接近于完整的 C 語言了,但最終可以看到,BPF 程序需要的一些功能甚至在完整的 C 語言標準中都沒有。于是 BPF 社區(qū)開始擴展 BPF 編程環(huán)境,從而包括一些傳統(tǒng) C 語言沒有的新特性。其中一個擴展功能就是 "一次編譯-到處運行"(CO-RE, Compile Once - Run Everywhere)。

CO-RE 使 BPF 程序可以在不同的內核版本和平臺上都可以運行。在 BPF 程序中,訪問內核數(shù)據結構是很常見的行為。然而,內核沒有為 struct layer 確保 ABI 不變,因此,如果內核結構在未來的版本或不同的 config 下發(fā)生了變化,在固定偏移的地方對內核結構進行讀取的 BPF 程序可能就會讀到錯誤的值。CO-RE 通過利用運行中的內核中的 BPF 類型格式(BTF)數(shù)據來解決這個問題。在加載一個程序時,libbpf 對所有的 struct 的訪問都會進行重定位,以便根據當前運行的內核的 BTF 信息讓被訪問的字段的偏移量匹配上。

Starovoitov 還描述了 BPF 編程環(huán)境的其他一些有趣的新增功能。其中一個是 kptrs,它允許將內核內存的指針存儲在 BPF map 中。另一個功能是允許程序在加載時訪問內核 config 參數(shù)。內核 module 只能使用編譯時設置的 config 值,但 BPF 程序在加載時可以根據當前內核的配置來決定自己的行為。還有一個特點是 "type tags",可以讓程序能對變量進行 annotation,從而描述它們的使用方式。例如,kptrs 可以用 __kptr 和 __kptr_ref type tags 來進行標注,從而表明它們分別是 unreferenced 或者 referenced kptr。當然指針也可以用 __user 或 __percpu 標準,來告訴編譯器和 verifier 這個指針分別指向用戶內存或 per-CPU 內存。

Plans for the future

目前正在設計和實現(xiàn)更多的擴展,包括 lock-correctness 正確性驗證,以及支持 BPF 程序包含 assertion。lock 的驗證乍一看似乎是一個很難解決的問題,而 Dave Marchevsky 和 Kumar Kartikeya Dwivedi 都已經發(fā)出了 RFC patch set 來實現(xiàn)用于 lock 驗證的新 map type。Marchevsky 的 patch set 提出了一個新的紅黑樹 map type,而 Dwivedi 的 patch set 提出了一個 list map type。這兩個 patch set 都實現(xiàn)了共同的效果,允許 BPF 程序執(zhí)行由 verifier 檢查和驗證過的 locking 機制。

assertion 驗證仍處于規(guī)劃階段,實現(xiàn)起來可能會很復雜。assertion 將作為給編譯器和 verifier 的信號,assertion 被用來指示程序中的一些不變的因素,這些不變因素的失敗將導致程序中止。Starovoitov 聲稱,弄清如何讓程序中止,這會是一個 "有趣" 的問題,因為它需要安全地對堆棧進行 unwind,調用 kptr destructor,以及其他收尾工作。

Starovoitov 在演講的最后分享了他對 BPF 未來的觀點:會取代內核模塊成為擴展內核的有效方式。早期版本的 BPF 程序看起來更像是帶有固定的 BPF helper function 和固定的 map type 的用戶空間程序,而如今新的 BPF 已經可以讓用戶在更多個性化使用場景下對內核進行擴展。事實上,這樣的使用場景已經在 upstream 社區(qū)被提出來了。在 Starovoitov 之后在 LPC 發(fā)言的 Benjamin Tissoires,一直在開發(fā)一個 patch set,希望用 BPF 程序來 fix 人類輸入設備(HID)的 quirk。到目前為止,還沒有一個內核 module 被 BPF 程序完全取代掉,不過,很期待看到內核的其他一些功能可以在 BPF 程序中實現(xiàn)。

一位聽眾要求了解 Starovoitov 所提到的 lock-correctness 驗證的更多細節(jié)。Starovoitov 說,這個工作還在進行當中,但他樂觀地認為可以找到一種方法來進行 static lock checking,從而驗證數(shù)據保護是正確的,并保證不會發(fā)生死鎖。Dave Miller 回應說,如果鎖可以由 verifier 進行靜態(tài)檢查,那么可能可以研究一下 locking 邏輯是否可以由 verifier 自動生成。Starovoitov 回答說,這就是他們希望實現(xiàn)的目標,目前的設計中將 lock 和受保護的數(shù)據在同一次 allocation 中放在一起。對于不能跟 lock 放在一起的數(shù)據,可以用 BTF type tag 來指定它需要明確進行鎖保護。

審核編輯 :李倩

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • C語言
    +關注

    關注

    180

    文章

    7575

    瀏覽量

    134041
  • 編程
    +關注

    關注

    88

    文章

    3521

    瀏覽量

    93266
  • 驅動程序
    +關注

    關注

    19

    文章

    798

    瀏覽量

    47773
  • BPF
    BPF
    +關注

    關注

    0

    文章

    24

    瀏覽量

    3926

原文標題:LWN:讓BPF成為一個更安全的內核編程環(huán)境!

文章出處:【微信號:LinuxDev,微信公眾號:Linux閱碼場】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    NVIDIA助力提供多樣、靈活的模型選擇

    在本案例中,Dify 以模型中立以及開源生態(tài)的優(yōu)勢,廣大 AI 創(chuàng)新者提供豐富的模型選擇。其集成的 NVIDIAAPI Catalog、NVIDIA NIM和Triton 推理服務器
    的頭像 發(fā)表于 09-09 09:19 ?314次閱讀

    為了學習內核開發(fā),大佬手搓輕量級操作系統(tǒng)YiYiYa OS

    一小個模塊都提供基本的功能。按各自的職責劃分,分別對應與傳統(tǒng)內核層則為核心領域業(yè)務。每一小個模塊都提供基本的功能。按各自的職責劃分,分別對應
    發(fā)表于 08-30 14:57

    為了學習內核開發(fā),大佬手搓輕量級操作系統(tǒng)YiYiYa OS

    對應與傳統(tǒng)內核層則為核心領域業(yè)務。每一小個模塊都提供基本的功能。按各自的職責劃分,分別對應與傳統(tǒng)操作系統(tǒng)的內存管理、進程通信、文件系統(tǒng)、進程通信、等等。在演進操作系統(tǒng)時候,可以修改這里,對應源碼目錄
    發(fā)表于 08-27 10:08

    Stack Overflow與OpenAI簽訂協(xié)議模型提供數(shù)據

    OpenAI與知名的軟件開發(fā)者問答論壇Stack Overflow達成了重要合作,旨在提升生成式人工智能模型編程領域的性能。根據雙方周宣布的合作協(xié)議,OpenAI將利用Stack Overflow的豐富數(shù)據資源,不斷優(yōu)化其人
    的頭像 發(fā)表于 05-09 09:25 ?281次閱讀

    【大語言模型:原理與工程實踐】大語言模型的應用

    輸出的關鍵詞或短語。對于任何輸入,大語言模型都會根據提示詞提供相應的輸出。例如,“天空是”就是提示詞,引導模型輸出關于天空的描述。提示詞
    發(fā)表于 05-07 17:21

    【大語言模型:原理與工程實踐】探索《大語言模型原理與工程實踐》

    的未來發(fā)展方向進行了展望,包括跨領域、跨模態(tài)和自動提示生成能力方向,讀者提供對未來技術發(fā)展的深刻見解?!洞笳Z言模型原理與工程實踐》是
    發(fā)表于 04-30 15:35

    谷歌發(fā)布用于輔助編程的代碼大模型CodeGemma

    谷歌發(fā)布用于輔助編程的代碼大模型 CodeGemma。CodeGemma 基于谷歌今年 2 月發(fā)布的輕量級開源大模型 Gemma,針對 Gemma 的兩
    的頭像 發(fā)表于 04-17 16:07 ?532次閱讀
    谷歌發(fā)布用于輔助<b class='flag-5'>編程</b>的代碼大<b class='flag-5'>模型</b>CodeGemma

    使用iLD API對TC357進行編程,如何將其兩ADC內核配置同時連續(xù)地采樣?

    使用 iLD API 對 TC357 進行編程,如何將其兩 ADC 內核配置同時連續(xù)地對以下兩通道進行采樣: AN2 (EVADC_
    發(fā)表于 01-18 07:12

    AI引擎內核與計算圖編程指南

    電子發(fā)燒友網站提供《AI引擎內核與計算圖編程指南.pdf》資料免費下載
    發(fā)表于 01-03 10:50 ?0次下載
    AI引擎<b class='flag-5'>內核</b>與計算圖<b class='flag-5'>編程</b>指南

    LabVIEW進行癌癥預測模型研究

    ,然后將得到的特征向量輸入到SVM中進行分類。 LabVIEW是種視覺編程語言,與傳統(tǒng)的文本編程語言不同,更適合于進行復雜數(shù)據分析和預測模型的開發(fā)。 LabVIEW使用數(shù)據流
    發(fā)表于 12-13 19:04

    如何從簡單的數(shù)學表達式創(chuàng)建Saber模型?

    如何從簡單的數(shù)學表達式創(chuàng)建Saber模型,將你的輸出描述輸入的函數(shù)?例如 out=a*
    的頭像 發(fā)表于 12-05 13:42 ?599次閱讀
    如何從<b class='flag-5'>一</b><b class='flag-5'>個</b>簡單的數(shù)學表達式創(chuàng)建<b class='flag-5'>一</b><b class='flag-5'>個</b>Saber<b class='flag-5'>模型</b>?

    NVIDIA 部分大型亞馬遜 Titan 基礎模型提供訓練支持

    本文將介紹亞馬遜如何使用 NVIDIA NeMo 框架、GPU 以及亞馬遜云科技的 EFA 來訓練其 最大的新代大語言模型(LLM)。 大語言模型切都很龐大——巨型
    的頭像 發(fā)表于 11-29 21:15 ?457次閱讀
    NVIDIA <b class='flag-5'>為</b>部分大型亞馬遜 Titan 基礎<b class='flag-5'>模型</b><b class='flag-5'>提供</b>訓練支持

    DDSROS的通信系統(tǒng)提供哪些特性

    質量服務策略QoS DDSROS的通信系統(tǒng)提供哪些特性呢?我們通過這個通信模型圖來看下。 DDS中的基本結構是Domain,Domain將各個應用程序綁定在
    的頭像 發(fā)表于 11-24 17:59 ?582次閱讀
    DDS<b class='flag-5'>為</b>ROS的通信系統(tǒng)<b class='flag-5'>提供</b><b class='flag-5'>了</b>哪些特性

    內核觀測技術BPF詳解

    補丁和不斷完善代碼,BPF程序變成了更通用的執(zhí)行引擎,可以完成多種任務。簡單來說,BPF提供
    的頭像 發(fā)表于 11-10 10:34 ?1036次閱讀

    內核模塊知識:多個源文件編譯生成內核模塊

    多個源文件編譯生成內核模塊 例如,將hello.c和world.c兩c文件編譯生成叫h
    的頭像 發(fā)表于 09-26 16:58 ?757次閱讀