作法是低優先權的 process 未完成前讓出 CPU 給高優先權 process 使用,叫做 preempty。程式在 userspace 原本就 preemptible,kernel 部份在 2.6 開始才有 CONFIG_PREEMPTY 支援,即使在執行 syscall,除了關掉 local interrupts (或持有 siplock),也可被高優先 process preempted。
preempty 時為了維持資料完整和正確,需要 critical section,lock 機制也會不同。uni-processor 的 spinlock,沒有 preempty 時用 no-op 就可以了,有 preempty 就不行。
preemption 可減少延遲,但也會減少 throughput,所以有個平衡點。
在 Linux 中有如下不同程度的 real-time 實作,從無到終極版 throughput 愈低,但愈具備決定性
- CONFIG_PREEMPT_NONE:無
- CONFIG_PREEMPT_VOLUNTARY:低優先權 process 自願讓出
- CONFIG_PREEMPT:隱含在 spinlock, interrupt return code 裡讓出。使用 PREEMPT_RCU,前兩者則使用 CLASSIC_RCU
- CONFIG_PREEMPT_RT:終極版,使用 preemptive 排程器
參考
- Jserv's blog: 破除 Realtime GNU/Linux 的迷思 (Getting real (time) about embedded GNU/Linux 的譯註)
- Real-Time Linux Wiki
- Driver porting: the preemptible kernel
- Linux Device Drivers, Concurrency and Race Conditions
- https://www.codeblueprint.co.uk/2019/12/23/linux-preemption-latency-throughput.html
- CONFIG_SMP:Symmetric multiprocessing。SMP mutual exclusion 確保也可以用在 preemption。同一 CPU 內存取 per-CPU variables 要特別注意 preemption 時是否有 races 問題。其它 CPU 存取已處理,應該沒問題。
- CONFIG_HZ
- Spinlock 原始碼觀摩(—)
沒有留言:
張貼留言