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的吞吐量。对象

相关文章
相关标签/搜索