Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

x86/platform/UV: Add adjustable set memory block size function

Add a new function to "adjust" the current fixed UV memory block size
of 2GB so it can be changed to a different physical boundary. This is
out of necessity so arch dependent code can accommodate specific BIOS
requirements which can align these new PMEM modules at less than the
default boundaries.

A "set order" type of function was used to insure that the memory block
size will be a power of two value without requiring a validity check.
64GB was chosen as the upper limit for memory block size values to
accommodate upcoming 4PB systems which have 6 more bits of physical
address space (46 becoming 52).

Signed-off-by: Mike Travis <mike.travis@hpe.com>
Reviewed-by: Andrew Banman <andrew.banman@hpe.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Dimitri Sivanich <dimitri.sivanich@hpe.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Russ Anderson <russ.anderson@hpe.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: dan.j.williams@intel.com
Cc: jgross@suse.com
Cc: kirill.shutemov@linux.intel.com
Cc: mhocko@suse.com
Cc: stable@vger.kernel.org
Link: https://lkml.kernel.org/lkml/20180524201711.609546602@stormcage.americas.sgi.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>

authored by

mike.travis@hpe.com and committed by
Ingo Molnar
f642fb58 d6605b6b

+17 -4
+16 -4
arch/x86/mm/init_64.c
··· 1350 1350 /* Amount of ram needed to start using large blocks */ 1351 1351 #define MEM_SIZE_FOR_LARGE_BLOCK (64UL << 30) 1352 1352 1353 + /* Adjustable memory block size */ 1354 + static unsigned long set_memory_block_size; 1355 + int __init set_memory_block_size_order(unsigned int order) 1356 + { 1357 + unsigned long size = 1UL << order; 1358 + 1359 + if (size > MEM_SIZE_FOR_LARGE_BLOCK || size < MIN_MEMORY_BLOCK_SIZE) 1360 + return -EINVAL; 1361 + 1362 + set_memory_block_size = size; 1363 + return 0; 1364 + } 1365 + 1353 1366 static unsigned long probe_memory_block_size(void) 1354 1367 { 1355 1368 unsigned long boot_mem_end = max_pfn << PAGE_SHIFT; 1356 1369 unsigned long bz; 1357 1370 1358 - /* If this is UV system, always set 2G block size */ 1359 - if (is_uv_system()) { 1360 - bz = MAX_BLOCK_SIZE; 1371 + /* If memory block size has been set, then use it */ 1372 + bz = set_memory_block_size; 1373 + if (bz) 1361 1374 goto done; 1362 - } 1363 1375 1364 1376 /* Use regular block if RAM is smaller than MEM_SIZE_FOR_LARGE_BLOCK */ 1365 1377 if (boot_mem_end < MEM_SIZE_FOR_LARGE_BLOCK) {
+1
include/linux/memory.h
··· 38 38 39 39 int arch_get_memory_phys_device(unsigned long start_pfn); 40 40 unsigned long memory_block_size_bytes(void); 41 + int set_memory_block_size_order(unsigned int order); 41 42 42 43 /* These states are exposed to userspace as text strings in sysfs */ 43 44 #define MEM_ONLINE (1<<0) /* exposed to userspace */