2010-4-13 pdflush 之 balance_dirty_pages_ratelimited 之ratelimit_pages

ratelimite_pages write_trunk 的计算


对于ratelimit_pages ,代码中的注释为 "After a CPU has dirtied this many pages, balance_dirty_pages_ratelimited will look to see if it needs to force writeback or throttling"

即:当一个cpu 弄脏了这么多页后, balance_dirty_pages() 函数将会检查是否需要回写。而要求的回写量 write_trunk ,则由函数 sync_writeback_page() 计算得出,其全部代码为:

static inline long sync_writeback_pages(void)

{

return ratelimit_pages + ratelimit_pages / 2;

}

即,write_trunk = 1.5 * ratelimit_pages 1.5 倍的原因是: "It should be somewhat larger than RATELIMIT_PAGES to ensure that reasonably large amounts of I/O are submitted" ,即回写量应该比 ratelimit_pages 大,确保合理数目的 I/O 被提交。

ratelimit_pages初始化为 32 页,但系统在启动过程中会通过调用函数 set_ratelimit() 来根据系统环境重新设定( start_kernel()-->page_writeback_init()-->set_ratelimit() )。

set_ratelimit()函数的代码很少,全部代码如下所示:

ratelimit_pages = total_pages / (num_online_cpus() * 32);

if (ratelimit_pages < 16)

ratelimit_pages = 16;

if (ratelimit_pages * PAGE_CACHE_SIZE > 4096 * 1024)

ratelimit_pages = (4096 * 1024) / PAGE_CACHE_SIZE;

    

其中total_pages "The total number of pages in the machine" ,由此可知 ratelimit_pages 是系统中页总数的 3% 在每个 cpu 上的分量,且不小于 16 页,不大于 1024 页。

设定一个这样的量的目的是:"Here we set ratelimit_pages to a level which ensures that when all CPUs are dirtying in parallel, we cannot go more than 3% (1/32) over the dirty memory thresholds before writeback cuts in." ,即:当多个 cpu 并行的使页变脏时,确保超出脏页阈值的脏页不会达到系统页数的 3%

一开始,我看到注释,怎么都想不通," we cannot go more than 3% (1/32)  over the dirty memory thresholds  before writeback cuts in "是什么意思, " over the dirty memory thresholds "体现在什么地方。结合 balance_dirty_pages() 函数的流程,我想我终于明白了,为什么说“ 超出脏页阈值的脏页不会达到系统页数的3% ”,并且对 balance_dirty_pages_ratelimited()函数有了新的理解。

balance_dirty_pages()函数在调用 write_inodes() 之前会检测系统中的脏页是否超过了脏阈值。只有在超过脏页阈值的情况下,才会调用 write_inodes() 回写数量为 1.5*ratelimit_pages 的一些页,而 ratelimit_pages 正是系统中总页数的 3% 在每个 cpu 上的分量。

但是,在超出了脏阈值后,回写1.5*ratelimit_pages 个页,并不能保证“ 超出脏页阈值的脏页不会达到系统页数的3% ”。

那么怎样才能保证这一点呢?最简单的办法就是每写脏一页就检查是否超过了脏阈值,如果超过了就回写。但是每写一页就检查势必会降低系统性能,于是系统设定了一个“频率限制”,用以限制balance_dirty_pages() 函数的调用,即 "so try to avoid calling it too often (ratelimiting)" ,而这个“ ratelimiting ”又是通过 ratelimit_pages 来实现的。

balance_dirty_pages_ratelimited_nr()函数每次调用时,对一个 per_cpu 变量 ratelimit 进行加一操作,当这个 ratelimit 达到 ratelimit_pages 后,就将其清 0 ,并调用 balance_dirty_pages() 函数, balance_dirty_pages() 函数将检查脏页数是否超过了脏阈值,然后再进行进一步处理。即:每次写脏系统所有页 3% cpu 上的分量,就检查一次脏页是否超过了脏阈值,这样就可以确保“ we cannot go more than 3% (1/32) over the dirty memory thresholds ”了。


你可能感兴趣的:(cache,2010)