summaryrefslogtreecommitdiffstats
path: root/mm/sparse.c
diff options
context:
space:
mode:
authorGrant Likely <grant.likely@secretlab.ca>2012-07-24 22:31:09 -0600
committerGrant Likely <grant.likely@secretlab.ca>2012-07-24 22:34:40 -0600
commit6aeea3ecc33b1f36dbc3b80461d15a7052ae424f (patch)
treebbd273e3e0ca76094aed8e9c77e5adfe2b07f779 /mm/sparse.c
parent9844a5524ec532aee826c35e3031637c7fc8287b (diff)
parentbdc0077af574800d24318b6945cf2344e8dbb050 (diff)
Merge remote-tracking branch 'origin' into irqdomain/next
Diffstat (limited to 'mm/sparse.c')
-rw-r--r--mm/sparse.c20
1 files changed, 14 insertions, 6 deletions
diff --git a/mm/sparse.c b/mm/sparse.c
index 6a4bf9160e8..c7bb952400c 100644
--- a/mm/sparse.c
+++ b/mm/sparse.c
@@ -275,8 +275,9 @@ static unsigned long * __init
sparse_early_usemaps_alloc_pgdat_section(struct pglist_data *pgdat,
unsigned long size)
{
- pg_data_t *host_pgdat;
- unsigned long goal;
+ unsigned long goal, limit;
+ unsigned long *p;
+ int nid;
/*
* A page may contain usemaps for other sections preventing the
* page being freed and making a section unremovable while
@@ -287,10 +288,17 @@ sparse_early_usemaps_alloc_pgdat_section(struct pglist_data *pgdat,
* from the same section as the pgdat where possible to avoid
* this problem.
*/
- goal = __pa(pgdat) & PAGE_SECTION_MASK;
- host_pgdat = NODE_DATA(early_pfn_to_nid(goal >> PAGE_SHIFT));
- return __alloc_bootmem_node_nopanic(host_pgdat, size,
- SMP_CACHE_BYTES, goal);
+ goal = __pa(pgdat) & (PAGE_SECTION_MASK << PAGE_SHIFT);
+ limit = goal + (1UL << PA_SECTION_SHIFT);
+ nid = early_pfn_to_nid(goal >> PAGE_SHIFT);
+again:
+ p = ___alloc_bootmem_node_nopanic(NODE_DATA(nid), size,
+ SMP_CACHE_BYTES, goal, limit);
+ if (!p && limit) {
+ limit = 0;
+ goto again;
+ }
+ return p;
}
static void __init check_usemap_section_nr(int nid, unsigned long *usemap)