diff options
Diffstat (limited to 'mm/page_alloc.c')
-rw-r--r-- | mm/page_alloc.c | 33 |
1 files changed, 22 insertions, 11 deletions
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index b7a6f583a373..2302f250d6b1 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c | |||
@@ -292,6 +292,26 @@ int page_group_by_mobility_disabled __read_mostly; | |||
292 | #ifdef CONFIG_DEFERRED_STRUCT_PAGE_INIT | 292 | #ifdef CONFIG_DEFERRED_STRUCT_PAGE_INIT |
293 | static inline void reset_deferred_meminit(pg_data_t *pgdat) | 293 | static inline void reset_deferred_meminit(pg_data_t *pgdat) |
294 | { | 294 | { |
295 | unsigned long max_initialise; | ||
296 | unsigned long reserved_lowmem; | ||
297 | |||
298 | /* | ||
299 | * Initialise at least 2G of a node but also take into account that | ||
300 | * two large system hashes that can take up 1GB for 0.25TB/node. | ||
301 | */ | ||
302 | max_initialise = max(2UL << (30 - PAGE_SHIFT), | ||
303 | (pgdat->node_spanned_pages >> 8)); | ||
304 | |||
305 | /* | ||
306 | * Compensate the all the memblock reservations (e.g. crash kernel) | ||
307 | * from the initial estimation to make sure we will initialize enough | ||
308 | * memory to boot. | ||
309 | */ | ||
310 | reserved_lowmem = memblock_reserved_memory_within(pgdat->node_start_pfn, | ||
311 | pgdat->node_start_pfn + max_initialise); | ||
312 | max_initialise += reserved_lowmem; | ||
313 | |||
314 | pgdat->static_init_size = min(max_initialise, pgdat->node_spanned_pages); | ||
295 | pgdat->first_deferred_pfn = ULONG_MAX; | 315 | pgdat->first_deferred_pfn = ULONG_MAX; |
296 | } | 316 | } |
297 | 317 | ||
@@ -314,20 +334,11 @@ static inline bool update_defer_init(pg_data_t *pgdat, | |||
314 | unsigned long pfn, unsigned long zone_end, | 334 | unsigned long pfn, unsigned long zone_end, |
315 | unsigned long *nr_initialised) | 335 | unsigned long *nr_initialised) |
316 | { | 336 | { |
317 | unsigned long max_initialise; | ||
318 | |||
319 | /* Always populate low zones for address-contrained allocations */ | 337 | /* Always populate low zones for address-contrained allocations */ |
320 | if (zone_end < pgdat_end_pfn(pgdat)) | 338 | if (zone_end < pgdat_end_pfn(pgdat)) |
321 | return true; | 339 | return true; |
322 | /* | ||
323 | * Initialise at least 2G of a node but also take into account that | ||
324 | * two large system hashes that can take up 1GB for 0.25TB/node. | ||
325 | */ | ||
326 | max_initialise = max(2UL << (30 - PAGE_SHIFT), | ||
327 | (pgdat->node_spanned_pages >> 8)); | ||
328 | |||
329 | (*nr_initialised)++; | 340 | (*nr_initialised)++; |
330 | if ((*nr_initialised > max_initialise) && | 341 | if ((*nr_initialised > pgdat->static_init_size) && |
331 | (pfn & (PAGES_PER_SECTION - 1)) == 0) { | 342 | (pfn & (PAGES_PER_SECTION - 1)) == 0) { |
332 | pgdat->first_deferred_pfn = pfn; | 343 | pgdat->first_deferred_pfn = pfn; |
333 | return false; | 344 | return false; |
@@ -6138,7 +6149,6 @@ void __paginginit free_area_init_node(int nid, unsigned long *zones_size, | |||
6138 | /* pg_data_t should be reset to zero when it's allocated */ | 6149 | /* pg_data_t should be reset to zero when it's allocated */ |
6139 | WARN_ON(pgdat->nr_zones || pgdat->kswapd_classzone_idx); | 6150 | WARN_ON(pgdat->nr_zones || pgdat->kswapd_classzone_idx); |
6140 | 6151 | ||
6141 | reset_deferred_meminit(pgdat); | ||
6142 | pgdat->node_id = nid; | 6152 | pgdat->node_id = nid; |
6143 | pgdat->node_start_pfn = node_start_pfn; | 6153 | pgdat->node_start_pfn = node_start_pfn; |
6144 | pgdat->per_cpu_nodestats = NULL; | 6154 | pgdat->per_cpu_nodestats = NULL; |
@@ -6160,6 +6170,7 @@ void __paginginit free_area_init_node(int nid, unsigned long *zones_size, | |||
6160 | (unsigned long)pgdat->node_mem_map); | 6170 | (unsigned long)pgdat->node_mem_map); |
6161 | #endif | 6171 | #endif |
6162 | 6172 | ||
6173 | reset_deferred_meminit(pgdat); | ||
6163 | free_area_init_core(pgdat); | 6174 | free_area_init_core(pgdat); |
6164 | } | 6175 | } |
6165 | 6176 | ||