Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c5320926 authored by Tang Chen's avatar Tang Chen Committed by Linus Torvalds
Browse files

mem-hotplug: introduce movable_node boot option



The hot-Pluggable field in SRAT specifies which memory is hotpluggable.
As we mentioned before, if hotpluggable memory is used by the kernel, it
cannot be hot-removed.  So memory hotplug users may want to set all
hotpluggable memory in ZONE_MOVABLE so that the kernel won't use it.

Memory hotplug users may also set a node as movable node, which has
ZONE_MOVABLE only, so that the whole node can be hot-removed.

But the kernel cannot use memory in ZONE_MOVABLE.  By doing this, the
kernel cannot use memory in movable nodes.  This will cause NUMA
performance down.  And other users may be unhappy.

So we need a way to allow users to enable and disable this functionality.
In this patch, we introduce movable_node boot option to allow users to
choose to not to consume hotpluggable memory at early boot time and later
we can set it as ZONE_MOVABLE.

To achieve this, the movable_node boot option will control the memblock
allocation direction.  That said, after memblock is ready, before SRAT is
parsed, we should allocate memory near the kernel image as we explained in
the previous patches.  So if movable_node boot option is set, the kernel
does the following:

1. After memblock is ready, make memblock allocate memory bottom up.
2. After SRAT is parsed, make memblock behave as default, allocate memory
   top down.

Users can specify "movable_node" in kernel commandline to enable this
functionality.  For those who don't use memory hotplug or who don't want
to lose their NUMA performance, just don't specify anything.  The kernel
will work as before.

Signed-off-by: default avatarTang Chen <tangchen@cn.fujitsu.com>
Signed-off-by: default avatarZhang Yanfei <zhangyanfei@cn.fujitsu.com>
Suggested-by: default avatarKamezawa Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Suggested-by: default avatarIngo Molnar <mingo@kernel.org>
Acked-by: default avatarTejun Heo <tj@kernel.org>
Acked-by: default avatarToshi Kani <toshi.kani@hp.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: Wanpeng Li <liwanp@linux.vnet.ibm.com>
Cc: Thomas Renninger <trenn@suse.de>
Cc: Yinghai Lu <yinghai@kernel.org>
Cc: Jiang Liu <jiang.liu@huawei.com>
Cc: Wen Congyang <wency@cn.fujitsu.com>
Cc: Lai Jiangshan <laijs@cn.fujitsu.com>
Cc: Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com>
Cc: Taku Izumi <izumi.taku@jp.fujitsu.com>
Cc: Mel Gorman <mgorman@suse.de>
Cc: Michal Nazarewicz <mina86@mina86.com>
Cc: Minchan Kim <minchan@kernel.org>
Cc: Rik van Riel <riel@redhat.com>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent fa591c4a
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -1775,6 +1775,9 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
			that the amount of memory usable for all allocations
			is not too small.

	movable_node	[KNL,X86] Boot-time switch to enable the effects
			of CONFIG_MOVABLE_NODE=y. See mm/Kconfig for details.

	MTD_Partition=	[MTD]
			Format: <name>,<region-number>,<size>,<offset>

+11 −0
Original line number Diff line number Diff line
@@ -567,6 +567,17 @@ static int __init numa_init(int (*init_func)(void))
	ret = init_func();
	if (ret < 0)
		return ret;

	/*
	 * We reset memblock back to the top-down direction
	 * here because if we configured ACPI_NUMA, we have
	 * parsed SRAT in init_func(). It is ok to have the
	 * reset here even if we did't configure ACPI_NUMA
	 * or acpi numa init fails and fallbacks to dummy
	 * numa init.
	 */
	memblock_set_bottom_up(false);

	ret = numa_cleanup_meminfo(&numa_meminfo);
	if (ret < 0)
		return ret;
+12 −5
Original line number Diff line number Diff line
@@ -153,11 +153,18 @@ config MOVABLE_NODE
	help
	  Allow a node to have only movable memory.  Pages used by the kernel,
	  such as direct mapping pages cannot be migrated.  So the corresponding
	  memory device cannot be hotplugged.  This option allows users to
	  online all the memory of a node as movable memory so that the whole
	  node can be hotplugged.  Users who don't use the memory hotplug
	  feature are fine with this option on since they don't online memory
	  as movable.
	  memory device cannot be hotplugged.  This option allows the following
	  two things:
	  - When the system is booting, node full of hotpluggable memory can
	  be arranged to have only movable memory so that the whole node can
	  be hot-removed. (need movable_node boot option specified).
	  - After the system is up, the option allows users to online all the
	  memory of a node as movable memory so that the whole node can be
	  hot-removed.

	  Users who don't use the memory hotplug feature are fine with this
	  option on since they don't specify movable_node boot option or they
	  don't online memory as movable.

	  Say Y here if you want to hotplug a whole node.
	  Say N here if you want kernel to use memory on all nodes evenly.
+31 −0
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@
#include <linux/firmware-map.h>
#include <linux/stop_machine.h>
#include <linux/hugetlb.h>
#include <linux/memblock.h>

#include <asm/tlbflush.h>

@@ -1422,6 +1423,36 @@ static bool can_offline_normal(struct zone *zone, unsigned long nr_pages)
}
#endif /* CONFIG_MOVABLE_NODE */

static int __init cmdline_parse_movable_node(char *p)
{
#ifdef CONFIG_MOVABLE_NODE
	/*
	 * Memory used by the kernel cannot be hot-removed because Linux
	 * cannot migrate the kernel pages. When memory hotplug is
	 * enabled, we should prevent memblock from allocating memory
	 * for the kernel.
	 *
	 * ACPI SRAT records all hotpluggable memory ranges. But before
	 * SRAT is parsed, we don't know about it.
	 *
	 * The kernel image is loaded into memory at very early time. We
	 * cannot prevent this anyway. So on NUMA system, we set any
	 * node the kernel resides in as un-hotpluggable.
	 *
	 * Since on modern servers, one node could have double-digit
	 * gigabytes memory, we can assume the memory around the kernel
	 * image is also un-hotpluggable. So before SRAT is parsed, just
	 * allocate memory near the kernel image to try the best to keep
	 * the kernel away from hotpluggable memory.
	 */
	memblock_set_bottom_up(true);
#else
	pr_warn("movable_node option not supported\n");
#endif
	return 0;
}
early_param("movable_node", cmdline_parse_movable_node);

/* check which state of node_states will be changed when offline memory */
static void node_states_check_changes_offline(unsigned long nr_pages,
		struct zone *zone, struct memory_notify *arg)