# fb_0413 :::success 可以搭配參考 [2025-04-15 問答簡記](https://hackmd.io/V7bD2XjnQuCZqDMt4ZizGA#EricccTaiwan) ::: > 目前的主要參考資料 〈[Linux Kernel Development](https://www.doc-developpement-durable.org/file/Projets-informatiques/cours-&-manuels-informatiques/Linux/Linux%20Kernel%20Development,%203rd%20Edition.pdf)〉v2.6 (許多 API 已過時) 和 [Interrupts and Interrupt Handling](https://0xax.gitbooks.io/linux-insides/content/Interrupts/) 近日我與帥潮繼寬同學一同討論 Linux2025 核心實作第三份作業(kxo),在理解程式碼的過程中遇到不少疑問,查閱資料後仍有許多不解之處。在老師的建議下,發文向各位大神與同學們請益,相關問題整理如下,並附上連結供參考,謝謝大家! 1. top 與 bottom 的差異是否僅在於「是否屏蔽其他中斷」? 還是 top 和 bot half 是一種「功能導向」的概念性區分(僅是一種抽象的概念)? > 原本以為是透過「是否會屏蔽中斷」來區分 top half 和 bottom half,例如 top half 會屏蔽 (Hard IRQ)、bottom half 則不會。不過在閱讀 tasklet_action() 的時候注意到它其實也會使用 local_irq_save() 去關中斷 (繼寬發現的),而根據 〈LKMPG〉 與 〈Linux Kernel Development〉 兩本書,tasklet 又明確被歸類為 bottom half 的一種。 這樣一來,是否就推翻了「以是否屏蔽中斷」作為 top/bottom 劃分依據的說法? 另外我在這兩本書中也沒有找到關於 top/bottom half 劃分的明確定義 2. 若 top half 與 bottom half 並非僅為抽象概念,在 top half 與 bottom half 各自內部,是否還能依照具體功能再細分出自己的「top / bottom」結構呢? 3. 討論如何區分兩者(top / bottom half)是否有意義? 4. tasklet 和 workqueue 的具體差異為何? 它們在 interrupt context 中的角色與行為如何區分? 5. 如何判斷目前執行環境是否處於 interrupt context? 是透過下方的 MARCO 嘛? [include/linux/preempt.h](https://elixir.bootlin.com/linux/v6.13.7/source/include/linux/preempt.h#L141) ```c /* * The following macros are deprecated and should not be used in new code: * in_irq() - Obsolete version of in_hardirq() * in_softirq() - We have BH disabled, or are processing softirqs * in_interrupt() - We're in NMI,IRQ,SoftIRQ context or have BH disabled */ #define in_irq() (hardirq_count()) #define in_softirq() (softirq_count()) #define in_interrupt() (irq_count()) ``` 6. Interrupt context 與 process context 有哪些具體差異?為何在設計上需要明確區分這兩者? 書中提到 interrupt handler 執行時的場景就稱為 Interrupt context ,程式處於該場景無法進入 sleeping state, 但為何要這樣? 此外書中強調 Interrupt context 又稱 Atomic context, 在 workqueue 與 tasklet 的比較中也能看到 tasklet 相較與 workqueue 具有 atomic 的特性: >This means that workqueue functions must not be atomic as tasklet functions. "Atomic" 在中斷處理中的意義為何? # 已經解決 0. 在閱讀 [Interrupts and Interrupt Handling. Part 9.](https://0xax.gitbooks.io/linux-insides/content/Interrupts/linux-interrupts-9.html) 時,不理解為什麼會說把 tasklets 存放在 `tasklet_vec` 和 `tasklet_hi_vec` 的 "Array" 中,這兩者的資料結構不應該是鏈結串列? > Tasklets and high-priority tasklets are stored in the `tasklet_vec` and `tasklet_hi_vec` arrays, respectively 經過**帥潮繼寬**的查證,`tasklet_vec` 和 `tasklet_hi_vec` 都是鏈結串列(It's the head of the linked list in fact),目前也以著手提交 patch 修正! [Fix incorrect description of tasklet #861](https://github.com/0xAX/linux-insides/pull/861),已被 merge ,恨帥潮。 0. 乘上,透過 `tasklet_vec.tail` 推斷 `tasklet_vec` 是鏈結串列,但卻找不到此結構體的定義 該段落末段提到: >These two per-cpu variables defined in the same source code file as the softirq_init function and represent two `tasklet_head` structures. 因此該變數的結構應該是 `struct tasklet_head` 沒錯 ```c struct tasklet_head { struct tasklet_struct *head; struct tasklet_struct **tail; }; ``` 但問題來了,要如何儲存 tasklets ? -> 就是個平凡的 linked list, 但我不知道為何要儲存「指向最後一個元素」的指標? 只有 head 會怎樣? ```c struct tasklet_struct { struct tasklet_struct *next; unsigned long state; atomic_t count; void (*func)(unsigned long); unsigned long data; }; ``` 所以 tasklet_struct 的 \*func 會用來除存 handler 的指標 --- ~~0414: 謝謝仁廷學長的回覆,我禮拜一晚上前會看完並回覆,謝謝!~~
×
Sign in
Email
Password
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