Commit 7ace9917 authored by Mel Gorman's avatar Mel Gorman Committed by Linus Torvalds

mm, meminit: allow early_pfn_to_nid to be used during runtime

early_pfn_to_nid() historically was inherently not SMP safe but only
used during boot which is inherently single threaded or during hotplug
which is protected by a giant mutex.

With deferred memory initialisation there was a thread-safe version
introduced and the early_pfn_to_nid would trigger a BUG_ON if used
unsafely.  Memory hotplug hit that check.  This patch makes
early_pfn_to_nid introduces a lock to make it safe to use during
hotplug.
Signed-off-by: default avatarMel Gorman <mgorman@suse.de>
Reported-by: default avatarAlex Ng <alexng@microsoft.com>
Tested-by: default avatarAlex Ng <alexng@microsoft.com>
Acked-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
Cc: Nicolai Stange <nicstange@gmail.com>
Cc: Dave Hansen <dave.hansen@intel.com>
Cc: Fengguang Wu <fengguang.wu@intel.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent de54b9ac
...@@ -981,21 +981,21 @@ static void __init __free_pages_boot_core(struct page *page, ...@@ -981,21 +981,21 @@ static void __init __free_pages_boot_core(struct page *page,
#if defined(CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID) || \ #if defined(CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID) || \
defined(CONFIG_HAVE_MEMBLOCK_NODE_MAP) defined(CONFIG_HAVE_MEMBLOCK_NODE_MAP)
/* Only safe to use early in boot when initialisation is single-threaded */
static struct mminit_pfnnid_cache early_pfnnid_cache __meminitdata; static struct mminit_pfnnid_cache early_pfnnid_cache __meminitdata;
int __meminit early_pfn_to_nid(unsigned long pfn) int __meminit early_pfn_to_nid(unsigned long pfn)
{ {
static DEFINE_SPINLOCK(early_pfn_lock);
int nid; int nid;
/* The system will behave unpredictably otherwise */ spin_lock(&early_pfn_lock);
BUG_ON(system_state != SYSTEM_BOOTING);
nid = __early_pfn_to_nid(pfn, &early_pfnnid_cache); nid = __early_pfn_to_nid(pfn, &early_pfnnid_cache);
if (nid >= 0) if (nid < 0)
nid = 0;
spin_unlock(&early_pfn_lock);
return nid; return nid;
/* just returns 0 */
return 0;
} }
#endif #endif
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment