int watermark_boost_factor __read_mostly =15000;// watermark_scale_factor默认为10, 取值范围: 1 ~ 1000// 可以通过/proc/sys/vm/watermark_scale_factor设置int watermark_scale_factor =10;// 设置每个zone的min, low和high水位staticvoid__setup_per_zone_wmarks(void){// 将总警戒水位值单位由kb转换为页数unsignedlong pages_min = min_free_kbytes >>(PAGE_SHIFT -10);unsignedlong lowmem_pages =0;structzone*zone;unsignedlong flags;/* Calculate total number of !ZONE_HIGHMEM pages */for_each_zone(zone){// highmem(ZONE_HIGHMEM和ZONE_MOVEABLE)if(!is_highmem(zone))// 计算lowmem(ZONE_DMA和ZONE_NORMAL)总的可管理内存
lowmem_pages +=zone_managed_pages(zone);}for_each_zone(zone){
u64 tmp;spin_lock_irqsave(&zone->lock, flags);// 总警戒水位 * zone->managed_pages
tmp =(u64)pages_min *zone_managed_pages(zone);// 1. 相当于先计算zone->managed_pages占总managed_pages的比例;// 2. 然后将这个比例 * 总警戒水位, 得到此zone的警戒水位do_div(tmp, lowmem_pages);// 这里不再考虑highmem的情况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 WMARK_HIGH-WMARK_LOW and (WMARK_LOW-WMARK_MIN)
* deltas control asynch page reclaim, and so should
* not be capped for highmem.
*/unsignedlong min_pages;
min_pages =zone_managed_pages(zone)/1024;
min_pages =clamp(min_pages, SWAP_CLUSTER_MAX,128UL);
zone->_watermark[WMARK_MIN]= min_pages;}else{/*
* If it's a lowmem zone, reserve a number of pages
* proportionate to the zone's size.
*/// 更新zone的警戒水位
zone->_watermark[WMARK_MIN]= tmp;}/*
* Set the kswapd watermarks distance according to the
* scale factor in proportion to available memory, but
* ensure a minimum size on small systems.
*/// 取以下两者之间的最大值// 1. 计算警戒水位的一半// 2. 计算zone->managed_pages的比例(0.1% ~ 10%), watermark_scale_factor越大tmp越大
tmp =max_t(u64, tmp >>2,mult_frac(zone_managed_pages(zone),
watermark_scale_factor,10000));// 低水位 = 警戒水位 + tmp
zone->_watermark[WMARK_LOW]=min_wmark_pages(zone)+ tmp;// 高水位 = 警戒水位 + tmp * 2
zone->_watermark[WMARK_HIGH]=min_wmark_pages(zone)+ tmp *2;
zone->watermark_boost =0;spin_unlock_irqrestore(&zone->lock, flags);}/* update totalreserve_pages */// 计算总的预留内存[见1.2.2节]calculate_totalreserve_pages();}