發表文章

目前顯示的是 三月, 2011的文章

ibus-chewing 單純注音模式 - OSDC.tw 2011 Lightening Talk

為了注音輸入法,您是否長久以來也仍在使用 SCIM?每次裝好 Linux 的第一件事就是刪除系統預設輸入法,我們彷彿是外星人一般,一點都沒享有人權。感謝 OSDC.tw 2011(活動期間 3/26 ~ 3/27) 提供好吃的食物和舒適的場地,在活動這兩天筆者花了一點功夫做 patch,修掉了 ibus-chewing 單純注音模式的一些 Bugs,現在基本上 ibus-chewing 單純注音模式已經可用,我們可以丟掉 SCIM + 爛注音 Table 了!

以下是 Lightening Talk 的簡報檔:


後記
由於簡報格式的關係,暫時無法轉成 PDF 輸入,所以目前使用錄影的方式公開,待轉檔程式開發完成再來釋出 PDF 檔。

Linux Kernel Sendfile() 的提升 Server 效能之路

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) - 將 user space 的 buffer 複製回 k…

在 Linux Kernel 中取得目錄中的檔案清單

寫一支程式在 User Space 下列出目錄中的檔案清單相當容易,我們可以用 readdir() 去一項項取得檔案內容,事實上, readdir() 是由 Linux Kernel VFS(Virtual Filesystem) 所提供的 API,真正的實作在檔案系統的核心模組(Kernel Module)中。然而因為 Kernel readdir() 的相關實作牽涉到 Kernel/User space 的資料交換問題,所以如果我們是在撰寫 Kernel 的驅動程式,當然就不能使用這系列的 APIs。不過也因為所有的資訊都存在於 Kernel 的資料結構中,我們可以直接從記憶體中的 Linked list 中快速取得檔案清單。

在取得某個目錄下所有檔案資訊前,要先得到該目錄的敘述 struct dentry,VFS 用 struct dentry 的串聯組合來描述整個檔案系統的目錄結構,檔案清單則被保存在 dentry 中的 Double Linked List,因此其實只要知道如何使用 Kernel 提供的 Double Linked list,就能得到該目錄下所有的檔案資訊。而這邊要注意的是 Kernel 提供的一個通用 Linked list 結構(struct list_head),用來統一整個核心的 Linked list 操作機制,這檔案清單的 Double Linked List 就是使用這通用的結構。

這裡是 Linux Kernel 2.6.37 中 dentry 的資料結構(定義在 linux/dcache.h,其中較不重要的部份以『...』做省略,此外,某些定義與較早版本的 Kernel 有所差異,將在文章最後補上說明):struct dentry { ...省略 struct hlist_node d_hash; /* lookup hash list */ struct dentry *d_parent; /* parent directory */ struct qstr d_name; struct list_head d_lru; /* LRU list */ /* * d_child and d_rcu can share memory */ …