• Oscar Salvador's avatar
    mm: Avoid calling build_all_zonelists_init under hotplug context · 23feab18
    Oscar Salvador authored
    Recently a customer of ours experienced a crash when booting the
    system while enabling memory-hotplug.
    
    The problem is that Normal zones on different nodes don't get their private
    zone->pageset allocated, and keep sharing the initial boot_pageset.
    The sharing between zones is normally safe as explained by the comment for
    boot_pageset - it's a percpu structure, and manipulations are done with
    disabled interrupts, and boot_pageset is set up in a way that any page placed
    on its pcplist is immediately flushed to shared zone's freelist, because
    pcp->high == 1.
    However, the hotplug operation updates pcp->high to a higher value as it
    expects to be operating on a private pageset.
    
    The problem is in build_all_zonelists(), which is called when the first range
    of pages is onlined for the Normal zone of node X or Y:
    
    	if (system_state == SYSTEM_BOOTING) {
    		build_all_zonelists_init();
    	} else {
    	#ifdef CONFIG_MEMORY_HOTPLUG
    		if (zone)
    			setup_zone_pag...
    23feab18
memory_hotplug.c 57 KB