# 2023q1 Homework3 (fibdrv) contributed by < `sherrygottalent` > ## materials [L04: fibdrv](https://hackmd.io/@sysprog/linux2023-fibdrv-a) [Linux Device Drivers: Tutorial for Linux Driver Development](https://www.apriorit.com/dev-blog/195-simple-driver-for-linux-os) > The Linux kernel is written in the C and Assembler programming languages. C implements the main part of the kernel, while Assembler implements architecture-dependent parts. > .. > If a developer makes a mistake when implementing a user-level application, it will not cause problems outside the user application in most cases. But mistakes in the implementation of a kernel module will lead to system-level issues. >.. > The kernel and its modules represent a single program module and use a single global namespace. ## 開發環境 ```shell $ uname -r 5.15.0-67-generic $ gcc --version gcc (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0 $ lscpu 架構: x86_64 CPU 作業模式: 32-bit, 64-bit Byte Order: Little Endian Address sizes: 39 bits physical, 48 bits virtual CPU(s): 8 On-line CPU(s) list: 0-7 每核心執行緒數: 2 每通訊端核心數: 4 Socket(s): 1 NUMA 節點: 1 供應商識別號: GenuineIntel CPU 家族: 6 型號: 142 Model name: Intel(R) Core(TM) i7-8550U CPU @ 1.80GHz 製程: 10 CPU MHz: 2000.000 CPU max MHz: 4000.0000 CPU min MHz: 400.0000 BogoMIPS: 3999.93 虛擬: VT-x L1d 快取: 128 KiB L1i 快取: 128 KiB L2 快取: 1 MiB L3 快取: 8 MiB NUMA node0 CPU(s): 0-7 ``` ## 自我檢查清單 - [ ] 研讀上述 ==Linux 效能分析的提示== 描述,在自己的實體電腦運作 GNU/Linux,做好必要的設定和準備工作 $\to$ 從中也該理解為何不希望在虛擬機器中進行實驗; - [ ] 研讀上述費氏數列相關材料 (包含論文),摘錄關鍵手法,並思考 [clz / ctz](https://en.wikipedia.org/wiki/Find_first_set) 一類的指令對 Fibonacci 數運算的幫助。請列出關鍵程式碼並解說 - [ ] 複習 C 語言 [數值系統](https://hackmd.io/@sysprog/c-numerics) 和 [bitwise operation](https://hackmd.io/@sysprog/c-bitwise),思考 Fibonacci 數快速計算演算法的實作中如何減少乘法運算的成本; - [ ] 研讀 [KYG-yaya573142 的報告](https://hackmd.io/@KYWeng/rkGdultSU),指出針對大數運算,有哪些加速運算和縮減記憶體操作成本的舉措? - [ ] `lsmod` 的輸出結果有一欄名為 `Used by`,這是 "each module's use count and a list of referring modules",但如何實作出來呢?模組間的相依性和實際使用次數 ([reference counting](https://en.wikipedia.org/wiki/Reference_counting)) 在 Linux 核心如何追蹤呢? - [ ] 注意到 `fibdrv.c` 存在著 `DEFINE_MUTEX`, `mutex_trylock`, `mutex_init`, `mutex_unlock`, `mutex_destroy` 等字樣,什麼場景中會需要呢?撰寫多執行緒的 userspace 程式來測試,觀察 Linux 核心模組若沒用到 mutex,到底會發生什麼問題。嘗試撰寫使用 [POSIX Thread](https://en.wikipedia.org/wiki/POSIX_Threads) 的程式碼來確認。 ## :penguin: 作業要求 * 回答上述==自我檢查清單==的所有問題,需要附上對應的參考資料和必要的程式碼,以第一手材料 (包含自己設計的實驗) 為佳 * 在 GitHub 上 fork [fibdrv](https://github.com/sysprog21/fibdrv),目標是修正 Fibonacci 數計算的正確性 (現有實作存在缺陷,請指出),隨後改善 `fibdrv` 計算 Fibinacci 數列的執行效率,過程中需要量化執行時間,可在 Linux 核心模組和使用層級去測量 * 原本的程式碼只能列出到 Fibonacci(100) 而且==部分輸出是錯誤的數值==,請修改程式碼,列出後方更多數值 (注意: 檢查正確性和數值系統的使用) * 務必研讀上述 ==Linux 效能分析的提示== 的描述,降低效能分析過程中的干擾; * 在 Linux 核心模組中,可用 ktime 系列的 API; * 在 userspace 可用 [clock_gettime](https://linux.die.net/man/2/clock_gettime) 相關 API; * 善用統計模型,除去極端數值,過程中應詳述你的手法 * 分別[用 gnuplot 製圖](https://hackmd.io/@sysprog/Skwp-alOg),分析 Fibonacci 數列在核心計算和傳遞到 userspace 的時間開銷,單位需要用 us 或 ns (自行斟酌) * 嘗試解讀上述實驗的時間分佈,特別是隨著 Fibonacci 數列增長後,對於 Linux 核心的影響。可修改 VFS 函式,允許透過寫入 `/dev/fibonacci` 裝置檔案來變更不同的 Fibonacci 求值的實作程式碼。 ![](https://i.imgur.com/7xyCUVO.png) * 用 printk 固然方便,但其執行時間易受各種因素而不穩定,除了透過統計來觀察,也可改用核心的 sysfs 介面,後者可讓我們自行宣告 show 和 store 介面來提供讀寫操作,可參見 [Sample kobject implementation](https://elixir.bootlin.com/linux/latest/source/samples/kobject/kobject-example.c) (注意: 切換到對應的 Linux 核心版本)。 * 逐步最佳化 Fibonacci 的執行時間,引入[費氏數列分析](https://hackmd.io/@sysprog/fibonacci-number) 提到的策略,並善用 [clz / ffs](https://en.wikipedia.org/wiki/Find_first_set) 一類的指令 (Linux 核心有對應的包裝函式),過程中都要充分量化 * 嘗試研讀 [bignum](https://github.com/0xff07/bignum/tree/fibdrv) (`fibdrv` 分支) 的實作,理解其中的技巧並與你的實作進行效能比較,探討個中值得取鏡之處。 * 原理和分析可見 [KYG-yaya573142 的報告](https://hackmd.io/@KYWeng/rkGdultSU) :::spoiler linux command - `insmod` - `lsmod` - `modprobe` - `mknod` - `krealloc` - reallocate memory. The contents will remain unchanged. ::: ### 模組間的相依性和實際使用次數 > However, there is a counter which keeps track of how many processes are using your module. You can see what its value is by looking at the 3rd field with the command cat /proc/modules or sudo lsmod . __《[The Linux Kernel Module Programming Guide](https://sysprog21.github.io/lkmpg/#what-is-a-kernel-module)》 - `teskset` 限定使用指定 CPU 執行 - `isolcpu` isolate 指定 CPU,讓他們只執行某些程式 - 重現 ### test [The Linux Kernel Module Programming](https://sysprog21.github.io/lkmpg/) --- :::spoiler ... ## 開發環境 trial 2 M1 with AsahiLinux [Asahi Linux](https://asahilinux.org/) ``` shell $ uname -r 6.1.0-rc6-asahi-4-1-ARCH $gcc --version gcc (GCC) 12.1.0 Copyright (C) 2022 Free Software Foundation, Inc. $ lscpu 架構: aarch64 CPU 作業模式: 64-bit Byte Order: Little Endian CPU(s): 8 On-line CPU(s) list: 0-7 供應商識別號: Apple Model name: Icestorm 型號: 1 每核心執行緒數: 1 每通訊端核心數: 4 Socket(s): 1 製程: 0x1 CPU(s) scaling MHz: 100% CPU max MHz: 2064.0000 CPU min MHz: 600.0000 BogoMIPS: 48.00 Flags: fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm jscvt fcma lrcpc dcpop sha3 asimddp sha512 asimdfhm dit uscat ilrcpc flagm ssbs sb paca pacg dcpodp flagm2 frint Model name: Firestorm 型號: 1 每核心執行緒數: 1 每通訊端核心數: 4 Socket(s): 1 製程: 0x1 CPU(s) scaling MHz: 65% CPU max MHz: 2988.0000 CPU min MHz: 600.0000 BogoMIPS: 48.00 Flags: fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm jscvt fcma lrcpc dcpop sha3 asimddp sha512 asimdfhm dit uscat ilrcpc flagm ssbs sb paca pacg dcpodp flagm2 frint Vulnerabilities: Itlb multihit: Not affected L1tf: Not affected Mds: Not affected Meltdown: Not affected Mmio stale data: Not affected Retbleed: Not affected Spec store bypass: Mitigation; Speculative Store Bypass disabled via prctl Spectre v1: Mitigation; __user pointer sanitization Spectre v2: Not affected Srbds: Not affected Tsx async abort: Not affected $ cat /etc/*-release NAME="Arch Linux ARM" PRETTY_NAME="Arch Linux ARM" ID=archarm ID_LIKE=arch BUILD_ID=rolling ANSI_COLOR="38;2;23;147;209" HOME_URL="https://archlinuxarm.org/" DOCUMENTATION_URL="https://archlinuxarm.org/wiki" SUPPORT_URL="https://archlinuxarm.org/forum" BUG_REPORT_URL="https://github.com/archlinuxarm/PKGBUILDs/issues" LOGO=archlinux-logo ``` . . . Asahi Linux 的指令只有 `wget`, `rpm` `dpkg` 都不支援,安裝 `git` 都會碰到問題,最後還是決定要買一台 windows 電腦作業。 ::: :::spoiler ... ## 開發環境 trial 1 M1 with container ``` shell $ uname -r 5.15.49-linuxkit $ gcc --version gcc (Ubuntu 11.3.0-1ubuntu1~22.04) 11.3.0 $ lscpu Architecture: aarch64 CPU op-mode(s): 64-bit Byte Order: Little Endian CPU(s): 8 On-line CPU(s) list: 0-7 Vendor ID: 0x00 Model: 0 Thread(s) per core: 1 Core(s) per cluster: 8 Socket(s): - Cluster(s): 1 Stepping: 0x0 BogoMIPS: 48.00 Flags: fp asimd evtstrm aes pmul l sha1 sha2 crc32 atomics fphp asimdhp cpuid asimd rdm jscvt fcma lrcpc dcpo p sha3 asimddp sha512 asi mdfhm dit uscat ilrcpc fl agm ssbs sb paca pacg dcp odp flagm2 frint Vulnerabilities: Itlb multihit: Not affected L1tf: Not affected Mds: Not affected Meltdown: Not affected Mmio stale data: Not affected Spec store bypass: Vulnerable Spectre v1: Mitigation; __user pointe r sanitization Spectre v2: Not affected Srbds: Not affected Tsx async abort: Not affected ``` ## materials [Run Linux GUI Apps on macOS using Docker](https://www.youtube.com/watch?v=cNDR6Z24KLM) [docker CLI cheat sheet](https://docs.docker.com/get-started/docker_cheatsheet.pdf) ## 環境建置 - 安裝 linux-headers 套件 (注意寫法裡頭有 s) ```shell $ sudo apt install linux-headers-`uname -r` Reading package lists... Done Building dependency tree Reading state information... Done E: Unable to locate package linux-headers-5.15.49-linuxkit E: Couldn't find any package by glob 'linux-headers-5.15.49-linuxkit' ``` [解決方式] 先使用 `apt-cache search linux-headers-` 查詢可用套件,再安裝對應套件 e.g.`linux-headers-5.15.0-48-generic-64k` ```shell $ dpkg -L linux-headers-5.15.0-48-generic-64k | grep "/lib/modules" /lib/modules /lib/modules/5.15.0-48-generic-64k /lib/modules/5.15.0-48-generic-64k/build ``` - 檢驗目前的使用者身份 ```shell $ whoami libsemigroups ``` ```shell $ sudo whoami root ``` * 編譯並測試 ```shell $ make check ``` 預期會看到綠色的 ` Passed [-]` 字樣,隨後是 ``` f(93) fail input: 7540113804746346429 expected: 12200160415121876738 ``` 這符合預期,因為給定的 `fibdrv` Error 1. ```shell $ make check make -C /lib/modules/5.15.49-linuxkit/build M=/home/libsemigroups/linux2023/L04_fibdrv/sysprog/ make[1]: *** /lib/modules/5.15.49-linuxkit/build: No such file or directory. Stop. make: *** [Makefile:14: all] Error 2 ``` [解決方式] 修改 Makefile argument,寫死 `KDIR := /lib/modules/5.15.0-48-generic-64k/build` Error 2. ```shell $ make check make -C /lib/modules/5.15.0-48-generic-64k/build M=/home/libsemigroups/linux2023/L04_fibdrv/sysprog/fibdrv modules make[1]: Entering directory '/usr/src/linux-headers-5.15.0-48-generic-64k' make[1]: Leaving directory '/usr/src/linux-headers-5.15.0-48-generic-64k' make unload make[1]: Entering directory '/home/libsemigroups/linux2023/L04_fibdrv/sysprog/fibdrv' sudo rmmod fibdrv || true >/dev/null sudo: rmmod: command not found make[1]: Leaving directory '/home/libsemigroups/linux2023/L04_fibdrv/sysprog/fibdrv' make load make[1]: Entering directory '/home/libsemigroups/linux2023/L04_fibdrv/sysprog/fibdrv' sudo insmod fibdrv.ko sudo: insmod: command not found make[1]: *** [Makefile:24: load] Error 1 make[1]: Leaving directory '/home/libsemigroups/linux2023/L04_fibdrv/sysprog/fibdrv' make: *** [Makefile:38: check] Error 2 ``` [解決方式] `sudo apt-get install insmod ` ["Unable to locate package" while trying to install packages with APT](https://askubuntu.com/questions/378558/unable-to-locate-package-while-trying-to-install-packages-with-apt) . . . 更改環境, switch from M1 with container to M1 with Asahi Linux :::