min_free_kbytes 的初始化

min_free_kbytes的作用

当请求分配内存时,如果有足够的内存,则分配成功。如果没有,则要阻塞,释放内存,再来分配内存。原子请求不能被阻塞,如果分配不到,则失败。内核为了尽量避免原子请求失败,预留了一个页池框,在内存不足时使用。这个页池框的大小就是min_free_kbytes。

这段引自《深入理解Linux内核(第三版)(中文版)》Page302

min_free_kbytes的设置

代码调用关系

init_per_zone_wmark_min()(\linux\mm\page_alloc.c) 中进行初始化,dump_stack()的结果:

[    0.053007] [init_per_zone_wmark_min 6792] min_free_kbytes: 1024.
[    0.053067] [<c0210710>] (unwind_backtrace) from [<c020bb54>] (show_stack+0x10/0x14)
[    0.053083] [<c020bb54>] (show_stack) from [<c04fc8bc>] (dump_stack+0x84/0x98)
[    0.053100] [<c04fc8bc>] (dump_stack) from [<c0e33870>] (init_per_zone_wmark_min+0x2c/0x13c)
[    0.053127] [<c0e33870>] (init_per_zone_wmark_min) from [<c0201898>] (do_one_initcall+0x54/0x190)
[    0.053153] [<c0201898>] (do_one_initcall) from [<c0e00e74>] (kernel_init_freeable+0x158/0x1e4)
[    0.053180] [<c0e00e74>] (kernel_init_freeable) from [<c09b68d4>] (kernel_init+0x8/0x114)
[    0.053203] [<c09b68d4>] (kernel_init) from [<c0208628>] (ret_from_fork+0x14/0x2c)
[    0.053222] [init_per_zone_wmark_min 6797] nr_free_buffer_pages: 162930.
[    0.053233] [init_per_zone_wmark_min 6798] lowmem_kbytes: 651720.
[    0.053245] [init_per_zone_wmark_min 6802] new_min_free_kbytes: 3229.
[    0.053256] [init_per_zone_wmark_min 6803] user_min_free_kbytes: -1.
[    0.053267] [init_per_zone_wmark_min 6808] min_free_kbytes: 3229.
[    0.053285] [init_per_zone_wmark_min 6822] min_free_kbytes: 3229.

代码流程就是:
kernel_init -- kernel_init_freeable -- do_one_initcall -- init_per_zone_wmark_min 

代码逻辑

int min_free_kbytes = 1024; //初始值设为1024
int user_min_free_kbytes = -1;
int watermark_scale_factor = 10;
int __meminit init_per_zone_wmark_min(void)
{
	unsigned long lowmem_kbytes;
	int new_min_free_kbytes;
	
	/*
	nr_free_buffer_pages() 获取free_pages
	根据公式  计算 new_min_free_kbytes 
	*/
	lowmem_kbytes = nr_free_buffer_pages() * (PAGE_SIZE >> 10);
	new_min_free_kbytes = int_sqrt(lowmem_kbytes * 16);

	if (new_min_free_kbytes > user_min_free_kbytes) {
		min_free_kbytes = new_min_free_kbytes;
		// min_free_kbytes必须在[128, 65536]之间
		if (min_free_kbytes < 128)
			min_free_kbytes = 128;
		if (min_free_kbytes > 65536)
			min_free_kbytes = 65536;
	} else {
		pr_warn("min_free_kbytes is not updated to %d because user defined value %d is preferred\n", 
		         new_min_free_kbytes, user_min_free_kbytes);
	}

   ......
}
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页