黑品
    • Create new note
    • Create a note from template
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Write
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
    • Invite by email
      Invitee

      This note has no invitees

    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Note Insights
    • Engagement control
    • Transfer ownership
    • Delete this note
    • Save as template
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Versions and GitHub Sync Note Insights Sharing URL Create Help
Create Create new note Create a note from template
Menu
Options
Engagement control Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Write
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       owned this note    owned this note      
    Published Linked with GitHub
    Subscribed
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    Subscribe
    # 2025q1 Homework5 (assessment) contribute by < `ginsengAttack` > :::danger 注意書寫規範! ::: ## 閱讀〈因為自動飲料機而延畢的那一年〉 作者以解決具體問題出發,試圖製造出自動飲料機,但是問題之所以存在,就是因為它暫時沒有解法。 在尋找解方的過程中,一定會遇到很多出發前難以想像的困難,但這也是一個問題值得被解決的證明。 想要獲得回報,就要有相應的付出,從飲料機的每一個細節,再到為了它而延畢,都是一種取捨,一種等價交換。 同時,細節也是決定成敗的關鍵,材質、結構、流速,一切都環環相扣,我在初步接觸核心的程式設計後也稍有體悟,程式出錯,系統是真的會壞給你看,溢位、race condition、資源釋放,不真的經歷很難切身的體會這些細節。 ## 目前投入 ktcp 產出不多,但是再不準備期末專題就來不及了,所以暫緩進度。 ## 疑問 KXO這個專案和裝置驅動有關聯性嗎? 在看驅動相關的專案的時候,我發現系統和硬體溝通的方式,也是透過註冊操作,提供上下層通訊的媒介,和 KXO 中核心和使用者層級的互動方式有些相似。 甚至在註冊操作的時候,也是註冊裝置號碼? - [ ] 查過後,發現這個東西叫 Character Device Driver ,也是驅動程式的一種。 ktcp 具體在什麼部份會需要進行 IO 的處理? - [ ] 接收連線,傳輸數據都是 如何在 ktcp 中更好的應用驅動程式相關知識? ktcp 可以運行在樹莓派上面嗎? 根據 [linux 核心網路:第一章](https://hackmd.io/@rickywu0421/linux_networking_1) ![圖片](https://hackmd.io/_uploads/r1N_qTLGex.png) 傳遞一個封包需要層層遞進的系統呼叫,老師在上課的時候提到, ktcp 直接使用 `kernel_recvmsg` 和 `kernel_sendmsg` 在核心層級發收資料,但為什麼不使用更下層的系統呼叫? 這段描述是我的理解,這樣理解有錯嗎? > 原本架構 CPU 和 thread 綁定,並且一組 thread 為一個 workqueue。CMWQ 一樣 CPU 和 thread 綁定,但是 workqueue 變成更上層的概念,我們定義的 workitem 不再嚴格對應到具體某個 CPU 上面的某個 thread。 ## 期末專題 ktcp 筆記 (紀錄一下讀教材遇到的問題,然後都先讀老師的材料,比較好吸收) (純筆記,實做放在另一個頁面) ### I/O 模型演化: 事件驅動伺服器:原理和實例 [連結](https://hackmd.io/@sysprog/linux-io-model/https%3A%2F%2Fhackmd.io%2F%40sysprog%2Fevent-driven-server) #### I/O 模型概述 雙工分為兩種: 全雙工 和 半雙工 半雙工就是允許雙向通訊,但是同時只有一方可以進行傳輸,像對講機一樣。 後來引入了 `select` 系統呼叫,能一次監控多個檔案描述子, 'kxo' 就使用了這種技術,同時去監聽鍵盤事件和來自核心的資料,這邊的監聽是"通知哪個檔案有資料",後續我們再自行讀取。 #### Non-blocking I/O 這邊提到可以透過將檔案描述子設置為 `O_NONBLOCK` 來實現非阻塞。 同時提到 lwan 也是採用這種技術,但是我實際上在自己的電腦上實驗的時候,發現我採用這種方法,會致使程式碼以 busy waitting 的方式運行,而如果是採用阻塞式的就不會有這個問題? #### I/O Multiplexing 這種機制就是透過 `epoll`、`select`一類 api 去做出事件監聽,本身是阻塞式的,我們可以透過回傳值來判定具體是哪一個檔案子有資料傳入。 但是以 ktcp 的架構,貌似不適合這種結構?還是可以用這個機制,一次監聽多個 port? 原來是一次監聽多種類型的操作。 然後我還想問, `accept` 算不算一種 `select` 的機制? #### Asynchronous I/O 難以理解,這部份是必須作業系統支援? #### 綜合解讀 第一次看不太懂,稍微研究過 ktcp 後回來看這個例子說明,很具體。 #### 事件驅動式伺服器 簡單來說,就是將連線處理和實際服務分開,由一個 thread 去負責接收連線,反應到 ktcp 裡面就是背景程式,實際服務則由其他的thread 提供。 #### 案例探討:NGINX 由 master 行程負責初始化任務,worker 則專門處理用戶端請求,比較特別的是它會將每個 worker 固定綁定至特定 CPU。 kxo 裡面也有類似的機制,印象中是透過禁用中斷達成的,今天上課有提到,但是我沒有聽到最後,之後會查看同學筆記來確認。 然後會用 `epoll` 去監聽不同種類的事件,是後面會提到的 Reactor Pattern 架構。 #### Thread Pool 透過將工作交由 thread 執行,以作業系統的輔助提高同步能力,由一個thread loop 做為 consumer ,變相達成一種 aio。 ### I/O 模型演化: 高效 Web 伺服器開發 #### TCP 伺服器的實作挑戰 一般的 tcp 伺服器,會先監聽某個 port ,等待連線,然後有連線進入就讀取該 fd 的資料,`tcp echo` 就是如此, 但是這種程式碼構造簡單,直接回傳訊息即可,如果是建立在其上的 web 伺服器,就必須要有解析 HTTP 的和處理通訊協定的功能,這種結構就沒有辦法負荷多個請求的同時處理。 有一種方法是 fork,讓子行程去運行,親代行程繼續監聽連線。可是這意味著每個連線都會需要一個完整的行程,花費大量的資源,就算引入 thread 機制也不會有太大的不同,資源的使用一樣很高。 所以可以引入 thread pool,後面會提到的 CMWQ 就是採用這個機制。 可是執行緒的數量也有上限,同樣會在過多連線的情況下遇到無法滿足並行的困境。 這個問題的根源是 read 為阻塞式, 這邊我看不懂,是指用事件驅動可以克服這個問題? 但是根據: > 若進一步增加廚房人手(類比為 thread pool 中的 worker thread),即可提升同時處理訂單的能力(throughput)。但當工作人員數量持續增加,瓶頸會轉移至實體空間、烤箱數量等資源限制(即系統容量)。 這種模型不是也有上限嗎? #### Reactor Pattern Reactor pattern 是個設計模式 (design pattern),針對同時處理多個或單個服務需求。服務處理任務 (service handler) 將傳入的需求拆解,然後分派給相關的請求端處理任務 (request handler)。 #### Edge vs. Level Triggering 一個是電位改變時觸發,一個是處於某個電位就一直觸發。 分別對應到對資料處理流程的不同處理,`select` 和 `poll` ,要自行將資料讀取完成,所以有資料就要一直讀,但是 `Asynchronous I/O` 則是將資料交給作業系統處理,所以觸發一次就好。 #### 實做考量點 :question: 將 fd 設定為 non-blocking 後... :這個問題我不懂,我能理解 tcp 傳輸可能會切分封包,讓上層的資料被分段傳輸,可是這一定要用狀態機模式的解析器才可以解決嗎?老師的其中一項要求是將解析器換成更加輕量的解析器,不就又會遇到這個問題嗎? ### I/O uring 無法理解,還要花時間再看 ### 透過 timerfd 處理週期性任務 #### timerfd 把 timer 當成 file descriptor,這樣就可以透過上述的 I/O Multiplexor 去監聽。 之前提到伺服器可以透過 `epoll` 去監聽不同的事件,這就是其中一種,可以用一致的邏輯去處理。 但是我看 ktcp 的教材,它好像不是用這種方法,而是維護一個 queue 來處理所有連線的 timer? ### kecho/khttpd ### 程式碼導讀: #### 減少 printk 的使用 這個 `pr_info` 會對效能產生影響,甚至印出太多還會塞滿記憶體,教材建議以統計的方式,最後一次印出。 #### HTTP keep-alive 模式 這個伺服器是自行解析 http 請求,實際上下層依賴 tcp 建立連線,然後tcp 建立連線的時候需要三路交握,是一個比較大的開銷,使用 keep-alive 機制就能透過 persistent connection 的方式維持一個 tcp 的連線,而不是每次重新進行交握。 #### Linux 核心如何處理傳遞到核心模組的參數 使用 `module_param` 巨集傳遞參數,但是為什麼不用字節驅動? 這邊不太理解,還要再看。 ### Ktcp #### CMWQ workqueue 是一種機制,使用者將預要執行的工作項目包裝成結構體,並交由核心進行處理。 原有的 MT workqueue 會為每個 CPU 配置一個 worker thread,讓工作在複數個處理器上執行,可是一來,多個 CPU 可能會連帶導致大量的 worker thread 耗盡 PID。 (這邊我有個疑問,教材的描述是:"若建立 100 個 workqueue 且系統有 64 個 CPU,就會產生多達 6400 條 worker threads。",但這個架構有那麼不彈性嗎?我不能每個 CPU 數量不同?) 而且 worker thread 綁定單一 CPU,且各 CPU 間的 worker 無法共享工作項目。 所以引入 CMWQ,捨棄每個 workqueue 綁定一組 worker threads 的設計,改為所有 workqueue 共享一組 per-CPU worker pool,然後動態併發控制:CMWQ 內部根據工作負載與系統狀態,自動調整 worker threads 的並行程度與綁定,避免資源浪費。 有三個元素: 1. workqueue 2. worker pool:由核心維護的 worker thread 池,每個 CPU 有一組對應的 pool 3. worker 我的理解是: 原本架構 CPU 和 thread 綁定,並且一組 thread 為一個 workqueue。 CMWQ 一樣 CPU 和 thread 綁定,但是 workqueue 變成更上層的概念,我們定義的 workitem 不再嚴格對應到具體某個 CPU 上面的某個 thread。 :::danger 注意用語! ::: 這個方法讓核心幫我們動態的管理執行緒的<s>調用</s>,對應到 ktcp 中,就是把 `kthread_run` 取代,讓我們不用每次為了處理新的連線就要創建一個新的 thread ,而且除了基本的記憶體配置與 kthread 結構,idle 狀態下的 worker thread 並不會額外耗用系統資源。 #### 使用 Ftrace 觀察 kHTTPd 按照教材要求,輸入: ```c sudo ls /sys/kernel/debug/tracing //獲得: available_events options stack_trace_filter available_filter_functions osnoise synthetic_events available_filter_functions_addrs per_cpu timestamp_mode ... ``` 然後接著輸入: ```c sudo cat /sys/kernel/debug/tracing/available_filter_functions | grep khttpd ``` 然後我一開始還沒有打 `/sys/kernel/debug/tracing/` 然後想說我的電腦有問題,有點蠢。 然後我將輸入改為: ```c # clear echo 0 | sudo tee $TRACE_DIR/tracing_on sudo truncate -s 0 $TRACE_DIR/set_graph_function # 明確清空文件 sudo truncate -s 0 $TRACE_DIR/set_ftrace_filter # 明確清空文件 echo nop | sudo tee $TRACE_DIR/current_tracer # setting echo function_graph | sudo tee $TRACE_DIR/current_tracer echo 3 | sudo tee $TRACE_DIR/max_graph_depth echo http_server_worker | sudo tee $TRACE_DIR/set_graph_function # execute echo 1 | sudo tee $TRACE_DIR/tracing_on ./htstress localhost:8081 -n 2000 echo 0 | sudo tee $TRACE_DIR/tracing_on ``` 然後最終:`sudo cat /sys/kernel/debug/tracing/trace` `http_parser_execute()` 為效能瓶頸,該函式採用狀態機模型,針對輸入資料 buf 進行逐字元處理,其實後面破梗了,可以用更輕量化的函式庫來實現,例如 `picohttpparser`。 #### 實作 content cache `iterate_dir()` 是另一個效能瓶頸,它會走訪檔案目錄裡面所有檔案,即使我只放一個檔案,他的影響也很大,遑論更大的目錄。 教材的方法很直觀,既然我們必須傳目錄資料,但是走訪又很花時間,那就先將常用資料緩存,說起來簡單,但是做起來很難。 具體實做之後跟著一起做。 #### scatter-gather I/O 傳送資料 可以提高吞吐量,一次把多個 buf 的資料傳出,就不用每傳一段資料,就要一次系統呼叫。 這個我還沒寫,也沒辦法測。 #### 支援 HTTP 壓縮 降低傳輸開銷,Linux 核心就有提供壓縮 API將檔案內容經壓縮後透過 HTTP 回應傳送給客戶端,藉此達成減少網路傳輸負擔與提升效能的目的。 這個我自己實做過,但是要注意,非純文字檔案例如圖檔,會被壓壞。 #### 引入 timer 以主動關閉逾期的連線 為何不用前述的 `timerfd` 搭配 `epoll` 機制? #### 藉由 RCU 在並行環境中釋放系統資源 在針對效能的分析中,讀取檔案的操作佔用了大量的時間,所以可以通過 cache 的機制降低這方面的成本。 這個所謂的 content cache 讀多寫少,主要是用來應付來自網路中的請求,少數時候需要更改內容,所以使用普遍的 lock 不現實,卻是使用 RCU 的理想環境。 這個機制會使用 `rcu_read_lock` 和 `rcu_read_unlock` 保護讀取操作,但不同的是,他不會禁止其他人進行存取。 這個特別的鎖,搭配相應的存取操作,能保證資料在讀的資料不會受到破壞,但是新的讀取操作又能讀取到更新後的資料。 最後透過 `synchronize_rcu()` 產生一段 grace period 也就是寬限期,讓舊資料的刪除操作延後到所有正在讀取者結束讀取。 像是清潔廁所一樣,放一個"清潔中"的牌子到廁所外面,後來的去其他廁所,但是已經在裡面的人也不會被趕走,直到所有人使用完才真的開始清潔。 ## 期末專題想法 我想要聚焦在韌體跟驅動程式,最好是和電腦網路相關的領域。 之所以會選擇裝置驅動這個主題,是因為老師上課的時候提過,在台灣學 linux 往往會去寫 device driver ,並且很多優秀人才是不屑寫這個的,這是一個值得把握的機會。 ### 開發 vETH 驅動程式 :::danger 注意書寫規範:中英文間用一個半形空白字元區隔 ::: 參考[ vwifi 虛擬無線網路裝置驅動程式和實驗環境](https://hackmd.io/@rickywu0421/FinalProject) 此專題撰寫了針對虛擬網路設備的驅動程式,提供模擬無線網路的實驗環境。 :::danger call 是「呼叫」,而非「調用」,尊重你所在的傳統文化 ::: `cfg80211` 是 linux 管理無線網路的框架,會通過<s>調用</s> api 跟下層的設備進行互動,而 vwifi 同樣提供了 api 給 cfg80211 進行使用,並同時模擬了設備的行為。 虛擬的網路設備讓專題的發想有很大的空間,不會受限於硬體。 而我想針對乙太網路的有線環境進行學習,仿照 vwifi 的形式,透過軟體模擬實體網路卡,在虛擬機器之間透過虛擬網卡建立乙太網路環境。 乙太網路不像 wifi 一樣在核心中有專門的子系統,而是透過通用的子系統進行管理,並且比起連線與通訊的議題,更重視封包的傳輸與處理。

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password

    or

    By clicking below, you agree to our terms of service.

    Sign in via Facebook Sign in via Twitter Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully