分类: LINUX
2011-07-15 17:40:36
1. 当空闲的内存低于一个特定的阈值时,内核必须将脏页写回磁盘,以便释放内存。
2. 当脏页在内存中驻留时间超过一个特定的阈值时,内核必须将超时的脏页写回磁盘,以确保脏页不会无限期地驻留在内存。
在老内核中,这是由两个独立的内核线程分别完成。但是在2.6版本中,由一组内核线程统一执行这两种工作---pdflush后回写线程。这两个目标是如何实现的?
首先,pdflush线程在系统中的空闲内存低于一个阈值时,将脏页刷新回磁盘。该后台回写例程的目的在于在可用物理内存过低时,释放脏页以重新获得内 存。特定的内存与之可以通过dirty_background_ratio sysctl系统调用设置(看kernel/Sysctl.c)。
当空闲内存比阈值dirty_background_ratio还低时,内核便会调用函数wakeup_bdflush()唤醒一个pdflush线程,随后pdflush线程进一步调用函数background_writeout()开始将脏页写回磁盘。该函数的参数指定试图写回的页面数目,该函数会连续的写出数据,直到满足一下两个条件:
1. 已经有指定的最小数据的页被写出到磁盘
2. 空闲内存数已经回升,超过阈值dirty_background_ratio
pdflush后台例程会被周期唤醒,将那些在内存中驻留时间过长的脏页写出,确保内存中不会有长期存在的脏页。如果系统发生崩溃,由于内存处于混乱中,所以那些在内存中还没来得及写回磁盘的脏页就会丢失,所以周期性同步页高速缓存和磁盘非常重要。
在系统启动时,内核初始化一个定时器,让它周期地唤醒pdflush线程,随后使其运行函数wb_kupdate()。该函数将把所有驻留时间超过百分之 dirty_expire_centisecs秒的脏页写回。然后定时器将再次被初始化为百分之dirty_expire_centisecs秒后唤醒 pdflush线程。
总而言之,pdflush线程周期地被唤醒并把超过特定期限的脏页写回磁盘。
系统管理员可以在/proc/sys/vm中设置回写的相关参数,也可以通过sysctl系统调用设置它们。
pdflush线程的实现代码在文件mm/pdflush.c中,回写机制的实现代码在文件mm/page-writeback.c和fs-writeback.c中。
pdflush设置
变量 | 描述 |
dirty_expire_centisecs | 该数值以百分之一秒为单位,它描述超时多久的数据将被周期性执行的pdflush线程写出 |
dirty_ratio | 占全部内存百分比,当一个进程产生的脏页达到这个比例时,就开始被写出 |
dirty_writeback_centisecs | 该数值以百分之一秒为单位,它描述pdflush线程的运行频率 |
laptop_mode | 一个布尔值,用于控制膝上型电脑模式 |
dirty_background_ratio | 占全部内存的百分比。当内存中空闲页到达这个比例时,pdflush线程开始回写脏页 |
膝上型电脑模式是一种特殊的页回写策略,该策略主要意图是将硬盘转动的机械行为最小化,允许硬盘尽可能长时间的停滞,以此延长电池供电时间。该模式可通过 /proc/sys/vm/laptop_mode文件进行配置。通常,该配置文件内容为0,即膝上型电脑模式关闭,写1则启用该模式。
该模式的页写回行为与传统方式相比只有一处变化。除了当缓存中的页面太旧要执行回写脏页以外,pdflush还好找准磁盘运转的实际,把所有其他的物理磁盘IO、刷新脏换成等统统写回磁盘,以便保证不会专门为了写磁盘而去主动激活磁盘运行。
所述Linux发布版会在电脑接上或拔下电池时,自动开启或禁止膝上型电脑模式及其需要的pdflush可调节开关。因此机器可在使用电池电源时自动进入膝上型电脑模式,而在插上交流电源时恢复到常规的页回写模式。
因为磁盘的吞吐量有限,如果只有惟一线程执行回写操作,那么这个线程很容易等待对一个磁盘上的操作。为了避免出现这样的情况,内核需要多个回写线程并发执行,这样单个设备队列的拥塞就不会称为系统的瓶颈了。
2.6内核使用多个pdflush线程,每个线程可以相互独立地将脏页刷新回磁盘,而且不同的pdflush线程处理不同的设备队列。线程的数目可以根据 系统的运行时间进行调整。pdflush线程数量取决于页回写的数量和拥塞情况,动态调整。如果所有存在的pdflush线程都忙着写回数据,那么一个新 线程就会被创建,确保不会出现一个设备队列处于拥塞状态,而其他设备队列却在等待---不是接收--回写数据的情况。如果堵塞,pdflush线程的数量 便会自动减少,以便节约内存。
为了避免每一pdflush线程都挂起在同一个堵塞的队列上,pdflush线程利用了拥塞避免策略,它们会积极的试图写回那些不属于拥塞队列的页面。这样一来,pdflush线程通过分派回写工作,阻止多个线程在同一个忙设备上纠缠。