readahead即预读,提前从块设备(如硬盘)里多读一些page缓存到page cache tree,以便下次读时能直接从page cache中命中,而不需要触发实际块设备的访问,提高IO效率。
那么什么时候readahead,readahead多少个page呢?
调用系统调用read时,先find page cache,若cache miss则进行sync readahead;若命中的page设置了PG_readahead标志则进行async readahead。sync readahead和async readahead都调用了ondemand_readahead函数,readahead的算法就是在这里实现的。
对于是否readahead和readahead多少page分以下几种情况 :
1.顺序读
从文件第一个page读假定为顺序读
当前读的page与上一次读的page相邻,则为顺序读 。
2.连续顺序读
和上一次readahead的 page连续或者命中PG_readahead
和history pages连续
3.随机读
不符合上述情况的判断为随机读,不做readahead(最少读一个page)
对于顺序读,readahead的pages数按请求的pages数计算,读的越多则 readahead越多,如果是连续顺序读则ramp up。具体如下 :
上面提到的PG_readahead是怎么放置的呢?
async_size表示预读的page数,size表示读的总的page数(含用户请求的和预读的),在预读的第一个page设置PG_readahead标志。