|
@@ -1328,14 +1328,39 @@ int kern_addr_valid(unsigned long addr)
|
|
|
return pfn_valid(pte_pfn(*pte));
|
|
|
}
|
|
|
|
|
|
+/*
|
|
|
+ * Block size is the minimum amount of memory which can be hotplugged or
|
|
|
+ * hotremoved. It must be power of two and must be equal or larger than
|
|
|
+ * MIN_MEMORY_BLOCK_SIZE.
|
|
|
+ */
|
|
|
+#define MAX_BLOCK_SIZE (2UL << 30)
|
|
|
+
|
|
|
+/* Amount of ram needed to start using large blocks */
|
|
|
+#define MEM_SIZE_FOR_LARGE_BLOCK (64UL << 30)
|
|
|
+
|
|
|
static unsigned long probe_memory_block_size(void)
|
|
|
{
|
|
|
- unsigned long bz = MIN_MEMORY_BLOCK_SIZE;
|
|
|
+ unsigned long boot_mem_end = max_pfn << PAGE_SHIFT;
|
|
|
+ unsigned long bz;
|
|
|
|
|
|
- /* if system is UV or has 64GB of RAM or more, use large blocks */
|
|
|
- if (is_uv_system() || ((max_pfn << PAGE_SHIFT) >= (64UL << 30)))
|
|
|
- bz = 2UL << 30; /* 2GB */
|
|
|
+ /* If this is UV system, always set 2G block size */
|
|
|
+ if (is_uv_system()) {
|
|
|
+ bz = MAX_BLOCK_SIZE;
|
|
|
+ goto done;
|
|
|
+ }
|
|
|
|
|
|
+ /* Use regular block if RAM is smaller than MEM_SIZE_FOR_LARGE_BLOCK */
|
|
|
+ if (boot_mem_end < MEM_SIZE_FOR_LARGE_BLOCK) {
|
|
|
+ bz = MIN_MEMORY_BLOCK_SIZE;
|
|
|
+ goto done;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Find the largest allowed block size that aligns to memory end */
|
|
|
+ for (bz = MAX_BLOCK_SIZE; bz > MIN_MEMORY_BLOCK_SIZE; bz >>= 1) {
|
|
|
+ if (IS_ALIGNED(boot_mem_end, bz))
|
|
|
+ break;
|
|
|
+ }
|
|
|
+done:
|
|
|
pr_info("x86/mm: Memory block size: %ldMB\n", bz >> 20);
|
|
|
|
|
|
return bz;
|