aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/mm/init_64.c33
1 files changed, 29 insertions, 4 deletions
diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
index 45241de66785..dca9abf2b85c 100644
--- a/arch/x86/mm/init_64.c
+++ b/arch/x86/mm/init_64.c
@@ -1328,14 +1328,39 @@ int kern_addr_valid(unsigned long addr)
1328 return pfn_valid(pte_pfn(*pte)); 1328 return pfn_valid(pte_pfn(*pte));
1329} 1329}
1330 1330
1331/*
1332 * Block size is the minimum amount of memory which can be hotplugged or
1333 * hotremoved. It must be power of two and must be equal or larger than
1334 * MIN_MEMORY_BLOCK_SIZE.
1335 */
1336#define MAX_BLOCK_SIZE (2UL << 30)
1337
1338/* Amount of ram needed to start using large blocks */
1339#define MEM_SIZE_FOR_LARGE_BLOCK (64UL << 30)
1340
1331static unsigned long probe_memory_block_size(void) 1341static unsigned long probe_memory_block_size(void)
1332{ 1342{
1333 unsigned long bz = MIN_MEMORY_BLOCK_SIZE; 1343 unsigned long boot_mem_end = max_pfn << PAGE_SHIFT;
1344 unsigned long bz;
1334 1345
1335 /* if system is UV or has 64GB of RAM or more, use large blocks */ 1346 /* If this is UV system, always set 2G block size */
1336 if (is_uv_system() || ((max_pfn << PAGE_SHIFT) >= (64UL << 30))) 1347 if (is_uv_system()) {
1337 bz = 2UL << 30; /* 2GB */ 1348 bz = MAX_BLOCK_SIZE;
1349 goto done;
1350 }
1338 1351
1352 /* Use regular block if RAM is smaller than MEM_SIZE_FOR_LARGE_BLOCK */
1353 if (boot_mem_end < MEM_SIZE_FOR_LARGE_BLOCK) {
1354 bz = MIN_MEMORY_BLOCK_SIZE;
1355 goto done;
1356 }
1357
1358 /* Find the largest allowed block size that aligns to memory end */
1359 for (bz = MAX_BLOCK_SIZE; bz > MIN_MEMORY_BLOCK_SIZE; bz >>= 1) {
1360 if (IS_ALIGNED(boot_mem_end, bz))
1361 break;
1362 }
1363done:
1339 pr_info("x86/mm: Memory block size: %ldMB\n", bz >> 20); 1364 pr_info("x86/mm: Memory block size: %ldMB\n", bz >> 20);
1340 1365
1341 return bz; 1366 return bz;