mm: meminit: make __early_pfn_to_nid SMP-safe and introduce meminit_pfn_in_nid
__early_pfn_to_nid() use static variables to cache recent lookups as memblock lookups are very expensive but it assumes that memory initialisation is single-threaded. Parallel initialisation of struct pages will break that assumption so this patch makes __early_pfn_to_nid() SMP-safe by requiring the caller to cache recent search information. early_pfn_to_nid() keeps the same interface but is only safe to use early in boot due to the use of a global static variable. meminit_pfn_in_nid() is an SMP-safe version that callers must maintain their own state for. Signed-off-by: Mel Gorman <mgorman@suse.de> Tested-by: Nate Zimmer <nzimmer@sgi.com> Tested-by: Waiman Long <waiman.long@hp.com> Tested-by: Daniel J Blueman <daniel@numascale.com> Acked-by: Pekka Enberg <penberg@kernel.org> Cc: Robin Holt <robinmholt@gmail.com> Cc: Nate Zimmer <nzimmer@sgi.com> Cc: Dave Hansen <dave.hansen@intel.com> Cc: Waiman Long <waiman.long@hp.com> Cc: Scott Norton <scott.norton@hp.com> Cc: "Luck, Tony" <tony.luck@intel.com> Cc: Ingo Molnar <mingo@elte.hu> Cc: "H. Peter Anvin" <hpa@zytor.com> Cc: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:

committed by
Linus Torvalds

parent
d70ddd7a5d
commit
8a942fdea5
@@ -1216,10 +1216,24 @@ void sparse_init(void);
|
||||
#define sparse_index_init(_sec, _nid) do {} while (0)
|
||||
#endif /* CONFIG_SPARSEMEM */
|
||||
|
||||
/*
|
||||
* During memory init memblocks map pfns to nids. The search is expensive and
|
||||
* this caches recent lookups. The implementation of __early_pfn_to_nid
|
||||
* may treat start/end as pfns or sections.
|
||||
*/
|
||||
struct mminit_pfnnid_cache {
|
||||
unsigned long last_start;
|
||||
unsigned long last_end;
|
||||
int last_nid;
|
||||
};
|
||||
|
||||
#ifdef CONFIG_NODES_SPAN_OTHER_NODES
|
||||
bool early_pfn_in_nid(unsigned long pfn, int nid);
|
||||
bool meminit_pfn_in_nid(unsigned long pfn, int node,
|
||||
struct mminit_pfnnid_cache *state);
|
||||
#else
|
||||
#define early_pfn_in_nid(pfn, nid) (1)
|
||||
#define early_pfn_in_nid(pfn, nid) (1)
|
||||
#define meminit_pfn_in_nid(pfn, nid, state) (1)
|
||||
#endif
|
||||
|
||||
#ifndef early_pfn_valid
|
||||
|
Reference in New Issue
Block a user