1、内存域水印值:需要为关键性分配保留的内存空间的最小值;该值保存在全局变量min_free_kbytes中

2、内存域水印值的计算由函数init_per_zone_pages_min完成:

/*
* Initialise min_free_kbytes.
*
* For small machines we want it small (128k min). For large machines
* we want it large (64MB max). But it is not linear, because network
* bandwidth does not increase linearly with machine size. We use
*
* min_free_kbytes = 4 * sqrt(lowmem_kbytes), for better accuracy:
* min_free_kbytes = sqrt(lowmem_kbytes * 16)
*
* which yields
*
* 16MB: 512k
* 32MB: 724k
* 64MB: 1024k
* 128MB: 1448k
* 256MB: 2048k
* 512MB: 2896k
* 1024MB: 4096k
* 2048MB: 5792k
* 4096MB: 8192k
* 8192MB: 11584k
* 16384MB: 16384k
*/
static int __init init_per_zone_pages_min(void)
{
unsigned long lowmem_kbytes; lowmem_kbytes = nr_free_buffer_pages() * (PAGE_SIZE >> 10); min_free_kbytes = int_sqrt(lowmem_kbytes * 16);
if (min_free_kbytes < 128)
min_free_kbytes = 128;
if (min_free_kbytes > 65536)
min_free_kbytes = 65536;
setup_per_zone_pages_min();
setup_per_zone_lowmem_reserve();
return 0;
}

3、setup_per_zone_pages_min设置struct zone的pages_min、pages_low、pages_high成员

/**
* setup_per_zone_pages_min - called when min_free_kbytes changes.
*
* Ensures that the pages_{min,low,high} values for each zone are set correctly
* with respect to min_free_kbytes.
*/
void setup_per_zone_pages_min(void)
{
unsigned long pages_min = min_free_kbytes >> (PAGE_SHIFT - 10);
unsigned long lowmem_pages = 0;
struct zone *zone;
unsigned long flags; /* Calculate total number of !ZONE_HIGHMEM pages */
for_each_zone(zone) {
if (!is_highmem(zone))
lowmem_pages += zone->present_pages;
} for_each_zone(zone) {
u64 tmp; spin_lock_irqsave(&zone->lru_lock, flags);
tmp = (u64)pages_min * zone->present_pages;
do_div(tmp, lowmem_pages);
if (is_highmem(zone)) {
/*
* __GFP_HIGH and PF_MEMALLOC allocations usually don't
* need highmem pages, so cap pages_min to a small
* value here.
*
* The (pages_high-pages_low) and (pages_low-pages_min)
* deltas controls asynch page reclaim, and so should
* not be capped for highmem.
*/
int min_pages; min_pages = zone->present_pages / 1024;
if (min_pages < SWAP_CLUSTER_MAX)
min_pages = SWAP_CLUSTER_MAX;
if (min_pages > 128)
min_pages = 128;
zone->pages_min = min_pages;
} else {
/*
* If it's a lowmem zone, reserve a number of pages
* proportionate to the zone's size.
*/
zone->pages_min = tmp;
} zone->pages_low = zone->pages_min + (tmp >> 2);
zone->pages_high = zone->pages_min + (tmp >> 1);
setup_zone_migrate_reserve(zone);
spin_unlock_irqrestore(&zone->lru_lock, flags);
} /* update totalreserve_pages */
calculate_totalreserve_pages();
}

4、setup_per_zone_lowmem_reserve主要用作设置lowmem_reserve值

/*
* setup_per_zone_lowmem_reserve - called whenever
* sysctl_lower_zone_reserve_ratio changes. Ensures that each zone
* has a correct pages reserved value, so an adequate number of
* pages are left in the zone after a successful __alloc_pages().
*/
static void setup_per_zone_lowmem_reserve(void)
{
struct pglist_data *pgdat;
enum zone_type j, idx; for_each_online_pgdat(pgdat) {
for (j = 0; j < MAX_NR_ZONES; j++) {
struct zone *zone = pgdat->node_zones + j;
unsigned long present_pages = zone->present_pages; zone->lowmem_reserve[j] = 0; idx = j;
while (idx) {
struct zone *lower_zone; idx--; if (sysctl_lowmem_reserve_ratio[idx] < 1)
sysctl_lowmem_reserve_ratio[idx] = 1; lower_zone = pgdat->node_zones + idx;
lower_zone->lowmem_reserve[j] = present_pages /
sysctl_lowmem_reserve_ratio[idx];
present_pages += lower_zone->present_pages;
}
}
} /* update totalreserve_pages */
calculate_totalreserve_pages();
}

除数的默认值,对低端内存是256,对高端内存是32

/*
* results with 256, 32 in the lowmem_reserve sysctl:
* 1G machine -> (16M dma, 800M-16M normal, 1G-800M high)
* 1G machine -> (16M dma, 784M normal, 224M high)
* NORMAL allocation will leave 784M/256 of ram reserved in the ZONE_DMA
* HIGHMEM allocation will leave 224M/32 of ram reserved in ZONE_NORMAL
* HIGHMEM allocation will (224M+784M)/256 of ram reserved in ZONE_DMA
*
* TBD: should special case ZONE_DMA32 machines here - in those we normally
* don't need any ZONE_NORMAL reservation
*/
int sysctl_lowmem_reserve_ratio[MAX_NR_ZONES-1] = {
#ifdef CONFIG_ZONE_DMA
256,
#endif
#ifdef CONFIG_ZONE_DMA32
256,
#endif
#ifdef CONFIG_HIGHMEM
32,
#endif
32,
};

最新文章

  1. DFA 最小化
  2. FindBugs插件
  3. 微信扫码支付asp.net(C#)实现步骤
  4. Xubuntu下Mentohust认证(校园网用户)
  5. iOS 图片填充 UIImageView
  6. SCALA中的函数式编程
  7. 有关CUBLAS中的矩阵乘法函数
  8. ssh分发秘钥时出现错误“Permission denied (publickey,gssapi-keyex,gssapi-with-mic)”
  9. java servlet的执行流程
  10. vue非父子组件之间的通信
  11. jsp请求java返回pdf、excel与word
  12. pythonweb服务器编程(四)
  13. 【五】jquery之事件(focus事件与blur事件)[提示语的出现及消失时机]
  14. LG1397 [NOI2013]矩阵游戏
  15. Libpacp 深度剖析
  16. Matplotlib的初次使用
  17. Kali-linux使用社会工程学工具包(SET)
  18. Linux下Tomcat性能优化--文件句柄数增大
  19. 静态分析工具PMD使用说明
  20. for循环删除列表中元素遇到的漏删的问题(python)

热门文章

  1. 视频色彩空间RGB、YUV、YCbCr
  2. Java基础 三目运算符 用if-else对其进行解释
  3. React中跨域问题的完美解决方案
  4. Linux_CentOS中Mongodb4.x 安装调试、远程管理、配置 mongodb 管理员密码
  5. Pycharm连接远程服务器并进行代码上传+远程调试
  6. 论文阅读:FaceBoxes: A CPU Real-time Face Detector with High Accuracy
  7. [LeetCode] 191. Number of 1 Bits 二进制数1的个数
  8. [LeetCode] 309. Best Time to Buy and Sell Stock with Cooldown 买卖股票的最佳时间有冷却期
  9. redis(1)---linux下的安装
  10. Java中缓存的介绍