• Charan Teja Reddy's avatar
    mm, page_alloc: reset the zone->watermark_boost early · aa092591
    Charan Teja Reddy authored
    Updating the zone watermarks by any means, like min_free_kbytes,
    water_mark_scale_factor etc, when ->watermark_boost is set will result in
    higher low and high watermarks than the user asked.
    
    Below are the steps to reproduce the problem on system setup of Android
    kernel running on Snapdragon hardware.
    
    1) Default settings of the system are as below:
    
       #cat /proc/sys/vm/min_free_kbytes = 5162
       #cat /proc/zoneinfo | grep -e boost -e low -e "high " -e min -e Node
    	Node 0, zone   Normal
    		min      797
    		low      8340
    		high     8539
    
    2) Monitor the zone->watermark_boost(by adding a debug print in the
       kernel) and whenever it is greater than zero value, write the same
       value of min_free_kbytes obtained from step 1.
    
       #echo 5162 > /proc/sys/vm/min_free_kbytes
    
    3) Then read the zone watermarks in the system while the
       ->watermark_boost is zero.  This should show the same values of
       watermarks as step 1 but shown a higher values than asked.
    
       #cat /proc/zoneinfo | grep -e boost -e low -e "high " -e min -e Node
    	Node 0, zone   Normal
    		min      797
    		low      21148
    		high     21347
    
    These higher values are because of updating the zone watermarks using the
    macro min_wmark_pages(zone) which also adds the zone->watermark_boost.
    
    	#define min_wmark_pages(z) (z->_watermark[WMARK_MIN] +
    					z->watermark_boost)
    
    So the steps that lead to the issue are:
    
    1) On the extfrag event, watermarks are boosted by storing the required
       value in ->watermark_boost.
    
    2) User tries to update the zone watermarks level in the system through
       min_free_kbytes or watermark_scale_factor.
    
    3) Later, when kswapd woke up, it resets the zone->watermark_boost to
       zero.
    
    In step 2), we use the min_wmark_pages() macro to store the watermarks
    in the zone structure thus the values are always offsetted by
    ->watermark_boost value. This can be avoided by resetting the
    ->watermark_boost to zero before it is used.
    Signed-off-by: default avatarCharan Teja Reddy <charante@codeaurora.org>
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    Reviewed-by: default avatarBaoquan He <bhe@redhat.com>
    Cc: Vinayak Menon <vinmenon@codeaurora.org>
    Link: http://lkml.kernel.org/r/1589457511-4255-1-git-send-email-charante@codeaurora.orgSigned-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    aa092591
page_alloc.c 241 KB