kswapd

Subject:
这是当时开发VM算法时,阅读2.4.22内核的一些阅读笔记,仅供参考,并且不保证每段解释都是正确的。 张昀
Author: 张昀
阅读笔记 – Kswapd
张昀 * 2003.10.2

内核线程kswapd仍然和以前一样,用来处理页面的交换,它可以在内存不足时,将一些进程的页面交换到swap空间之中。
在以前版本的Linux中(大部分教材都是这样写的),kswapd每隔10毫秒被激活一次,检测是否需要进行页面交换。而新的(2.4.20以后)算法中,kswapd在可用页面数量小于pages_low时,以及经过了某一段时间时,才被激活。
采取新的方法,显然需要激活kswapd的次数被大大减少。而且只在内存空间不够时,才请求进行页面交换,从理论上来说,也更加合理。
调用关系如下。
1. mm//page-alloc.c文件中的struct page * __alloc_pages(unsigned int gfp_mask, unsigned int order, struct zonelist *zonelist)函数,是分配内存的核心函数。

其中有代码如下:
/* we/'re somewhat low on memory, failed to find what we needed */
for (i = 0; zones[i] != NULL; i++)
wakeup_kswapd(zones[i]);

这段代码的含义是,如果没有能够成功地分配内存,那么表明系统可用内存不足,因此对每一个zone,都调用wakeup_kswapd函数。
2. mm//vmscan.c文件中的void wakeup_kswapd(struct zone *zone)函数,是用来唤醒kswapd核心线程的。
{
//如果空闲页面超过pages_low,那么什么也不做。这一步骤有点奇怪,既然
//分配内存空间已经失败,那么即使空闲页面超过pages_low,也应该去释放
//空间,为什么可以什么都不去做,这样不是可能导致分配空闲空间失败吗?
//是否应该考虑将该句去掉,或者调高pages_low的值?
if (zone->free_pages > zone->pages_low)
return;
//下面两句不是很明白,估计大体含义是如果待激活内核线程的队列中如果还//没有包括kswpad,那么把kswpad添加到等待激活的内核线程队列之中
if (!waitqueue_active(&zone->zone_pgdat->kswapd_wait))
return;
wake_up_interruptible(&zone->zone_pgdat->kswapd_wait);
}
3. mm//vmscan.c文件中的int kswapd(void *p)函数,实际完成kswapd的激活操作。
kswapd 的参数通常是pg_data_t结构,这个结构的定义为typedef struct pglist_data,按照说明,这是描述NUMA结构的内存版面的一个结构。
Kswapd持续地释放页面,一直到达到pages_high为止。
看起来kswapd和pages_low、pages_high这两个参数的设置值很有关系:
 增加pages_low的值,可以使得kswapd不要等到内存消耗得太厉害再开始释放页面,这样似乎可以增加内存成功分配的几率。
 增加pages_high的值,可以使得kswapd每次多释放一些内存,这样对于大型应用软件的使用,可以减少调用kswapd进行内存释放的次数。不过这样做带来的缺陷是,如果系统始终释放不出pages_high这样多的内存,那么是否会陷入一种死循环,或者过多地调用OOM函数?因此,如果pages_high设置得比较高,那么需要一种平衡机制。
pages_low、pages_high的值是在函数void setup_per_zone_pages_min(void)中进行设置的,这个函数位于mm//page_alloc.c之中。
pages_min和系统实际拥有的内存有关,而pages_low、pages_high分别是pages_min的2倍和3倍。我印象在RedHat系统中,pages_min是1MB。

Kswpad函数的核心代码是balance_pgdat(pgdat, 0, &ps);这个语句对各个pgdat中的各个zone,进行平衡操作。这部分的代码在2.6内核和2.4内核中,相差甚远,替换掉了原来的kswapd_balance_pgdat函数。
可以考虑对这个函数进行调试,相信能够发现很多关键性参数的用法。

来自:http://liu783129.blog.hexun.com/2763642_d.html

你可能感兴趣的:(算法,linux,redhat,struct,null,UP)