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: Mel Gorman <mgorman@suse.de> Reported-by: Alex Ng <alexng@microsoft.com> Tested-by: Alex Ng <alexng@microsoft.com> Acked-by: Peter 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: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
de54b9ac25
commit
7ace991707
|
@ -981,21 +981,21 @@ static void __init __free_pages_boot_core(struct page *page,
|
|||
|
||||
#if defined(CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID) || \
|
||||
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;
|
||||
|
||||
int __meminit early_pfn_to_nid(unsigned long pfn)
|
||||
{
|
||||
static DEFINE_SPINLOCK(early_pfn_lock);
|
||||
int nid;
|
||||
|
||||
/* The system will behave unpredictably otherwise */
|
||||
BUG_ON(system_state != SYSTEM_BOOTING);
|
||||
|
||||
spin_lock(&early_pfn_lock);
|
||||
nid = __early_pfn_to_nid(pfn, &early_pfnnid_cache);
|
||||
if (nid >= 0)
|
||||
return nid;
|
||||
/* just returns 0 */
|
||||
return 0;
|
||||
if (nid < 0)
|
||||
nid = 0;
|
||||
spin_unlock(&early_pfn_lock);
|
||||
|
||||
return nid;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
Loading…
Reference in New Issue