• Xishi Qiu's avatar
    mm: setup pageblock_order before it's used by sparsemem · ca57df79
    Xishi Qiu authored
    On architectures with CONFIG_HUGETLB_PAGE_SIZE_VARIABLE set, such as
    Itanium, pageblock_order is a variable with default value of 0.  It's set
    to the right value by set_pageblock_order() in function
    free_area_init_core().
    
    But pageblock_order may be used by sparse_init() before free_area_init_core()
    is called along path:
    sparse_init()
        ->sparse_early_usemaps_alloc_node()
    	->usemap_size()
    	    ->SECTION_BLOCKFLAGS_BITS
    		->((1UL << (PFN_SECTION_SHIFT - pageblock_order)) *
    NR_PAGEBLOCK_BITS)
    
    The uninitialized pageblock_size will cause memory wasting because
    usemap_size() returns a much bigger value then it's really needed.
    
    For example, on an Itanium platform,
    sparse_init() pageblock_order=0 usemap_size=24576
    free_area_init_core() before pageblock_order=0, usemap_size=24576
    free_area_init_core() after pageblock_order=12, usemap_size=8
    
    That means 24K memory has been wasted for each section, so fix it by calling
    set_pageblock_order() from sparse_init().
    Signed-off-by: default avatarXishi Qiu <qiuxishi@huawei.com>
    Signed-off-by: default avatarJiang Liu <liuj97@gmail.com>
    Cc: Tony Luck <tony.luck@intel.com>
    Cc: Yinghai Lu <yinghai@kernel.org>
    Cc: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
    Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
    Cc: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
    Cc: David Rientjes <rientjes@google.com>
    Cc: Keping Chen <chenkeping@huawei.com>
    Cc: <stable@vger.kernel.org>
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    ca57df79
sparse.c 20.6 KB