diff options
Diffstat (limited to 'mm/sparse.c')
| -rw-r--r-- | mm/sparse.c | 18 |
1 files changed, 13 insertions, 5 deletions
diff --git a/mm/sparse.c b/mm/sparse.c index e861397016a9..c7bb952400c8 100644 --- a/mm/sparse.c +++ b/mm/sparse.c | |||
| @@ -275,8 +275,9 @@ static unsigned long * __init | |||
| 275 | sparse_early_usemaps_alloc_pgdat_section(struct pglist_data *pgdat, | 275 | sparse_early_usemaps_alloc_pgdat_section(struct pglist_data *pgdat, |
| 276 | unsigned long size) | 276 | unsigned long size) |
| 277 | { | 277 | { |
| 278 | pg_data_t *host_pgdat; | 278 | unsigned long goal, limit; |
| 279 | unsigned long goal; | 279 | unsigned long *p; |
| 280 | int nid; | ||
| 280 | /* | 281 | /* |
| 281 | * A page may contain usemaps for other sections preventing the | 282 | * A page may contain usemaps for other sections preventing the |
| 282 | * page being freed and making a section unremovable while | 283 | * page being freed and making a section unremovable while |
| @@ -288,9 +289,16 @@ sparse_early_usemaps_alloc_pgdat_section(struct pglist_data *pgdat, | |||
| 288 | * this problem. | 289 | * this problem. |
| 289 | */ | 290 | */ |
| 290 | goal = __pa(pgdat) & (PAGE_SECTION_MASK << PAGE_SHIFT); | 291 | goal = __pa(pgdat) & (PAGE_SECTION_MASK << PAGE_SHIFT); |
| 291 | host_pgdat = NODE_DATA(early_pfn_to_nid(goal >> PAGE_SHIFT)); | 292 | limit = goal + (1UL << PA_SECTION_SHIFT); |
| 292 | return __alloc_bootmem_node_nopanic(host_pgdat, size, | 293 | nid = early_pfn_to_nid(goal >> PAGE_SHIFT); |
| 293 | SMP_CACHE_BYTES, goal); | 294 | again: |
| 295 | p = ___alloc_bootmem_node_nopanic(NODE_DATA(nid), size, | ||
| 296 | SMP_CACHE_BYTES, goal, limit); | ||
| 297 | if (!p && limit) { | ||
| 298 | limit = 0; | ||
| 299 | goto again; | ||
| 300 | } | ||
| 301 | return p; | ||
| 294 | } | 302 | } |
| 295 | 303 | ||
| 296 | static void __init check_usemap_section_nr(int nid, unsigned long *usemap) | 304 | static void __init check_usemap_section_nr(int nid, unsigned long *usemap) |
