min_free_kbytes
min_free_kbytes:
This is used to force the Linux VM to keep a minimum number
of kilobytes free.
就是系统运行需要的最小内存。
2081 static int __init init_per_zone_pages_min(void)
2082 {
2083 unsigned long lowmem_kbytes;
2084
2085 lowmem_kbytes = nr_free_buffer_pages() * (PAGE_SIZE >> 10);
2086 printk(KERN_ERR "init_per_zone_pages_min\r\n");
2087
2088 min_free_kbytes = int_sqrt(lowmem_kbytes * 16);
2089 printk(KERN_ERR "min_free_kbytes=%x\r\n",min_free_kbytes);
2090 if (min_free_kbytes < 128)
2091 min_free_kbytes = 128;
2092 if (min_free_kbytes > 65536)
2093 min_free_kbytes = 65536;
2094 printk(KERN_ERR "min_free_kbytes=%x\r\n",min_free_kbytes);
2095 setup_per_zone_pages_min();
2096 setup_per_zone_lowmem_reserve();
2097 return 0;
2098 }
1007 unsigned int nr_free_buffer_pages(void)
1008 {
1010 return nr_free_zone_pages(GFP_USER & GFP_ZONEMASK);
1011 }
980 static unsigned int nr_free_zone_pages(int offset)
981 {
982 pg_data_t *pgdat;
983 unsigned int sum = 0;
984 printk(KERN_ERR "tom %s(%s:%u) offset=%x\n", __FUNCTION__, __FILE__, __LINE__,offset);
985
986 for_each_pgdat(pgdat) {
987 struct zonelist *zonelist = pgdat->node_zonelists + offset;
988 struct zone **zonep = zonelist->zones;
989 struct zone *zone;
990
991 for (zone = *zonep++; zone; zone = *zonep++) {
992 unsigned long size = zone->present_pages;
993 unsigned long high = zone->pages_high;
994 if (size > high)
995 sum += size - high;
996 printk(KERN_ERR "tom present_pages=%x pages_high=%x sum=%x\r\n",size,highm,sum);
997 }
998 }
999
1000 printk(KERN_ERR "tom sum=%x\r\n",sum);
1001 return sum;
1002 }
说明:
1)nr_free_zone_pages传进来的offset=0,则会调用策略node_zonelists中的第1条策略,第1条策略是先NORMAL ZONE,然后DMA ZONE。因为pages_high是0,
present_pages在函数free_area_init_core初始化为zone的页帧个数,显然DMA ZONE的页帧个数是0x1000,NORMAL ZONE的个数是0x37000,这样sum=0x37000+0x1000=0x38000个页帧。
2)在函数init_per_zone_pages_min中, lowmem_kbytes = nr_free_buffer_pages() * (PAGE_SIZE >> 10)就是把页帧转化为大小,以KByte计算。*PAGE_SIZE就是转换为Byte,>>10转化为KByte。
3) min_free_kbytes = int_sqrt(lowmem_kbytes * 16)就是把lowmem_kbytes先乘以16,然后再开方,这样得到 min_free_kbytes。
page_min,page_low和page_high赋值
2005 static void setup_per_zone_pages_min(void)
2006 {
2007 unsigned long pages_min = min_free_kbytes >> (PAGE_SHIFT - 10);
2008 unsigned long lowmem_pages = 0;
2009 struct zone *zone;
2010 unsigned long flags;
2011
2012 printk(KERN_ERR "tom %s(%s:%u) min_free_kbytes=%x\r\n", __FUNCTION__, __FILE__, __LINE__,min_free_kbytes);
2013 printk(KERN_ERR "tom pages_min=%x\r\n",pages_min);
2014 /* Calculate total number of !ZONE_HIGHMEM pages */
2015 for_each_zone(zone) {
2016 if (!is_highmem(zone))
2017 lowmem_pages += zone->present_pages;
2011
2012 printk(KERN_ERR "tom %s(%s:%u) min_free_kbytes=%x\r\n", __FUNCTION__, __FILE__, __LINE__,min_free_kbytes);
2013 printk(KERN_ERR "tom pages_min=%x\r\n",pages_min);
2014 /* Calculate total number of !ZONE_HIGHMEM pages */
2015 for_each_zone(zone) {
2016 if (!is_highmem(zone))
2017 lowmem_pages += zone->present_pages;
2018 printk(KERN_ERR "tom lowmem_pages=%x\n",lowmem_pages);
2019 }
2007 unsigned long pages_min = min_free_kbytes >> (PAGE_SHIFT - 10);
2008 unsigned long lowmem_pages = 0;
2009 struct zone *zone;
2010 unsigned long flags;
2011
2012 printk(KERN_ERR "tom %s(%s:%u) min_free_kbytes=%x\r\n", __FUNCTION__, __FILE__, __LINE__,min_free_kbytes);
2013 printk(KERN_ERR "tom pages_min=%x\r\n",pages_min);
2014 /* Calculate total number of !ZONE_HIGHMEM pages */
2015 for_each_zone(zone) {
2016 if (!is_highmem(zone))
2017 lowmem_pages += zone->present_pages;
2018 printk(KERN_ERR "tom lowmem_pages=%x\n",lowmem_pages);
2019 }
2020
2021 for_each_zone(zone) {
2022 spin_lock_irqsave(&zone->lru_lock, flags);
2023 if (is_highmem(zone)) {
2024 /*
2025 * Often, highmem doesn't need to reserve any pages.
2026 * But the pages_min/low/high values are also used for
2027 * batching up page reclaim activity so we need a
2028 * decent value here.
2029 */
2030 int min_pages;
2031
2032 min_pages = zone->present_pages / 1024;
2033 printk(KERN_ERR "tom 111 min_pages=%x\r\n",min_pages);
2034 if (min_pages < SWAP_CLUSTER_MAX)
2035 min_pages = SWAP_CLUSTER_MAX;
2036 if (min_pages > 128)
2037 min_pages = 128;
2038 zone->pages_min = min_pages;
2039 printk(KERN_ERR "tom min_pages=%x SWAP_CLUSTER_MAX=%x zone->pages_min=%x\n",min_pages,SWAP_CLUSTER_MAX,zone->pages_min);
2040 } else {
2041 /* if it's a lowmem zone, reserve a number of pages
2042 * proportionate to the zone's size.
2043 */
2044 zone->pages_min = (pages_min * zone->present_pages) /
2045 lowmem_pages;
2046 printk(KERN_ERR "tom zone->pages_min=%x\r\n",zone->pages_min);
2047 }
2048 /*
2049 * When interpreting these watermarks, just keep in mind that:
2050 * zone->pages_min == (zone->pages_min * 4) / 4;
2051 */
2052 zone->pages_low = (zone->pages_min * 5) / 4;
2053 zone->pages_high = (zone->pages_min * 6) / 4;
2054 printk(KERN_ERR "tom zone->pages_low_min=%x zone->pages_high=%x\r\n",zone->pages_low,zone->pages_high);
2055 spin_unlock_irqrestore(&zone->lru_lock, flags);
2056 }
2057 }
说明:
1)如果不是高端zone,pages_min就是DMA zone和NORMAL ZONE两个区的需要最小页帧的和,lowmem_pages是DMA zone和NORMAL ZONE两个区的总页帧,然后DMA ZONE的页帧除以lowmem_pages再乘以总的最小页帧的和,便得到DMA_ZONE的最小页帧数,同理得到NORMAL_ZONE区的最小页帧数。
2)如果是高端zone,把high zone的页帧数除以1024,得到min_pages,比较min_pages是否小于SWAP_CLUSTER_MAX,如果是,则 min_pages=SWAP_CLUSTER_MAX=0x20;如果min_pages大于128,
则min_pages=128。显然0x7cffd/1024>128,则min_pages=128
3)相应zone的pages_low是pages_min的5/4倍,pages_high是pages_min的6/4倍。