diff options
Diffstat (limited to 'mm')
-rw-r--r-- | mm/memory_hotplug.c | 45 |
1 files changed, 19 insertions, 26 deletions
diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c index 9c12ae5e3695..1cbe9579e233 100644 --- a/mm/memory_hotplug.c +++ b/mm/memory_hotplug.c | |||
@@ -161,14 +161,27 @@ static void grow_pgdat_span(struct pglist_data *pgdat, | |||
161 | pgdat->node_start_pfn; | 161 | pgdat->node_start_pfn; |
162 | } | 162 | } |
163 | 163 | ||
164 | int online_pages(unsigned long pfn, unsigned long nr_pages) | 164 | static int online_pages_range(unsigned long start_pfn, unsigned long nr_pages, |
165 | void *arg) | ||
165 | { | 166 | { |
166 | unsigned long i; | 167 | unsigned long i; |
168 | unsigned long onlined_pages = *(unsigned long *)arg; | ||
169 | struct page *page; | ||
170 | if (PageReserved(pfn_to_page(start_pfn))) | ||
171 | for (i = 0; i < nr_pages; i++) { | ||
172 | page = pfn_to_page(start_pfn + i); | ||
173 | online_page(page); | ||
174 | onlined_pages++; | ||
175 | } | ||
176 | *(unsigned long *)arg = onlined_pages; | ||
177 | return 0; | ||
178 | } | ||
179 | |||
180 | |||
181 | int online_pages(unsigned long pfn, unsigned long nr_pages) | ||
182 | { | ||
167 | unsigned long flags; | 183 | unsigned long flags; |
168 | unsigned long onlined_pages = 0; | 184 | unsigned long onlined_pages = 0; |
169 | struct resource res; | ||
170 | u64 section_end; | ||
171 | unsigned long start_pfn; | ||
172 | struct zone *zone; | 185 | struct zone *zone; |
173 | int need_zonelists_rebuild = 0; | 186 | int need_zonelists_rebuild = 0; |
174 | 187 | ||
@@ -191,28 +204,8 @@ int online_pages(unsigned long pfn, unsigned long nr_pages) | |||
191 | if (!populated_zone(zone)) | 204 | if (!populated_zone(zone)) |
192 | need_zonelists_rebuild = 1; | 205 | need_zonelists_rebuild = 1; |
193 | 206 | ||
194 | res.start = (u64)pfn << PAGE_SHIFT; | 207 | walk_memory_resource(pfn, nr_pages, &onlined_pages, |
195 | res.end = res.start + ((u64)nr_pages << PAGE_SHIFT) - 1; | 208 | online_pages_range); |
196 | res.flags = IORESOURCE_MEM; /* we just need system ram */ | ||
197 | section_end = res.end; | ||
198 | |||
199 | while ((res.start < res.end) && (find_next_system_ram(&res) >= 0)) { | ||
200 | start_pfn = (unsigned long)(res.start >> PAGE_SHIFT); | ||
201 | nr_pages = (unsigned long) | ||
202 | ((res.end + 1 - res.start) >> PAGE_SHIFT); | ||
203 | |||
204 | if (PageReserved(pfn_to_page(start_pfn))) { | ||
205 | /* this region's page is not onlined now */ | ||
206 | for (i = 0; i < nr_pages; i++) { | ||
207 | struct page *page = pfn_to_page(start_pfn + i); | ||
208 | online_page(page); | ||
209 | onlined_pages++; | ||
210 | } | ||
211 | } | ||
212 | |||
213 | res.start = res.end + 1; | ||
214 | res.end = section_end; | ||
215 | } | ||
216 | zone->present_pages += onlined_pages; | 209 | zone->present_pages += onlined_pages; |
217 | zone->zone_pgdat->node_present_pages += onlined_pages; | 210 | zone->zone_pgdat->node_present_pages += onlined_pages; |
218 | 211 | ||