mm/hotplug: correctly add new zone to all other nodes' zone lists
Jiang Liu authored
commit 08dff7b7

 upstream.

When online_pages() is called to add new memory to an empty zone, it
rebuilds all zone lists by calling build_all_zonelists().  But there's a
bug which prevents the new zone to be added to other nodes' zone lists.

online_pages() {
	build_all_zonelists()
	.....
	node_set_state(zone_to_nid(zone), N_HIGH_MEMORY)
}

Here the node of the zone is put into N_HIGH_MEMORY state after calling
build_all_zonelists(), but build_all_zonelists() only adds zones from
nodes in N_HIGH_MEMORY state to the fallback zone lists.
build_all_zonelists()

    ->__build_all_zonelists()
	->build_zonelists()
	    ->find_next_best_node()
		->for_each_node_state(n, N_HIGH_MEMORY)

So memory in the new zone will never be used by other nodes, and it may
cause strange behavor when system is under memory pressure.  So put node
into N_HIGH_MEMORY state before calling build_all_zonelists().
Signed-off-by: default avatarJianguo Wu <wujianguo@huawei.com>
Signed-off-by: default avatarJiang Liu <liuj97@gmail.com>
Cc: Mel Gorman <mgorman@suse.de>
Cc: Michal Hocko <mhocko@suse.cz>
Cc: Minchan Kim <minchan@kernel.org>
Cc: Rusty Russell <rusty@rustcorp.com.au>
Cc: Yinghai Lu <yinghai@kernel.org>
Cc: Tony Luck <tony.luck@intel.com>
Cc: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Cc: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
Cc: David Rientjes <rientjes@google.com>
Cc: Keping Chen <chenkeping@huawei.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
[bwh: Backported to 3.2: adjust context]
Signed-off-by: default avatarBen Hutchings <ben@decadent.org.uk>
Cc: Qiang Huang <h.huangqiang@huawei.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
446327d6
Name Last commit Last update
..
Kconfig Merge branch 'master' into x86/memblock
Kconfig.debug mm: more intensive memory corruption debugging
Makefile Cross Memory Attach
backing-dev.c backing-dev: fix wakeup timer races with bdi_unregister()
bootmem.c mm: sparse: fix usemap allocation above node descriptor section
bounce.c mm: remove the second argument of k[un]map_atomic()
cleancache.c mm: cleancache: Use __read_mostly as appropiate.
compaction.c mm: compaction: fix echo 1 > compact_memory return error issue
debug-pagealloc.c mm, x86: Remove debug_pagealloc_enabled
dmapool.c mm: dmapool: use provided gfp flags for all dma_alloc_coherent() calls
fadvise.c mm/fadvise.c: drain all pagevecs if POSIX_FADV_DONTNEED fails to discard all pages
failslab.c switch debugfs to umode_t
filemap.c radix-tree: use iterators in find_get_pages* functions
filemap_xip.c mm/filemap_xip.c: fix race condition in xip_file_fault()
fremap.c mm: delete various needless include <linux/module.h>
highmem.c Merge branch 'modsplit-Oct31_2011' of git://git.kernel.org/pub/scm/linux/kernel/git/paulg/linux
huge_memory.c mm/huge_memory.c: fix potential NULL pointer dereference
hugetlb.c mm: hugetlbfs: fix hugetlbfs optimization
hwpoison-inject.c HWPOISON: Clean up memory_failure() vs. __memory_failure()
init-mm.c atomic: use <linux/atomic.h>
internal.h mm: setup pageblock_order before it's used by sparsemem
kmemcheck.c kmemcheck: add hooks for the page allocator
kmemleak-test.c kmemleak: remove memset by using kzalloc
kmemleak.c kmemleak: Disable early logging when kmemleak is off by default
ksm.c ksm: cleanup: introduce find_mergeable_vma()
maccess.c
madvise.c
memblock.c
memcontrol.c
memory-failure.c
memory.c
memory_hotplug.c
mempolicy.c
mempool.c
migrate.c
mincore.c
mlock.c
mm_init.c
mmap.c
mmu_context.c
mmu_notifier.c
mmzone.c
mprotect.c
mremap.c
msync.c
nobootmem.c
nommu.c
oom_kill.c
page-writeback.c
page_alloc.c
page_cgroup.c
page_io.c
page_isolation.c
pagewalk.c
percpu-km.c
percpu-vm.c
percpu.c
pgtable-generic.c
prio_tree.c
process_vm_access.c
quicklist.c
readahead.c
rmap.c
shmem.c
slab.c
slob.c
slub.c
sparse-vmemmap.c
sparse.c
swap.c
swap_state.c
swapfile.c
thrash.c
truncate.c
util.c
vmalloc.c
vmscan.c
vmstat.c