Apache 和 Samba 這類伺服器,主要以傳送檔案資料的工作為主,他們最常做的工作不外乎是開啟檔案(Open)、讀取(Read)、寫入網路連線(Write to Socket)。但是以 Kernel 的角度來說,這樣一個讀取檔案資料和傳送出去的流程相當繁複,並擁有最少兩次的 Kernel/User Space 資料搬移, 導致同一筆資料需要經過兩次多餘的複製。舉例來說,若一個檔案有 1MB,則 Linux Kernel 需要多做 2MB 的記憶體複製,使得效能經常消耗在這種地方,尤以 CPU 不夠快的平台上狀況特別明顯。 而過去曾有 khttpd 這樣的實作,讓 Linux Kernel 自成一個小型的 Web Server,提供一個極有效率方式的讀取靜態網站頁面和 Server 服務,其加速的方法,便是於 Kernel Space 讀取檔案並直接從網路連線送出資料,目的也在於減少 Kernel/User space 之間不必要的 context switch。 想瞭解 User Space 和 Kernel 的資料搬移狀況,我們可以來研究應用程式在讀取和傳送網路資料的流程,經簡化後大致上是(以下簡稱 User Space 為 US,Kernel Space 為 KS): [US] open() [KS] do_sys_open() [KS] do_filp_open() - 找到檔案,並從所在的檔案系統取得 struct file [KS] Return File Object [US] malloc() - 準備一塊記憶體當 buffer [US] read(file, buffer) [KS] vfs_read(file) - 標準 VFS 的檔案讀取 API [KS] file->f_op->read() - 使用資料所在的檔案系統(filesystem),其提供的低階 read 操作 [KS] copy_to_user(buffer) - 將檔案資料從硬碟讀出來後,複製一份到 user space 的 buffer 接著是將讀到的資料透過網路傳送出去: [US] write(Socket, buffer) - 將 buffer 內資料傳送出去 [KS] copy_from_user(buffer) -...