When memory hotplug auto-online is enabled, hotplug memory blocks are onlined into ZONE_NORMAL by default. The `memhp_default_state` boot param allows runtime configuration, but no build-time config exists. Add a build-time configuration option to change default hotplug zone. build config: MEMHP_DEFAULT_TYPE Selections: MEMHP_DEFAULT_TYPE_NORMAL => mhp_default_online_type = "online" MEMHP_DEFAULT_TYPE_MOVABLE => mhp_default_online_type = "online_movable" When MEMORY_HOTPLUG_DEFAULT_ONLINE is disabled, MEMHP_DEFAULT_TYPE is set to "offline" to match the current system behavior. ZONE_NORMAL still remains the default, because for systems with a large amount of hotplug memory, defaulting it to ZONE_MOVABLE may result in portions failing to online if sufficient ZONE_NORMAL memory does not exist to describe it. Signed-off-by: Gregory Price <gourry@xxxxxxxxxx> --- drivers/base/memory.c | 4 ++-- include/linux/memory_hotplug.h | 5 +++-- mm/Kconfig | 33 +++++++++++++++++++++++++++++++++ mm/memory_hotplug.c | 29 ++++++++++++++++++++++------- 4 files changed, 60 insertions(+), 11 deletions(-) diff --git a/drivers/base/memory.c b/drivers/base/memory.c index 67858eeb92ed..6f69b01abe51 100644 --- a/drivers/base/memory.c +++ b/drivers/base/memory.c @@ -512,7 +512,7 @@ static ssize_t auto_online_blocks_show(struct device *dev, struct device_attribute *attr, char *buf) { return sysfs_emit(buf, "%s\n", - online_type_to_str[mhp_default_online_type]); + online_type_to_str[memhp_default_type()]); } static ssize_t auto_online_blocks_store(struct device *dev, @@ -524,7 +524,7 @@ static ssize_t auto_online_blocks_store(struct device *dev, if (online_type < 0) return -EINVAL; - mhp_default_online_type = online_type; + memhp_set_default_type(online_type); return count; } diff --git a/include/linux/memory_hotplug.h b/include/linux/memory_hotplug.h index b27ddce5d324..a43470f0d93c 100644 --- a/include/linux/memory_hotplug.h +++ b/include/linux/memory_hotplug.h @@ -144,8 +144,6 @@ extern u64 max_mem_size; extern int mhp_online_type_from_str(const char *str); -/* Default online_type (MMOP_*) when new memory blocks are added. */ -extern int mhp_default_online_type; /* If movable_node boot option specified */ extern bool movable_node_enabled; static inline bool movable_node_is_enabled(void) @@ -303,6 +301,9 @@ static inline void __remove_memory(u64 start, u64 size) {} #endif /* CONFIG_MEMORY_HOTREMOVE */ #ifdef CONFIG_MEMORY_HOTPLUG +/* Default online_type (MMOP_*) when new memory blocks are added. */ +extern int memhp_default_type(void); +extern void memhp_set_default_type(int online_type); extern void __ref free_area_init_core_hotplug(struct pglist_data *pgdat); extern int __add_memory(int nid, u64 start, u64 size, mhp_t mhp_flags); extern int add_memory(int nid, u64 start, u64 size, mhp_t mhp_flags); diff --git a/mm/Kconfig b/mm/Kconfig index 7949ab121070..b6e63e5306b1 100644 --- a/mm/Kconfig +++ b/mm/Kconfig @@ -565,6 +565,39 @@ config MEMORY_HOTPLUG_DEFAULT_ONLINE Say N here if you want the default policy to keep all hot-plugged memory blocks in 'offline' state. +choice + prompt "Memory Hotplug Default Type" + depends on MEMORY_HOTPLUG_DEFAULT_ONLINE + default MEMHP_DEFAULT_TYPE_NORMAL + help + Default memory zone for driver managed hotplug memory. + Select normal to generally allow kernel usage of this memory. + Select movable to generally disallow kernel usage of this memory. + Example typical kernel usage would be page structs and page tables. + + +config MEMHP_DEFAULT_TYPE_NORMAL + bool "Normal" + help + Online driver managed hotplug memory into zone normal. + Select this if you want the kernel to be able to utilize + this memory for kernel data (e.g. page tables). + +config MEMHP_DEFAULT_TYPE_MOVABLE + bool "Movable" + help + Online driver managed hotplug memory into zone movable. + Select this if you do not want the kernel to be able to + utilize this memory for kernel data (e.g. page tables). + +endchoice + +config MEMHP_DEFAULT_TYPE + string + default "online" if MEMHP_DEFAULT_TYPE_NORMAL + default "online_movable" if MEMHP_DEFAULT_TYPE_MOVABLE + default "offline" + config MEMORY_HOTREMOVE bool "Allow for memory hot remove" select HAVE_BOOTMEM_INFO_NODE if (X86_64 || PPC64) diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c index 3b6f93962481..1e4340fa9f07 100644 --- a/mm/memory_hotplug.c +++ b/mm/memory_hotplug.c @@ -219,11 +219,26 @@ void put_online_mems(void) bool movable_node_enabled = false; -#ifndef CONFIG_MEMORY_HOTPLUG_DEFAULT_ONLINE -int mhp_default_online_type = MMOP_OFFLINE; -#else -int mhp_default_online_type = MMOP_ONLINE; -#endif +static int mhp_default_online_type = -1; +int memhp_default_type(void) +{ + int type; + + if (mhp_default_online_type >= 0) + return mhp_default_online_type; + + type = mhp_online_type_from_str(CONFIG_MEMHP_DEFAULT_TYPE); + if (type < 0) + type = MMOP_OFFLINE; + + mhp_default_online_type = type; + return mhp_default_online_type; +} + +void memhp_set_default_type(int online_type) +{ + mhp_default_online_type = online_type; +} static int __init setup_memhp_default_state(char *str) { @@ -1328,7 +1343,7 @@ static int check_hotplug_memory_range(u64 start, u64 size) static int online_memory_block(struct memory_block *mem, void *arg) { - mem->online_type = mhp_default_online_type; + mem->online_type = memhp_default_type(); return device_online(&mem->dev); } @@ -1575,7 +1590,7 @@ int add_memory_resource(int nid, struct resource *res, mhp_t mhp_flags) merge_system_ram_resource(res); /* online pages if requested */ - if (mhp_default_online_type != MMOP_OFFLINE) + if (memhp_default_type() != MMOP_OFFLINE) walk_memory_blocks(start, size, NULL, online_memory_block); return ret; -- 2.47.1