diff options
author | Mel Gorman <mgorman@suse.de> | 2015-06-30 17:56:52 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-06-30 22:44:55 -0400 |
commit | d70ddd7a5d9aa335f9b4b0c3d879e1e70ee1e4e3 (patch) | |
tree | 6d41a16e64635ce3cb77d498674bda9fc86053b7 /mm | |
parent | 92923ca3aacef63c92dc297a75ad0c6dfe4eab37 (diff) |
mm: page_alloc: pass PFN to __free_pages_bootmem
__free_pages_bootmem prepares a page for release to the buddy allocator
and assumes that the struct page is initialised. Parallel initialisation
of struct pages defers initialisation and __free_pages_bootmem can be
called for struct pages that cannot yet map struct page to PFN. This
patch passes PFN to __free_pages_bootmem with no other functional change.
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>
Diffstat (limited to 'mm')
-rw-r--r-- | mm/bootmem.c | 13 | ||||
-rw-r--r-- | mm/internal.h | 3 | ||||
-rw-r--r-- | mm/memblock.c | 2 | ||||
-rw-r--r-- | mm/nobootmem.c | 4 | ||||
-rw-r--r-- | mm/page_alloc.c | 3 |
5 files changed, 14 insertions, 11 deletions
diff --git a/mm/bootmem.c b/mm/bootmem.c index 477be696511d..a23dd1934654 100644 --- a/mm/bootmem.c +++ b/mm/bootmem.c | |||
@@ -164,7 +164,7 @@ void __init free_bootmem_late(unsigned long physaddr, unsigned long size) | |||
164 | end = PFN_DOWN(physaddr + size); | 164 | end = PFN_DOWN(physaddr + size); |
165 | 165 | ||
166 | for (; cursor < end; cursor++) { | 166 | for (; cursor < end; cursor++) { |
167 | __free_pages_bootmem(pfn_to_page(cursor), 0); | 167 | __free_pages_bootmem(pfn_to_page(cursor), cursor, 0); |
168 | totalram_pages++; | 168 | totalram_pages++; |
169 | } | 169 | } |
170 | } | 170 | } |
@@ -172,7 +172,7 @@ void __init free_bootmem_late(unsigned long physaddr, unsigned long size) | |||
172 | static unsigned long __init free_all_bootmem_core(bootmem_data_t *bdata) | 172 | static unsigned long __init free_all_bootmem_core(bootmem_data_t *bdata) |
173 | { | 173 | { |
174 | struct page *page; | 174 | struct page *page; |
175 | unsigned long *map, start, end, pages, count = 0; | 175 | unsigned long *map, start, end, pages, cur, count = 0; |
176 | 176 | ||
177 | if (!bdata->node_bootmem_map) | 177 | if (!bdata->node_bootmem_map) |
178 | return 0; | 178 | return 0; |
@@ -210,17 +210,17 @@ static unsigned long __init free_all_bootmem_core(bootmem_data_t *bdata) | |||
210 | if (IS_ALIGNED(start, BITS_PER_LONG) && vec == ~0UL) { | 210 | if (IS_ALIGNED(start, BITS_PER_LONG) && vec == ~0UL) { |
211 | int order = ilog2(BITS_PER_LONG); | 211 | int order = ilog2(BITS_PER_LONG); |
212 | 212 | ||
213 | __free_pages_bootmem(pfn_to_page(start), order); | 213 | __free_pages_bootmem(pfn_to_page(start), start, order); |
214 | count += BITS_PER_LONG; | 214 | count += BITS_PER_LONG; |
215 | start += BITS_PER_LONG; | 215 | start += BITS_PER_LONG; |
216 | } else { | 216 | } else { |
217 | unsigned long cur = start; | 217 | cur = start; |
218 | 218 | ||
219 | start = ALIGN(start + 1, BITS_PER_LONG); | 219 | start = ALIGN(start + 1, BITS_PER_LONG); |
220 | while (vec && cur != start) { | 220 | while (vec && cur != start) { |
221 | if (vec & 1) { | 221 | if (vec & 1) { |
222 | page = pfn_to_page(cur); | 222 | page = pfn_to_page(cur); |
223 | __free_pages_bootmem(page, 0); | 223 | __free_pages_bootmem(page, cur, 0); |
224 | count++; | 224 | count++; |
225 | } | 225 | } |
226 | vec >>= 1; | 226 | vec >>= 1; |
@@ -229,12 +229,13 @@ static unsigned long __init free_all_bootmem_core(bootmem_data_t *bdata) | |||
229 | } | 229 | } |
230 | } | 230 | } |
231 | 231 | ||
232 | cur = bdata->node_min_pfn; | ||
232 | page = virt_to_page(bdata->node_bootmem_map); | 233 | page = virt_to_page(bdata->node_bootmem_map); |
233 | pages = bdata->node_low_pfn - bdata->node_min_pfn; | 234 | pages = bdata->node_low_pfn - bdata->node_min_pfn; |
234 | pages = bootmem_bootmap_pages(pages); | 235 | pages = bootmem_bootmap_pages(pages); |
235 | count += pages; | 236 | count += pages; |
236 | while (pages--) | 237 | while (pages--) |
237 | __free_pages_bootmem(page++, 0); | 238 | __free_pages_bootmem(page++, cur++, 0); |
238 | 239 | ||
239 | bdebug("nid=%td released=%lx\n", bdata - bootmem_node_data, count); | 240 | bdebug("nid=%td released=%lx\n", bdata - bootmem_node_data, count); |
240 | 241 | ||
diff --git a/mm/internal.h b/mm/internal.h index a25e359a4039..58e9022e3757 100644 --- a/mm/internal.h +++ b/mm/internal.h | |||
@@ -155,7 +155,8 @@ __find_buddy_index(unsigned long page_idx, unsigned int order) | |||
155 | } | 155 | } |
156 | 156 | ||
157 | extern int __isolate_free_page(struct page *page, unsigned int order); | 157 | extern int __isolate_free_page(struct page *page, unsigned int order); |
158 | extern void __free_pages_bootmem(struct page *page, unsigned int order); | 158 | extern void __free_pages_bootmem(struct page *page, unsigned long pfn, |
159 | unsigned int order); | ||
159 | extern void prep_compound_page(struct page *page, unsigned long order); | 160 | extern void prep_compound_page(struct page *page, unsigned long order); |
160 | #ifdef CONFIG_MEMORY_FAILURE | 161 | #ifdef CONFIG_MEMORY_FAILURE |
161 | extern bool is_free_buddy_page(struct page *page); | 162 | extern bool is_free_buddy_page(struct page *page); |
diff --git a/mm/memblock.c b/mm/memblock.c index 114df622853f..87108e77e476 100644 --- a/mm/memblock.c +++ b/mm/memblock.c | |||
@@ -1419,7 +1419,7 @@ void __init __memblock_free_late(phys_addr_t base, phys_addr_t size) | |||
1419 | end = PFN_DOWN(base + size); | 1419 | end = PFN_DOWN(base + size); |
1420 | 1420 | ||
1421 | for (; cursor < end; cursor++) { | 1421 | for (; cursor < end; cursor++) { |
1422 | __free_pages_bootmem(pfn_to_page(cursor), 0); | 1422 | __free_pages_bootmem(pfn_to_page(cursor), cursor, 0); |
1423 | totalram_pages++; | 1423 | totalram_pages++; |
1424 | } | 1424 | } |
1425 | } | 1425 | } |
diff --git a/mm/nobootmem.c b/mm/nobootmem.c index 4af8f88c2bd1..e57cf24babd6 100644 --- a/mm/nobootmem.c +++ b/mm/nobootmem.c | |||
@@ -86,7 +86,7 @@ void __init free_bootmem_late(unsigned long addr, unsigned long size) | |||
86 | end = PFN_DOWN(addr + size); | 86 | end = PFN_DOWN(addr + size); |
87 | 87 | ||
88 | for (; cursor < end; cursor++) { | 88 | for (; cursor < end; cursor++) { |
89 | __free_pages_bootmem(pfn_to_page(cursor), 0); | 89 | __free_pages_bootmem(pfn_to_page(cursor), cursor, 0); |
90 | totalram_pages++; | 90 | totalram_pages++; |
91 | } | 91 | } |
92 | } | 92 | } |
@@ -101,7 +101,7 @@ static void __init __free_pages_memory(unsigned long start, unsigned long end) | |||
101 | while (start + (1UL << order) > end) | 101 | while (start + (1UL << order) > end) |
102 | order--; | 102 | order--; |
103 | 103 | ||
104 | __free_pages_bootmem(pfn_to_page(start), order); | 104 | __free_pages_bootmem(pfn_to_page(start), start, order); |
105 | 105 | ||
106 | start += (1UL << order); | 106 | start += (1UL << order); |
107 | } | 107 | } |
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 39c8d56a4056..c2ee4ecad083 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c | |||
@@ -878,7 +878,8 @@ static void __free_pages_ok(struct page *page, unsigned int order) | |||
878 | local_irq_restore(flags); | 878 | local_irq_restore(flags); |
879 | } | 879 | } |
880 | 880 | ||
881 | void __init __free_pages_bootmem(struct page *page, unsigned int order) | 881 | void __init __free_pages_bootmem(struct page *page, unsigned long pfn, |
882 | unsigned int order) | ||
882 | { | 883 | { |
883 | unsigned int nr_pages = 1 << order; | 884 | unsigned int nr_pages = 1 << order; |
884 | struct page *p = page; | 885 | struct page *p = page; |