From: David Hildenbrand david@redhat.com
mainline inclusion from linux-5.7-rc1 commit 5f47adf762b78cae97de58d9ff01d2d44db09467 category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I4SK3S CVE: NA
--------------------------------
For now, distributions implement advanced udev rules to essentially - Don't online any hotplugged memory (s390x) - Online all memory to ZONE_NORMAL (e.g., most virt environments like hyperv) - Online all memory to ZONE_MOVABLE in case the zone imbalance is taken care of (e.g., bare metal, special virt environments)
In summary: All memory is usually onlined the same way, however, the kernel always has to ask user space to come up with the same answer. E.g., Hyper-V always waits for a memory block to get onlined before continuing, otherwise it might end up adding memory faster than onlining it, which can result in strange OOM situations. This waiting slows down adding of a bigger amount of memory.
Let's allow to specify a default online_type, not just "online" and "offline". This allows distributions to configure the default online_type when booting up and be done with it.
We can now specify "offline", "online", "online_movable" and "online_kernel" via - "memhp_default_state=" on the kernel cmdline - /sys/devices/system/memory/auto_online_blocks just like we are able to specify for a single memory block via /sys/devices/system/memory/memoryX/state
Signed-off-by: David Hildenbrand david@redhat.com Signed-off-by: Andrew Morton akpm@linux-foundation.org Reviewed-by: Wei Yang richard.weiyang@gmail.com Reviewed-by: Baoquan He bhe@redhat.com Acked-by: Michal Hocko mhocko@suse.com Acked-by: Pankaj Gupta pankaj.gupta.linux@gmail.com Cc: Greg Kroah-Hartman gregkh@linuxfoundation.org Cc: Oscar Salvador osalvador@suse.de Cc: "Rafael J. Wysocki" rafael@kernel.org Cc: Wei Yang richard.weiyang@gmail.com Cc: Benjamin Herrenschmidt benh@kernel.crashing.org Cc: Eduardo Habkost ehabkost@redhat.com Cc: Haiyang Zhang haiyangz@microsoft.com Cc: Igor Mammedov imammedo@redhat.com Cc: "K. Y. Srinivasan" kys@microsoft.com Cc: Michael Ellerman mpe@ellerman.id.au Cc: Paul Mackerras paulus@samba.org Cc: Stephen Hemminger sthemmin@microsoft.com Cc: Vitaly Kuznetsov vkuznets@redhat.com Cc: Wei Liu wei.liu@kernel.org Cc: Yumei Huang yuhuang@redhat.com Link: http://lkml.kernel.org/r/20200317104942.11178-9-david@redhat.com Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Ma Wupeng mawupeng1@huawei.com Reviewed-by: Kefeng Wang wangkefeng.wang@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- drivers/base/memory.c | 11 +++++------ include/linux/memory_hotplug.h | 2 ++ mm/memory_hotplug.c | 8 ++++---- 3 files changed, 11 insertions(+), 10 deletions(-)
diff --git a/drivers/base/memory.c b/drivers/base/memory.c index f7c41be57976b..1b97f305173fb 100644 --- a/drivers/base/memory.c +++ b/drivers/base/memory.c @@ -37,7 +37,7 @@ static const char *const online_type_to_str[] = { [MMOP_ONLINE_MOVABLE] = "online_movable", };
-static int memhp_online_type_from_str(const char *str) +int memhp_online_type_from_str(const char *str) { int i;
@@ -481,13 +481,12 @@ static ssize_t auto_online_blocks_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - if (sysfs_streq(buf, "online")) - memhp_default_online_type = MMOP_ONLINE; - else if (sysfs_streq(buf, "offline")) - memhp_default_online_type = MMOP_OFFLINE; - else + const int online_type = memhp_online_type_from_str(buf); + + if (online_type < 0) return -EINVAL;
+ memhp_default_online_type = online_type; return count; }
diff --git a/include/linux/memory_hotplug.h b/include/linux/memory_hotplug.h index 1ba6a688094de..bc433d459c861 100644 --- a/include/linux/memory_hotplug.h +++ b/include/linux/memory_hotplug.h @@ -105,6 +105,8 @@ extern void __online_page_free(struct page *page); extern int try_online_node(int nid);
extern bool memhp_auto_online; +extern int memhp_online_type_from_str(const char *str); + /* Default online_type (MMOP_*) when new memory blocks are added. */ extern int memhp_default_online_type; /* If movable_node boot option specified */ diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c index 3b9d409c902b9..3df9285b73b18 100644 --- a/mm/memory_hotplug.c +++ b/mm/memory_hotplug.c @@ -78,10 +78,10 @@ EXPORT_SYMBOL_GPL(memhp_auto_online);
static int __init setup_memhp_default_state(char *str) { - if (!strcmp(str, "online")) - memhp_default_online_type = MMOP_ONLINE; - else if (!strcmp(str, "offline")) - memhp_default_online_type = MMOP_OFFLINE; + const int online_type = memhp_online_type_from_str(str); + + if (online_type >= 0) + memhp_default_online_type = online_type;
return 1; }