歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

Linux 3.2中回寫機制的變革

writeback機制模型

在Linux-3.2新內核中,page cache和buffer cache的刷新機制發生了改變。放棄了原有的pdflush機制,改成了bdi_writeback機制。這種變化主要解決原有pdflush機制存在的一個問題:在多磁盤的系統中,pdflush管理了所有磁盤的page/buffer cache,從而導致一定程度的IO性能瓶頸。bdi_writeback機制為每個磁盤都創建一個線程,專門負責這個磁盤的page cache或者buffer cache的數據刷新工作,從而實現了每個磁盤的數據刷新程序在線程級的分離,這種處理可以提高IO性能。

writeback機制的基本原理可以描述如下:

在Linux內核中有一個常駐內存的線程bdi_forker_thread,該線程負責為bdi_object創建writeback線程,同時檢測如果writeback線程長時間處於空閒狀態,bdi_forker_thread線程便會將其進行銷毀。bdi_forker_thread在系統中只有一個,其會被定時喚醒,檢查全局鏈表bdi_list隊列中是否存在dirty的數據需要刷新到磁盤。如果存在dirty數據並且對應bdi的writeback線程還沒有被創建,bdi_forker_thread會為該bdi創建一個writeback的線程進行寫回操作。

writeback線程被創建之後會處理等待的work。writeback線程擁有一個定時器會周期性喚醒這個線程處理相應的work。當用戶(page cache/buffer cache)有需要處理的inode時,將inode掛載到writeback-> b_dirty鏈表中,然後喚醒writeback線程去處理相應的dirty_page。inode鏈表就是writeback線程需要處理的數據;work鏈表就是控制處理過程中的一些策略,不同的策略可以定義成不同的任務。

通過上述模型,對於塊設備或者文件系統而言,實現dirty page的後台刷新主要做如下幾個方面的工作:

1,將自己的bdi注冊到系統的bdi鏈表中,通過bdi_forker_thread實現對bdi對象的管理,從而可以實現writeback線程的動態創建、銷毀。每個塊設備和文件系統都有自己的bdi對象。Ext3文件系統在創建的時候會生成superblock對象,系統會將底層塊設備的backing_device關系到這個superblock對象上(在set_bdev_super函數中完成)。如果是塊設備的話,在add_disk的時候直接從request_queue中得到bdi對象,然後對其進行初始化。注冊bdi對象使用bdi_register_dev函數,對於ext3之類的文件系統不需要重新注冊bdi對象,因為其本身就采用了底層塊設備的bdi對象。

2,將需要刷新的inode節點掛載到bdi對象所屬的writeback->b_dirty上,如果有特殊的work需要writeback線程完成,那麼提交一個work即可;如果是通常的周期性刷新,writeback線程會自動創建相應的work。

3,操作writeback的喚醒定時器延遲喚醒writeback線程,或者直接喚醒線程,從而使得inode中radix tree上的dirty page刷新到磁盤。

bdi對象的注冊

每個塊設備在創建的時候會注冊bdi對象(參見add_disk函數),這是Linux-3.2內核不同的地方。文件系統在mount的時候會創建superblock對象,並且通過底層塊設備的request queue獲取bdi對象(mount_bdev->sget->set_bdev_super)。所以,像ext3之類的文件系統都不需要重新注冊bdi對象。當然,如果文件系統重新創建了一個bdi對象,那麼還需要調用bdi_register_dev函數注冊bdi對象。

小結

本文對linux-3.2中的writeback機制模型進行了闡述,後面還會對writeback機制中的關鍵函數進行分析說明。該機制是對老系統(Linux-2.6.23等)中pdflush機制的替代,其最重要的變化是每個塊設備都分配了writeback線程,使得回寫的IO流在各個磁盤之間獨立,從而從機制上提高了IO的吞吐量。

Copyright © Linux教程網 All Rights Reserved