aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/mm
diff options
context:
space:
mode:
authorYinghai Lu <yinghai@kernel.org>2014-06-04 19:06:32 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-06-04 19:53:55 -0400
commit982792c782ef337381e982fd2047391886f89693 (patch)
tree756b78ae2a098c97393d15da6a70cbb4adacb067 /arch/x86/mm
parentc46a7c817e662a820373bb76b88d0ad67d6abe5d (diff)
x86, mm: probe memory block size for generic x86 64bit
On system with 2TiB ram, current x86_64 have 128M as section size, and one memory_block only include one section. So will have 16400 entries under /sys/devices/system/memory/. Current code try to use block id to find block pointer in /sys for any section, and reuse that block pointer. that finding will take some time even after commit 7c243c7168dc ("mm: speedup in __early_pfn_to_nid") that will skip the search in that case during booting up. So solution could be increase block size just like SGI UV system did. (harded code to 2g). This patch is trying to probe the block size to make it match mmio remap size. for example, Intel Nehalem later system will have memory range [0, TOML), [4g, TOMH]. If the memory hole is 2g and total is 128g, TOM will be 2g, and TOM2 will be 130g. We could use 2g as block size instead of default 128M. That will reduce number of entries in /sys/devices/system/memory/ On system 6TiB system will reduce boot time by 35 seconds. Signed-off-by: Yinghai Lu <yinghai@kernel.org> Cc: Ingo Molnar <mingo@elte.hu> Cc: "H. Peter Anvin" <hpa@zytor.com> Cc: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'arch/x86/mm')
-rw-r--r--arch/x86/mm/init_64.c34
1 files changed, 30 insertions, 4 deletions
diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
index f35c66c5959a..b92591fa8970 100644
--- a/arch/x86/mm/init_64.c
+++ b/arch/x86/mm/init_64.c
@@ -1230,17 +1230,43 @@ const char *arch_vma_name(struct vm_area_struct *vma)
1230 return NULL; 1230 return NULL;
1231} 1231}
1232 1232
1233#ifdef CONFIG_X86_UV 1233static unsigned long probe_memory_block_size(void)
1234unsigned long memory_block_size_bytes(void)
1235{ 1234{
1235 /* start from 2g */
1236 unsigned long bz = 1UL<<31;
1237
1238#ifdef CONFIG_X86_UV
1236 if (is_uv_system()) { 1239 if (is_uv_system()) {
1237 printk(KERN_INFO "UV: memory block size 2GB\n"); 1240 printk(KERN_INFO "UV: memory block size 2GB\n");
1238 return 2UL * 1024 * 1024 * 1024; 1241 return 2UL * 1024 * 1024 * 1024;
1239 } 1242 }
1240 return MIN_MEMORY_BLOCK_SIZE;
1241}
1242#endif 1243#endif
1243 1244
1245 /* less than 64g installed */
1246 if ((max_pfn << PAGE_SHIFT) < (16UL << 32))
1247 return MIN_MEMORY_BLOCK_SIZE;
1248
1249 /* get the tail size */
1250 while (bz > MIN_MEMORY_BLOCK_SIZE) {
1251 if (!((max_pfn << PAGE_SHIFT) & (bz - 1)))
1252 break;
1253 bz >>= 1;
1254 }
1255
1256 printk(KERN_DEBUG "memory block size : %ldMB\n", bz >> 20);
1257
1258 return bz;
1259}
1260
1261static unsigned long memory_block_size_probed;
1262unsigned long memory_block_size_bytes(void)
1263{
1264 if (!memory_block_size_probed)
1265 memory_block_size_probed = probe_memory_block_size();
1266
1267 return memory_block_size_probed;
1268}
1269
1244#ifdef CONFIG_SPARSEMEM_VMEMMAP 1270#ifdef CONFIG_SPARSEMEM_VMEMMAP
1245/* 1271/*
1246 * Initialise the sparsemem vmemmap using huge-pages at the PMD level. 1272 * Initialise the sparsemem vmemmap using huge-pages at the PMD level.