From 5544c66c59c54310f006562f71619fded84ea6ad Mon Sep 17 00:00:00 2001 From: Dave Hansen Date: Sat, 3 Sep 2005 15:54:29 -0700 Subject: [PATCH] --- yaml --- r: 6842 b: refs/heads/master c: 28ae55c98e4d16eac9a05a8a259d7763ef3aeb18 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/include/linux/mmzone.h | 1 + trunk/mm/sparse.c | 53 ++++++++++++++++++++++++++++-------- 3 files changed, 43 insertions(+), 13 deletions(-) diff --git a/[refs] b/[refs] index f39ebee76f64..9a3385beccf3 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 3e347261a80b57df792ab9464b5f0ed59add53a8 +refs/heads/master: 28ae55c98e4d16eac9a05a8a259d7763ef3aeb18 diff --git a/trunk/include/linux/mmzone.h b/trunk/include/linux/mmzone.h index 79cf578e21b9..5ed471b58f4f 100644 --- a/trunk/include/linux/mmzone.h +++ b/trunk/include/linux/mmzone.h @@ -588,6 +588,7 @@ static inline int pfn_valid(unsigned long pfn) void sparse_init(void); #else #define sparse_init() do {} while (0) +#define sparse_index_init(_sec, _nid) do {} while (0) #endif /* CONFIG_SPARSEMEM */ #ifdef CONFIG_NODES_SPAN_OTHER_NODES diff --git a/trunk/mm/sparse.c b/trunk/mm/sparse.c index fa01292157a9..347249a4917a 100644 --- a/trunk/mm/sparse.c +++ b/trunk/mm/sparse.c @@ -6,6 +6,7 @@ #include #include #include +#include #include /* @@ -22,27 +23,55 @@ struct mem_section mem_section[NR_SECTION_ROOTS][SECTIONS_PER_ROOT] #endif EXPORT_SYMBOL(mem_section); -static void sparse_alloc_root(unsigned long root, int nid) -{ #ifdef CONFIG_SPARSEMEM_EXTREME - mem_section[root] = alloc_bootmem_node(NODE_DATA(nid), PAGE_SIZE); -#endif +static struct mem_section *sparse_index_alloc(int nid) +{ + struct mem_section *section = NULL; + unsigned long array_size = SECTIONS_PER_ROOT * + sizeof(struct mem_section); + + section = alloc_bootmem_node(NODE_DATA(nid), array_size); + + if (section) + memset(section, 0, array_size); + + return section; } -static void sparse_index_init(unsigned long section, int nid) +static int sparse_index_init(unsigned long section_nr, int nid) { - unsigned long root = SECTION_NR_TO_ROOT(section); + static spinlock_t index_init_lock = SPIN_LOCK_UNLOCKED; + unsigned long root = SECTION_NR_TO_ROOT(section_nr); + struct mem_section *section; + int ret = 0; if (mem_section[root]) - return; + return -EEXIST; - sparse_alloc_root(root, nid); + section = sparse_index_alloc(nid); + /* + * This lock keeps two different sections from + * reallocating for the same index + */ + spin_lock(&index_init_lock); - if (mem_section[root]) - memset(mem_section[root], 0, PAGE_SIZE); - else - panic("memory_present: NO MEMORY\n"); + if (mem_section[root]) { + ret = -EEXIST; + goto out; + } + + mem_section[root] = section; +out: + spin_unlock(&index_init_lock); + return ret; } +#else /* !SPARSEMEM_EXTREME */ +static inline int sparse_index_init(unsigned long section_nr, int nid) +{ + return 0; +} +#endif + /* Record a memory area against a node. */ void memory_present(int nid, unsigned long start, unsigned long end) {