首 先,它们存在的目的不同,kswap的作用是管理内存,pdflush的作用是同步内存和磁盘,当然因为数据写入磁盘前可能会换存在内存,这些缓存真正写 入磁盘由三个原因趋势:1.用户要求缓存马上写入磁盘;2.缓存过多,超过一定阀值,需要写入磁盘;3.内存吃紧,需要将缓存写入磁盘以腾出地方。上述原 因使得kswap和pdflush有交叉的地方,因此很多人混淆了它们。
它们相同的地方都是定期被唤醒,都是以守护进程(内核进程)的形式存在,kswap试图保证内存永远都是可满足用户要求的,为了实现这种承诺,它必须采取 一定的策略;pdflush试图保证内存和磁盘的数据是同步的,不会因为缓存的原因使内存和磁盘的数据不同步从而造成数据丢失或者损坏,为了实现这种承诺,它同样也要采取一定的策略。那么它们之间的交叉点在何处呢?比如,在用户要求内存不能被满足或者空闲内存的数量已经低于某一个值的时候,kswap被 唤醒,它必须为用户的要求提供服务,因此试图换出一部分正在使用的内存使之成为空闲内存以供用户使用,这时,磁盘缓存也是正在被使用的内存,因此,kswap需要将它们换出,这里的换出和匿名页面被换到交换分区是一样的概念,将磁盘缓存换到哪里呢?当然哪里来哪里去了。linux不区分匿名页面 对应的交换分区和真实文件的磁盘缓存对应的磁盘文件分区,实际上在将匿名页面写到交换分区的时候也是按照写文件的形式进行的,读源代码的时候就会发现有一个address_space_operations结构体,里面的readpage和writepage就是读写页面的回调函数,linux的这个实现 方式表明,写匿名页面和写ext2的缓存页面没有本质的区别,仅仅换一下那几个address_space_operations里面的回调函数就行。因此kswap也会将磁盘缓存回写到磁盘,和pdflush所作的工作一样,这就是它们交叉的地方,当然如果kswap已经将页面写入了磁盘,就会清除掉页 面的脏标志,这样,在pdflush扫描脏页的时候就不会二次回写了。
既然kswap和pdflush有联系,那么联系它们的纽带是什么?当然是内核中的lru链表了,本来需要pdflush写入磁盘的页面也许要通过 kswap写入,如何让kswap看到pdflush负责的页面呢?实际上linux并没有刻意关注这个事情,内核那么复杂,如果这么细致的考虑问题谁都 会发疯的。因此linux采用了更加宏伟的方式,就是将事情抽象,不再操心什么回写啊,内存释放之类的细节,而是抽象出了内存管理和缓存管理这些个模块,然后模块和模块之间建立一个耦合点,也可以理解成一个接口,这个东西就是lru链表,linux规定,凡是想纳入内存管理范畴的内存物理页面都要加入 lru链表,而kswap就是内存管理的执行者,它操作的正是这个链表,这样它就不需要别的什么了,只需要告诉大家,你想让我管理,别让我去找你,你自己加入lru链表吧,就这样而已。缓存管理模块当然想加入内存管理,因此所有的磁盘缓存页面都在加入缓存的同时加入了lru链表,这样缓存管理的执行者 pdflush和内存管理的执行者kswap就不需要直接交互商量事情了,一个lru链表解除了它们的耦合。