Original URL: http://www.jollen.org/blog/2008/08/linux_device_driver_blocking_io.html
在 Linux 驅動程式的整個框架中,最重要,而且必須一開始就先了解的主題有二個:
1. Blocking I/O 的觀念。
2. Wait queue 以及 event-driven(event-polling)的觀念。
雖然這裡分成二個小主題,不過其實這是同樣的一個主題。這裡有很多值得提出討論的觀念,首先針對 Blocking I/O 的觀念進行深度探討。
什麼是 blocking I/O?
當 user process 透過 read/write system call 讀取硬體資料時,會有哪些情況出現?請注意,這裡講的是「user process」,並不是驅動程式的 system call 實作(driver function、fops->read 或 fops->write)。以 user process 呼叫 read() 來讀取硬體資料的案例來說,當然免不了就是以下的情況:
1. 驅動程式能順利由硬體拿到資料,並丟到 user-space 給「該」process。
2. 驅動程式目前無法由硬體拿到資料。怎麼辦?
現在沒辦法馬上由硬體拿到資料,怎麼辦呢?當然要等待了。驅動程式必須設法等到可以由硬體拿到資料為止,再將資料丟給該 process。試想,現在有一個 process 想要讀取硬體資料,第一次的 read() 很順利地馬上就拿到資料了,可是第二次的 read() 因為硬體的關係,驅動程式暫時無法由硬體取得資料,於是 process 的第二次 read() 並不會立刻結束。
Process 這個時候「停在」第二次的 read() 呼叫,但其實此時,系統的執行位置是來到驅動程式的 read driver function(fops->read),而 fops->read 在待候硬體資料。「Blocking」就是「停住」的意思,所以第二次的 read() 動作就變成是 blocking I/O。請注意:
1. 這裡一定是討論 user process 是否會停在 read() 或 write()。Blocking I/O 一定要由 user process 的角度討論才會是正確的觀念。
2. 第二次的 read 是 blocking I/O(blocking operaton),這是「驅動程式的 fops->read 實作」所導致的結果。所以,user process 的 read/write 會不會停住,完全是看 fops->read 與 fops->write 的實作。
3. 我們在這裡只討論驅動程式的 read/write 實作,也就是 user process 存取 device file。
這就是所謂的 blocking I/O。由驅動程式的角度來看,可以總結如下:
1. 當驅動程式想讓 user process 在呼叫 read() 函數時,都保證能取得資料,此時驅動程式便要實作「當目前尚無資料可回傳給 user process 時,便讓 user process 停留等待」的機制(可能是驅動程式尚無法由裝置取得資料)。
2. w當驅動程式想讓 user process 在呼叫 write() 函數時,都保證能寫入資料,此時驅動程式便要實作「當目前無法寫入資料至裝置時,便讓 user process 停留等待」的機制(可能是裝置尚未 ready)。