分享到plurk 分享到twitter 分享到facebook

版本 f2a588854fdd9f3502e93f7112bbc20f8c8c76d6

Andrushika (張宇承)

2025 Linux 核心設計 春季班 自我評量

簡介

成果發表與貢獻

貢獻:

我給自己 7 分。 每當發現缺漏時,我總是相當興奮,因為這代表新的機會;一想到自己的名字會出現在大家都在使用的文件或程式專案的貢獻列表中,就覺得很有成就感。尤其是發 patch 到 barco 的經驗,也是我人生第一次對超過 1000 個 stars 的專案貢獻。但回顧這學期的貢獻經歷,幾乎都是修改錯字之類的小貢獻,這是我覺得自己不足的地方。

作業 / 隨堂測驗

  • 2025q1 Homework1 (lab0)
    • 確實 Reviewed 五位同學的程式碼並給出建議: yy214123, chensheep, Eric-0522, zinsei, dainel40911
    • Linux 核心的 list_head 結構、相關 macro 使用方式(list_entry() 等)
    • 用快慢指標在鏈結串列找中點
    • pointer of pointer 簡化指標處理
    • 以實驗比較自己的實作與 list_sort.c 中的排序演算法效率差異
    • 使用 select() 驅動事件迴圈
    • 用 chi-square test 檢測隨機數函式是否「夠亂」
    • 研讀論文〈Dude, is my code constant time?〉,認識 side channel attack 、以假設檢定監測函式是否為 \(O(1)\)
    • 協助 review 貢獻到 lab0-c 中的 percentile() 實作
  • 2025q1 Homework1 (ideas)
    • 初步認識 CFS, EEVDF,nice 值表示執行緒的禮讓程度
    • CPU affinity 會影響 cache miss rate,在決策是否 migration 時也要考慮進去
    • 認識 hypervisor 的不同種類
  • 2025q1 Homework2 (quiz1+2)
    • 熟悉 linux kernel list API
    • 認識以 bitwise operation 實作 count leading zero 的方式
    • 以數學還原、說明整數開平方根快速運算實作原理(參考維基百科)
    • 將整數開根號函式擴充為 ceil(sqrt(x)) 版本
    • 認識 hlist_head 結構,並進一步尋找 Linux 核心中其他使用本程式碼的地方
  • 2025q1 Homework3 (kxo)
    • 閱讀 LKMPG 前 16 章節,認識 kernel module 的運作機制:/proc filesystem、character device、Interrupt 等等
    • 將 kxo 專案中繪製棋盤的工作移至 user space
    • 開發記錄下棋歷史的機制
    • 認識 top half、bottom half interrupt,以及其 linux kernel 中實作的相關 API(tasklet, softirq, workqueue)
    • dmesg 查看 kernel log
    • 人生第一次體驗「程式沒寫好會搞垮電腦運作」,在撰寫 kxo 時一邊播放音樂,結果音樂變得像恐怖電影配樂
  • 2025q1 Homework4 (quiz3+4)
    • 用 size-1 array 來模擬物件導向風格程式、簡化記憶體操作
    • 認識 multi-precision integer 及其動態記憶體配置機制(enlarge)
    • 分析以 SWAR 檢測 null bytes 的 macro 實作原理
    • 了解 ADSR 機制
    • 了解聲音背後的取樣頻率和 phase 的關係
  • 2025q1 Homework5 (assessment)
  • 2025q1 homework6
    • 理解 RCU 的寬限期機制及 linux 核心中的 RCU 函式
    • 實際操作 ftrace 追蹤效能瓶頸
    • 將 khttpd 改進為使用 CMWQ

前一兩週的作業,我總是很急著想要看見成果、急著把每一件作業要求裡的要求完成並交差了事,因為我很討厭「事情沒做完,又有更多事情出現」的感覺。而這般速戰速決的結果是,我學到的東西很淺薄,做完一份作業後也說不出來有什麼領悟。

後來去讀了 yy214123 同學的 lab0-c 筆記,發現他對細節格外著墨:例如佇列操作的函式,除了實作程式碼以外,還會透過實驗去分析多種實作方法的效能優劣差異。看到他的作業,我覺得落差感很大,而且有種醍醐灌頂的感覺:這才是正確的學習方式吧! 所以在後面幾次的作業中,我開始放慢腳步,把教材、作業的內容讀懂。印象最深的是 Homework 2 的 Week 2 Q2,我面對了一直以來對數學的恐懼,將整數開根號實作的數學推導讀懂,並記錄在該次作業的 HackMD 上。雖然花的時間超級長,但我好好的面對了。

另外,我覺得課堂出的測驗題都很生動,因為都是從實際應用的專案中擷取下來,且據說都是在企業面試會出現的程式碼,一次就是數百行。印象最深的是 Homework 4 的 week 4 Q2,是一個用核心模組播放音樂的專案,我也藉此了解到濾波器、ADSR、取樣等實作中出現的知識。

雖然我認為自己在寫作業的過程中收穫豐富,但以結果論來說,我還是沒有達成所有老師所給出的作業要求(尤其針對 hw3 kxo 和 hw6 ktcp 兩項作業)所以我給自己 7 分。

期末專題

學習到的內容客觀事實:

  • 認識 namespace 等運作機制,light-container 中引入 newuidmap 幫助在 rootless 情況下寫入 uid/gid map
  • 理解 capabilities 於執行 execve() 後的重計算模型的設計哲學、演化的歷史
  • 學習 cgroups v2 的 delegation 機制、cgroups v1 需要改善的原因,並嘗試實作於 light-container 中
  • 參閱 docker 官方的 seccomp profile,基於 barco 之上新增更多針對系統呼叫的限制
  • 對 barco 提出貢獻(修拼字 paenrt -> parent)
  • 理解容器相較於 type 1, type 2 hypervisor 的優勢(不須依賴硬體虛擬化指令集、可重用作業系統機制)
  • argtable3 開源套件解析命令
  • 加入 rxi log 套件,幫助 light-container 開發過程中的除錯
  • 執行 cgroups 限額設定時,遇到權限問題。原先認為是 capabilities 問題,後來以 log 和使用 strace 定位,並讀了 Linux Security Module 和 SELinux 的相關資料,最終發現是被 AppArmor 擋住
  • 引入 slirp4netns 使容器具備網路連線功能

專題的題目為「輕量級容器實作」。一開始和老師討論定題時,被問了很多問題,但我都回答不出來。我因此察覺到自己學習方式一定出了問題,老師也建議我不要急著貢獻,專注細節、搞懂機制才是最重要的。 我一直將這句話惦記在心中;印象深刻的是,我當時正在研究 user namespace 的 pid/uid map 的權限問題,因為我想盡快解決問題,後來問 AI 無果;直到靜下心來把 user namespace 的 man page 仔細看過一遍後,才發現文件中早已精準註明使用的限制。此次事件後降低了我對 AI 及第二手文件(CSDN)的依賴程度。

真的從最基本的系統呼叫開始,自幹出容器的最小可行產品後,我也將 capabilities, namespace, seccomp, cgroups 等機制深深刻印在腦中了。但最終專案在 cgroups 設定上仍存在一些權限問題,我給自己 9 分。

與授課教師的互動

課堂問答:

  • 2025/04/22 問答追蹤
    • 回答關於同步 / 非同步機制的相異處問題
    • 回答快速排序的時間複雜度、worst case 時的資料分佈
    • 理解殭屍行程與孤兒行程的差異
    • 理解 PID 1 reaper (init, systemd) 的行為
  • 2025/05/06 問答追蹤
    • 理解 PELT 所扮演的角色及背後的數學
    • 探討 Linux 核心用定點數實作 EWMA 的方式、精度選擇上的考量(和排程 nice 值的 1024 息息相關)
    • 探討 EWMA 的衰變因子選擇原因
  • 2025/05/13 問答追蹤
    • 回顧統計學中的常態近似手法,將離散分佈轉換為連續形式,並理解公式中 continuity correction 的必要性
    • 研究 fork 後親代行程和子代行程 page 的相異之處

一對一討論時間:2025/05/22

第一次的問答,老師問了我一些關於同步 / 非同步、快速排序、殭屍行程的問題,因為是在線上進行,所以沒有那麼緊張。而後面的兩次都是現場授課:老師問了 PELT、EWMA 及一些延伸問題,而我對內容本身不熟悉以外,加上老師直接站在座位旁那股 look in my eyes 的威壓,使我的腦袋中一片空白。 這讓我有些擔心又有些慶幸,擔心的是未來面試的自己是否也會是這副模樣,慶幸的是提早面對了現實,所以有充分的時間可以去改善。 可惜的是,在課程的 20 週裡,和老師一對一互動的時間比較少,再修一次的話,我會希望維持最少兩周討論一次的頻率。 而每次課堂結束的問答,我總是深入完成議題追蹤。我給自己 8 分。

所見所聞所感

我覺得這門課對我而言最大的意義是,學會「放慢腳步」。 這學期我開始深深反思自己,而我發現自己是相當重視結果的人:我重視「考試考得好不好」大於「過程中學到了什麼」、我重視「羽球比賽贏了沒有」大過於「和隊友一同拼搏的快樂」、我重視「有沒有被人看見」大於「我真正懂什麼」。 所以我在短時間內發表成果的情境中(考試、報告等),都可以表現得不錯;但面對需要長期鑽研的議題,我好像缺乏一份靜下心來的韌性。面對需要短時間內看不到成果、嚐不到甜頭且需要高度自律的事情,我很容易放棄(學吉他、學語言等)

回顧前半個學期的我,會很急著想變得和厲害的同學、學長姐一樣,去貢獻、投入大型專案開發,去找有哪些缺失的地方可以改善;但後來發現這就是「還不會走路就想學跑步」的心態。老師要我先不要急,先掌握好細節、想懂課程教材的內容、搞懂機制才是最重要的。其實一開始我並沒有聽進去,這件事我到了做專題的過程中才有所領悟。

學期初聽到 visitorckw 學長的分享覺得很震撼,到底要怎麼在 Linux 如此大型的專案中,發現可改善之處?後來做專題的時候,發現只要靜下心來,把一個問題研究得夠深入,問題就會在思考的間隙間自己跑出來。(例如,當初研究 slirp4netns 時,在思考 rootless container 是否能在無法建立 veth 的狀況下處理 inbound connection?)

包含先前所提到的寫作業過程的心態轉變、「期末專題」章節中所述經驗等,讓我意識到太急著看見結果不是好事。縱使美麗的果實可能成為短時間內前進的動力,但也很容易因為看不見盡頭就將這份動力燃燒殆盡。對我而言,最好的心態就是放慢腳步。先把成果放一邊,才能夠專注眼下應該全心投入的議題、專注於細節。

另外,我覺得這門課很難能可貴的是「客製化」的程度很高,老師並不是用統一的衡量標準去衡量大家的付出;而且和見過社會殘酷的老師一對一討論後,也確實幫助我定位到自己的問題。這是在微積分、線性代數、演算法等課程裡面不可能發生的,因其衡量標準是齊頭式平等(考試)而非實質平等;大家願意多花時間寫考古題,也不願意正視自己不理解的地方、放慢腳步好好理解(其實包含我自己在內)。

經過這 20 週,這份「放慢腳步」的習慣已經慢慢養成了,也將會繼續影響我未來的學習方式。畢竟投入工程並不是要成為一隻急於展現自己的孔雀,而是要用專業改善生活。(還有要賺很多錢,可能這才是主要目的)

我給自己 10 分。

自我評量 (1 ~ 10)

  • GEOMEAN = \(\sqrt[5]{7*7*9*8*10} \approx 8.12\)
  • 方案 B : 1 + floor(GEOMEAN) = 1 + floor(8.12) = 9