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性能。node

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的線程進行寫回操做。linux

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。spa

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對象。3d

小結

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

相關文章
相關標籤/搜索