contributed by < Risheng1128
>
作業要求
lsmod
的輸出結果有一欄名為 Used by
,這是 "each module's use count and a list of referring modules",但如何實作出來呢?模組間的相依性和實際使用次數 (reference counting) 在 Linux 核心如何追蹤呢?
搭配閱讀 The Linux driver implementer’s API guide » Driver Basics
fibdrv.c
存在著 DEFINE_MUTEX
, mutex_trylock
, mutex_init
, mutex_unlock
, mutex_destroy
等字樣,什麼場景中會需要呢?撰寫多執行緒的 userspace 程式來測試,觀察 Linux 核心模組若沒用到 mutex,到底會發生什麼問題。嘗試撰寫使用 POSIX Thread 的程式碼來確認。看完了Linux 效能分析的提示後,了解為何要將要執行的 process 綁定在特定 CPU 上,以下為規劃的實作步驟
首先進行 CPU Core 保留的動作,在 boot loader 上新增參數 isolcpus=cpu_id
,這邊選擇 core 0
作為測試,因此新增:
isolcpus=0
進入目錄 /etc/default
,並且輸入命令 sudo vim grub
開啟檔案 grub
,並修改以下指令
GRUB_CMDLINE_LINUX="isolcpus=0"
接著輸入命令 sudo update-grub
更新 /boot/grub/grub.cfg
,以下為結果
重開機後,輸入命令 taskset -p 1
,可以看到 core 0
已經被保留
也可以從 System Monitor 觀察,如以下所示:
接著抑制 ASLR
sudo sh -c "echo 0 > /proc/sys/kernel/randomize_va_space"
設定 scaling_governor 為 performance ,建立 performance.sh
接著輸入命令 sudo sh performance.sh
執行 performance.sh
最後針對 Intel 處理器,關閉 turbo mode
sudo sh -c "echo 1 > /sys/devices/system/cpu/intel_pstate/no_turbo"
回答問題: 為何不希望在虛擬機器中進行實驗
參考Linux 核心設計: 不只挑選任務的排程器裡的連結 Hypervisor ,裡頭提到 hypervisor 的種類 (native or bare-metal hypervisors 及 hosted hypervisors) ,如下圖所示
參考 Hypervisor
如果使用虛擬機器進行實驗的話,電腦架構會類似上圖的 Tpye 2
,當執行程式時,會經過虛擬機器及原本的作業系統,因此效能會比較差
這邊將論文的分析放在額外開的筆記: 研讀 Algorithms for Computing Fibonacci Numbers Quickly
ToDo: 補上 Fast doubling ,以及 clz/ctz 指令的幫助
作業要求
這邊跟著作業說明,一步一步設定
首先,將 UEFI Secure Boot 的功能關閉: 已關閉
檢查 Linux 核心版本,輸入命令 uname -r
安裝 linux-headers
套件,輸入命令 sudo apt install linux-headers-‵uname -r‵
接著確認 linux-headers
套件已經正確安裝在開發環境,輸入命令 dpkg -L linux-headers-5.13.0-28-generic | grep "/lib/modules"
,可以得知符合預期
檢驗目前使用者身份,輸入命令 whoami
,可以得知符合預期 (非 root
)
一起檢查命令 sudo whoami
,可以得知符合預期
繼續安裝後續會用到的工具
取得原始程式碼
編譯並測試,輸入命令 make check
,根據作業說明可以得知以下結果符合預期
觀察產生的 fibdrv.ko
核心模組,輸入命令 modinfo fibdrv.ko
接著觀察 fibdrv.ko
核心模組在 Linux 核心掛載後的行為,需要先輸入命令 make load
掛載核心模組
ToDo: 理解命令 cat /sys/class/fibonacci/fibonacci/dev
回傳 507
的意義
為了能夠計算 Big number 以及有效管理程式,這邊新增兩個檔案 bignumber.c
bignumber.h
開始修改 Makefile
輸入命令 Make
試試,出現了奇怪的錯誤
後來發現是編譯的檔案重複了,後來參考 Linux Kernel driver modpost missing MODULE_LICENSE,把原本的檔名從 fibdrv
改成 fibdrv_core
,並且再次修改 Makefile
再次輸入命令 make
,成功!
接著可以開始實作程式碼,這邊是選擇使用字串將數字儲存,以下為 bignumber.c
實作結果,參考 415. Add Strings ,主要功能為將兩個字串相加
接著修改 fibdrv_core.c
裡的函式 fib_sequence()
最特別的部份主要是第 18 行的 copy_to_user
,可以參考 copy_to_user
,主要是因為變數 buf
是 user space 的變數,且 kbuf
則是 kernel space 的參數,這裡需要 copy_to_user
作為兩者資料複製的橋樑
接著把 fibdrv_core.c
的巨集 MAX_LENGTH
改成 500
最後根據作業說明的連結 The first 500 Fibonacci numbers 新增新的測試檔 fibnacci500.txt
,裡頭存放從第 1 個到第 500 個數字
修改 Makefile
最後輸入命令 make check
,確認執行結果,成功新增 big number!
在實作之前,先學習 gettime
和 ktime
的方法,參考去年學員 bakudr18 的共筆
這邊使用的範例為上述實作的結果,且使用的時間單位為 ns
,以下為實作程式碼 (client.c
)
實作用來計算時間差的函式 elapse()
這邊參考作業說明裡的核心模式的時間測量 ,了解 hrtimers 的使用方法
首先,一樣跟著作業說明,將 write
挪用來輸出上一次 fibnacci 的執行時間,並且修改 fibdrv_core.c
的程式碼
接著修改 client.c
的程式碼
這邊寫了一個 eliminate.py
,用來實現移除 out
產生出的極端值,同時可以執行多次測試並取平均值
為了方便執行這邊修改 Makefile
,新增 plot
及 splot
命令,如下所示
plot
: 執行多次後經過 python 計算後畫出的圖splot
: 單獨執行一次所畫出的圖這邊列出只執行一次及執行 50 後經過 python 處理的結果,都是取前 100 個數
輸入命令
make splot
(一共測試 3 次)
輸入命令
make plot
,經過去除極端值,且結果為執行 50 次的平均結果 (一樣測試 3 次)
可以看到有經過極端值處理的結果平緩且穩定許多
這邊有點好奇沒有指定 CPU 和有指定 CPU 所量測出來的結果,因此分別測試,分別測試前 100 、 500 和 1000 個數,且都只執行一次
測量沒有指定 CPU 的結果
接著測量有指定 CPU 的結果,從一開始的設定已經把 core 0 暫停,使用 core 0 進行量測
稍微修改 Makefile
測量有指定 CPU 的結果
兩者看起來沒有很明顯的差異,這邊節錄一段輸出資料
從圖片看來兩者差異不大,但是以實際數據來看,大部分的資料顯示有指定 CPU 的時間有稍微快一點,但是沒有差非常多
To DO: 改成 Fast Doubling 並測量時間
Linux 核心設計: 不只挑選任務的排程器
費氏數列分析
The Linux Kernel Module Programming Guide
Introduction to Linux kernel driver programming