diff options
author | Andy Whitcroft <apw@shadowen.org> | 2006-06-23 05:03:41 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-06-23 10:42:51 -0400 |
commit | 30c253e6da655d73eb8bfe2adca9b8f4d82fb81e (patch) | |
tree | 97c49ad364855b95ce52d97a62d176a077ff2a85 | |
parent | ddc2e812d592457747c4367fb73edcaa8e1e49ff (diff) |
[PATCH] sparsemem: record nid during memory present
Record the node id as we mark sections for instantiation. Use this nid
during instantiation to direct allocations.
Signed-off-by: Andy Whitcroft <apw@shadowen.org>
Cc: Mike Kravetz <kravetz@us.ibm.com>
Cc: Dave Hansen <haveblue@us.ibm.com>
Cc: Mel Gorman <mel@csn.ul.ie>
Cc: Bob Picco <bob.picco@hp.com>
Cc: Jack Steiner <steiner@sgi.com>
Cc: Yasunori Goto <y-goto@jp.fujitsu.com>
Cc: Martin Bligh <mbligh@google.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r-- | include/linux/mmzone.h | 5 | ||||
-rw-r--r-- | mm/sparse.c | 22 |
2 files changed, 25 insertions, 2 deletions
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h index e82fc1a52cd0..d6120fa69116 100644 --- a/include/linux/mmzone.h +++ b/include/linux/mmzone.h | |||
@@ -509,6 +509,10 @@ struct mem_section { | |||
509 | * pages. However, it is stored with some other magic. | 509 | * pages. However, it is stored with some other magic. |
510 | * (see sparse.c::sparse_init_one_section()) | 510 | * (see sparse.c::sparse_init_one_section()) |
511 | * | 511 | * |
512 | * Additionally during early boot we encode node id of | ||
513 | * the location of the section here to guide allocation. | ||
514 | * (see sparse.c::memory_present()) | ||
515 | * | ||
512 | * Making it a UL at least makes someone do a cast | 516 | * Making it a UL at least makes someone do a cast |
513 | * before using it wrong. | 517 | * before using it wrong. |
514 | */ | 518 | */ |
@@ -548,6 +552,7 @@ extern int __section_nr(struct mem_section* ms); | |||
548 | #define SECTION_HAS_MEM_MAP (1UL<<1) | 552 | #define SECTION_HAS_MEM_MAP (1UL<<1) |
549 | #define SECTION_MAP_LAST_BIT (1UL<<2) | 553 | #define SECTION_MAP_LAST_BIT (1UL<<2) |
550 | #define SECTION_MAP_MASK (~(SECTION_MAP_LAST_BIT-1)) | 554 | #define SECTION_MAP_MASK (~(SECTION_MAP_LAST_BIT-1)) |
555 | #define SECTION_NID_SHIFT 2 | ||
551 | 556 | ||
552 | static inline struct page *__section_mem_map_addr(struct mem_section *section) | 557 | static inline struct page *__section_mem_map_addr(struct mem_section *section) |
553 | { | 558 | { |
diff --git a/mm/sparse.c b/mm/sparse.c index 100040c0dfb6..e0a3fe48aa37 100644 --- a/mm/sparse.c +++ b/mm/sparse.c | |||
@@ -99,6 +99,22 @@ int __section_nr(struct mem_section* ms) | |||
99 | return (root_nr * SECTIONS_PER_ROOT) + (ms - root); | 99 | return (root_nr * SECTIONS_PER_ROOT) + (ms - root); |
100 | } | 100 | } |
101 | 101 | ||
102 | /* | ||
103 | * During early boot, before section_mem_map is used for an actual | ||
104 | * mem_map, we use section_mem_map to store the section's NUMA | ||
105 | * node. This keeps us from having to use another data structure. The | ||
106 | * node information is cleared just before we store the real mem_map. | ||
107 | */ | ||
108 | static inline unsigned long sparse_encode_early_nid(int nid) | ||
109 | { | ||
110 | return (nid << SECTION_NID_SHIFT); | ||
111 | } | ||
112 | |||
113 | static inline int sparse_early_nid(struct mem_section *section) | ||
114 | { | ||
115 | return (section->section_mem_map >> SECTION_NID_SHIFT); | ||
116 | } | ||
117 | |||
102 | /* Record a memory area against a node. */ | 118 | /* Record a memory area against a node. */ |
103 | void memory_present(int nid, unsigned long start, unsigned long end) | 119 | void memory_present(int nid, unsigned long start, unsigned long end) |
104 | { | 120 | { |
@@ -113,7 +129,8 @@ void memory_present(int nid, unsigned long start, unsigned long end) | |||
113 | 129 | ||
114 | ms = __nr_to_section(section); | 130 | ms = __nr_to_section(section); |
115 | if (!ms->section_mem_map) | 131 | if (!ms->section_mem_map) |
116 | ms->section_mem_map = SECTION_MARKED_PRESENT; | 132 | ms->section_mem_map = sparse_encode_early_nid(nid) | |
133 | SECTION_MARKED_PRESENT; | ||
117 | } | 134 | } |
118 | } | 135 | } |
119 | 136 | ||
@@ -164,6 +181,7 @@ static int sparse_init_one_section(struct mem_section *ms, | |||
164 | if (!valid_section(ms)) | 181 | if (!valid_section(ms)) |
165 | return -EINVAL; | 182 | return -EINVAL; |
166 | 183 | ||
184 | ms->section_mem_map &= ~SECTION_MAP_MASK; | ||
167 | ms->section_mem_map |= sparse_encode_mem_map(mem_map, pnum); | 185 | ms->section_mem_map |= sparse_encode_mem_map(mem_map, pnum); |
168 | 186 | ||
169 | return 1; | 187 | return 1; |
@@ -172,8 +190,8 @@ static int sparse_init_one_section(struct mem_section *ms, | |||
172 | static struct page *sparse_early_mem_map_alloc(unsigned long pnum) | 190 | static struct page *sparse_early_mem_map_alloc(unsigned long pnum) |
173 | { | 191 | { |
174 | struct page *map; | 192 | struct page *map; |
175 | int nid = early_pfn_to_nid(section_nr_to_pfn(pnum)); | ||
176 | struct mem_section *ms = __nr_to_section(pnum); | 193 | struct mem_section *ms = __nr_to_section(pnum); |
194 | int nid = sparse_early_nid(ms); | ||
177 | 195 | ||
178 | map = alloc_remap(nid, sizeof(struct page) * PAGES_PER_SECTION); | 196 | map = alloc_remap(nid, sizeof(struct page) * PAGES_PER_SECTION); |
179 | if (map) | 197 | if (map) |