From: David Hildenbrand <hidden> Date: 2020-03-11 12:30:48
Distributions nowadays use udev rules ([1] [2]) to specify if and
how to online hotplugged memory. The rules seem to get more complex with
many special cases. Due to the various special cases,
CONFIG_MEMORY_HOTPLUG_DEFAULT_ONLINE cannot be used. All memory hotplug
is handled via udev rules.
Everytime we hotplug memory, the udev rule will come to the same
conclusion. Especially Hyper-V (but also soon virtio-mem) add a lot of
memory in separate memory blocks and wait for memory to get onlined by user
space before continuing to add more memory blocks (to not add memory faster
than it is getting onlined). This of course slows down the whole memory
hotplug process.
To make the job of distributions easier and to avoid udev rules that get
more and more complicated, let's extend the mechanism provided by
- /sys/devices/system/memory/auto_online_blocks
- "memhp_default_state=" on the kernel cmdline
to be able to specify also "online_movable" as well as "online_kernel"
=== Example /usr/libexec/config-memhotplug ===
#!/bin/bash
VIRT=`systemd-detect-virt --vm`
ARCH=`uname -p`
sense_virtio_mem() {
if [ -d "/sys/bus/virtio/drivers/virtio_mem/" ]; then
DEVICES=`find /sys/bus/virtio/drivers/virtio_mem/ -maxdepth 1 -type l | wc -l`
if [ $DEVICES != "0" ]; then
return 0
fi
fi
return 1
}
if [ ! -e "/sys/devices/system/memory/auto_online_blocks" ]; then
echo "Memory hotplug configuration support missing in the kernel"
exit 1
fi
if grep "memhp_default_state=" /proc/cmdline > /dev/null; then
echo "Memory hotplug configuration overridden in kernel cmdline (memhp_default_state=)"
exit 1
fi
if [ $VIRT == "microsoft" ]; then
echo "Detected Hyper-V on $ARCH"
# Hyper-V wants all memory in ZONE_NORMAL
ONLINE_TYPE="online_kernel"
elif sense_virtio_mem; then
echo "Detected virtio-mem on $ARCH"
# virtio-mem wants all memory in ZONE_NORMAL
ONLINE_TYPE="online_kernel"
elif [ $ARCH == "s390x" ] || [ $ARCH == "s390" ]; then
echo "Detected $ARCH"
# standby memory should not be onlined automatically
ONLINE_TYPE="offline"
elif [ $ARCH == "ppc64" ] || [ $ARCH == "ppc64le" ]; then
echo "Detected" $ARCH
# PPC64 is handled via a user space daemon AFAIK
ONLINE_TYPE="offline"
elif [ $VIRT == "none" ]; then
echo "Detected bare-metal on $ARCH"
# Bare metal users expect hotplugged memory to be unpluggable. We assume
# that ZONE imbalances on such enterpise servers cannot happen and is
# properly documented
ONLINE_TYPE="online_movable"
else
# TODO: Hypervisors that want to unplug DIMMs and can guarantee that ZONE
# imbalances won't happen
echo "Detected $VIRT on $ARCH"
# Usually, ballooning is used in virtual environments, so memory should go to
# ZONE_NORMAL. However, sometimes "movable_node" is relevant.
ONLINE_TYPE="online"
fi
echo "Selected online_type:" $ONLINE_TYPE
# Configure what to do with memory that will be hotplugged in the future
echo $ONLINE_TYPE 2>/dev/null > /sys/devices/system/memory/auto_online_blocks
if [ $? != "0" ]; then
echo "Memory hotplug cannot be configured (e.g., old kernel or missing permissions)"
# A backup udev rule should handle old kernels if necessary
exit 1
fi
# Process all already pluggedd blocks (e.g., DIMMs, but also Hyper-V or virtio-mem)
if [ $ONLINE_TYPE != "offline" ]; then
for MEMORY in /sys/devices/system/memory/memory*; do
STATE=`cat $MEMORY/state`
if [ $STATE == "offline" ]; then
echo $ONLINE_TYPE > $MEMORY/state
fi
done
fi
=== Example /usr/lib/systemd/system/config-memhotplug.service ===
[Unit]
Description=Configure memory hotplug behavior
DefaultDependencies=no
Conflicts=shutdown.target
Before=sysinit.target shutdown.target
After=systemd-modules-load.service
ConditionPathExists=|/sys/devices/system/memory/auto_online_blocks
[Service]
ExecStart=/usr/libexec/config-memhotplug
Type=oneshot
TimeoutSec=0
RemainAfterExit=yes
[Install]
WantedBy=sysinit.target
=== Example modification to the 40-redhat.rules [2] ===
From: David Hildenbrand <hidden> Date: 2020-03-11 12:30:49
I have no idea why we have to start at -1. Just treat 0 as the special
case. Clarify a comment (which was wrong, when we come via
device_online() the first time, the online_type would have been 0 /
MEM_ONLINE). The default is now always MMOP_OFFLINE.
This is a preparation to use the online_type as an array index.
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Michal Hocko <mhocko@kernel.org>
Cc: Oscar Salvador <osalvador@suse.de>
Cc: "Rafael J. Wysocki" <rafael@kernel.org>
Cc: Baoquan He <redacted>
Cc: Wei Yang <redacted>
Signed-off-by: David Hildenbrand <redacted>
---
drivers/base/memory.c | 11 ++++-------
include/linux/memory_hotplug.h | 2 +-
2 files changed, 5 insertions(+), 8 deletions(-)
@@ -48,7 +48,7 @@ enum {/* Types for control the zone type of onlined and offlined memory */enum{/* Offline the memory. */-MMOP_OFFLINE=-1,+MMOP_OFFLINE=0,/* Online the memory. Zone depends, see default_zone_for_pfn(). */MMOP_ONLINE,/* Online the memory to ZONE_NORMAL. */
From: David Hildenbrand <hidden> Date: 2020-03-11 12:30:54
The name is misleading. Let's just name it like the online_type name we
expose to user space ("online").
Add some documentation to the types.
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Michal Hocko <mhocko@kernel.org>
Cc: Oscar Salvador <osalvador@suse.de>
Cc: "Rafael J. Wysocki" <rafael@kernel.org>
Cc: Baoquan He <redacted>
Cc: Wei Yang <redacted>
Signed-off-by: David Hildenbrand <redacted>
---
drivers/base/memory.c | 9 +++++----
include/linux/memory_hotplug.h | 6 +++++-
2 files changed, 10 insertions(+), 5 deletions(-)
@@ -47,9 +47,13 @@ enum {/* Types for control the zone type of onlined and offlined memory */enum{+/* Offline the memory. */MMOP_OFFLINE=-1,-MMOP_ONLINE_KEEP,+/* Online the memory. Zone depends, see default_zone_for_pfn(). */+MMOP_ONLINE,+/* Online the memory to ZONE_NORMAL. */MMOP_ONLINE_KERNEL,+/* Online the memory to ZONE_MOVABLE. */MMOP_ONLINE_MOVABLE,};
From: David Hildenbrand <hidden> Date: 2020-03-11 12:30:57
Let's use a simple array which we can reuse soon. While at it, move the
string->mmop conversion out of the device hotplug lock.
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Michal Hocko <mhocko@kernel.org>
Cc: Oscar Salvador <osalvador@suse.de>
Cc: "Rafael J. Wysocki" <rafael@kernel.org>
Cc: Baoquan He <redacted>
Cc: Wei Yang <redacted>
Signed-off-by: David Hildenbrand <redacted>
---
drivers/base/memory.c | 38 +++++++++++++++++++++++---------------
1 file changed, 23 insertions(+), 15 deletions(-)
From: David Hildenbrand <hidden> Date: 2020-03-11 12:31:05
... and rename it to memhp_default_online_type. This is a preparation
for more detailed default online behavior.
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Michal Hocko <mhocko@kernel.org>
Cc: Oscar Salvador <osalvador@suse.de>
Cc: "Rafael J. Wysocki" <rafael@kernel.org>
Cc: Baoquan He <redacted>
Cc: Wei Yang <redacted>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <redacted>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: "K. Y. Srinivasan" <kys@microsoft.com>
Cc: Haiyang Zhang <haiyangz@microsoft.com>
Cc: Stephen Hemminger <redacted>
Cc: Wei Liu <wei.liu@kernel.org>
Cc: Thomas Gleixner <redacted>
Cc: linuxppc-dev@lists.ozlabs.org
Cc: linux-hyperv@vger.kernel.org
Signed-off-by: David Hildenbrand <redacted>
---
arch/powerpc/platforms/powernv/memtrace.c | 2 +-
drivers/base/memory.c | 10 ++++------
drivers/hv/hv_balloon.c | 2 +-
include/linux/memory_hotplug.h | 3 ++-
mm/memory_hotplug.c | 13 +++++++------
5 files changed, 15 insertions(+), 15 deletions(-)
From: David Hildenbrand <hidden> Date: 2020-03-11 12:31:07
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 userspace to come up with the same answer.
E.g., HyperV always waits for a memory block to get onlined before
continuing, otherwise it might end up adding memory faster than
hotplugging it, which can result in strange OOM situations.
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/systemn/memory/auto_online_blocks
just like we are able to specify for a single memory block via
/sys/devices/systemn/memory/memoryX/state
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Michal Hocko <mhocko@kernel.org>
Cc: Oscar Salvador <osalvador@suse.de>
Cc: "Rafael J. Wysocki" <rafael@kernel.org>
Cc: Baoquan He <redacted>
Cc: Wei Yang <redacted>
Signed-off-by: David Hildenbrand <redacted>
---
drivers/base/memory.c | 11 +++++------
include/linux/memory_hotplug.h | 2 ++
mm/memory_hotplug.c | 8 ++++----
3 files changed, 11 insertions(+), 10 deletions(-)
On Wed, Mar 11, 2020 at 01:30:22PM +0100, David Hildenbrand wrote:
The name is misleading. Let's just name it like the online_type name we
expose to user space ("online").
Add some documentation to the types.
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Michal Hocko <mhocko@kernel.org>
Cc: Oscar Salvador <osalvador@suse.de>
Cc: "Rafael J. Wysocki" <rafael@kernel.org>
Cc: Baoquan He <redacted>
Cc: Wei Yang <redacted>
Signed-off-by: David Hildenbrand <redacted>
@@ -216,7 +216,7 @@ static int memory_subsys_online(struct device *dev)
* attribute and need to set the online_type.
*/
if (mem->online_type < 0)
- mem->online_type = MMOP_ONLINE_KEEP;
+ mem->online_type = MMOP_ONLINE;
ret = memory_block_change_state(mem, MEM_ONLINE, MEM_OFFLINE);
switch (online_type) {
case MMOP_ONLINE_KERNEL:
case MMOP_ONLINE_MOVABLE:
- case MMOP_ONLINE_KEEP:
+ case MMOP_ONLINE:
/* mem->online_type is protected by device_hotplug_lock */
mem->online_type = online_type;
ret = device_online(&mem->dev);
/* Types for control the zone type of onlined and offlined memory */
enum {
+ /* Offline the memory. */
MMOP_OFFLINE = -1,
- MMOP_ONLINE_KEEP,
+ /* Online the memory. Zone depends, see default_zone_for_pfn(). */
+ MMOP_ONLINE,
+ /* Online the memory to ZONE_NORMAL. */
MMOP_ONLINE_KERNEL,
+ /* Online the memory to ZONE_MOVABLE. */
MMOP_ONLINE_MOVABLE,
};
--
2.24.1
On Wed, Mar 11, 2020 at 01:30:23PM +0100, David Hildenbrand wrote:
I have no idea why we have to start at -1. Just treat 0 as the special
case. Clarify a comment (which was wrong, when we come via
device_online() the first time, the online_type would have been 0 /
MEM_ONLINE). The default is now always MMOP_OFFLINE.
This is a preparation to use the online_type as an array index.
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Michal Hocko <mhocko@kernel.org>
Cc: Oscar Salvador <osalvador@suse.de>
Cc: "Rafael J. Wysocki" <rafael@kernel.org>
Cc: Baoquan He <redacted>
Cc: Wei Yang <redacted>
Signed-off-by: David Hildenbrand <redacted>
@@ -211,17 +211,14 @@ static int memory_subsys_online(struct device *dev)
return 0;
/*
- * If we are called from state_store(), online_type will be
- * set >= 0 Otherwise we were called from the device online
- * attribute and need to set the online_type.
+ * When called via device_online() without configuring the online_type,
+ * we want to default to MMOP_ONLINE.
*/
- if (mem->online_type < 0)
+ if (mem->online_type == MMOP_OFFLINE)
mem->online_type = MMOP_ONLINE;
ret = memory_block_change_state(mem, MEM_ONLINE, MEM_OFFLINE);
-
- /* clear online_type */
- mem->online_type = -1;
+ mem->online_type = MMOP_OFFLINE;
return ret;
}
/* Types for control the zone type of onlined and offlined memory */
enum {
/* Offline the memory. */
- MMOP_OFFLINE = -1,
+ MMOP_OFFLINE = 0,
/* Online the memory. Zone depends, see default_zone_for_pfn(). */
MMOP_ONLINE,
/* Online the memory to ZONE_NORMAL. */
--
2.24.1
On Wed, Mar 11, 2020 at 01:30:24PM +0100, David Hildenbrand wrote:
quoted hunk
Let's use a simple array which we can reuse soon. While at it, move the
string->mmop conversion out of the device hotplug lock.
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Michal Hocko <mhocko@kernel.org>
Cc: Oscar Salvador <osalvador@suse.de>
Cc: "Rafael J. Wysocki" <rafael@kernel.org>
Cc: Baoquan He <redacted>
Cc: Wei Yang <redacted>
Signed-off-by: David Hildenbrand <redacted>
---
drivers/base/memory.c | 38 +++++++++++++++++++++++---------------
1 file changed, 23 insertions(+), 15 deletions(-)
On Wed, Mar 11, 2020 at 01:30:25PM +0100, David Hildenbrand wrote:
... and rename it to memhp_default_online_type. This is a preparation
for more detailed default online behavior.
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Michal Hocko <mhocko@kernel.org>
Cc: Oscar Salvador <osalvador@suse.de>
Cc: "Rafael J. Wysocki" <rafael@kernel.org>
Cc: Baoquan He <redacted>
Cc: Wei Yang <redacted>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <redacted>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: "K. Y. Srinivasan" <kys@microsoft.com>
Cc: Haiyang Zhang <haiyangz@microsoft.com>
Cc: Stephen Hemminger <redacted>
Cc: Wei Liu <wei.liu@kernel.org>
Cc: Thomas Gleixner <redacted>
Cc: linuxppc-dev@lists.ozlabs.org
Cc: linux-hyperv@vger.kernel.org
Signed-off-by: David Hildenbrand <redacted>
@@ -235,7 +235,7 @@ static int memtrace_online(void)
* If kernel isn't compiled with the auto online option
* we need to online the memory ourselves.
*/
- if (!memhp_auto_online) {
+ if (memhp_default_online_type == MMOP_OFFLINE) {
lock_device_hotplug();
walk_memory_blocks(ent->start, ent->size, NULL,
online_mem_block);
On Wed, Mar 11, 2020 at 01:30:26PM +0100, David Hildenbrand wrote:
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 userspace to come up with the same answer.
E.g., HyperV always waits for a memory block to get onlined before
continuing, otherwise it might end up adding memory faster than
hotplugging it, which can result in strange OOM situations.
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/systemn/memory/auto_online_blocks
just like we are able to specify for a single memory block via
/sys/devices/systemn/memory/memoryX/state
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Michal Hocko <mhocko@kernel.org>
Cc: Oscar Salvador <osalvador@suse.de>
Cc: "Rafael J. Wysocki" <rafael@kernel.org>
Cc: Baoquan He <redacted>
Cc: Wei Yang <redacted>
Signed-off-by: David Hildenbrand <redacted>
Ok, I got the reason to leave the change on string compare here.
Reviewed-by: Wei Yang <redacted>
On Wed, Mar 11, 2020 at 02:20:02PM +0000, Wei Yang wrote:
On Wed, Mar 11, 2020 at 01:30:24PM +0100, David Hildenbrand wrote:
quoted
Let's use a simple array which we can reuse soon. While at it, move the
string->mmop conversion out of the device hotplug lock.
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Michal Hocko <mhocko@kernel.org>
Cc: Oscar Salvador <osalvador@suse.de>
Cc: "Rafael J. Wysocki" <rafael@kernel.org>
Cc: Baoquan He <redacted>
Cc: Wei Yang <redacted>
Signed-off-by: David Hildenbrand <redacted>
Ok, I got the reason.
Reviewed-by: Wei Yang <redacted>
From: David Hildenbrand <hidden> Date: 2020-03-11 15:20:49
On 11.03.20 15:26, Wei Yang wrote:
On Wed, Mar 11, 2020 at 01:30:26PM +0100, David Hildenbrand wrote:
quoted
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 userspace to come up with the same answer.
E.g., HyperV always waits for a memory block to get onlined before
continuing, otherwise it might end up adding memory faster than
hotplugging it, which can result in strange OOM situations.
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/systemn/memory/auto_online_blocks
just like we are able to specify for a single memory block via
/sys/devices/systemn/memory/memoryX/state
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Michal Hocko <mhocko@kernel.org>
Cc: Oscar Salvador <osalvador@suse.de>
Cc: "Rafael J. Wysocki" <rafael@kernel.org>
Cc: Baoquan He <redacted>
Cc: Wei Yang <redacted>
Signed-off-by: David Hildenbrand <redacted>
Ok, I got the reason to leave the change on string compare here.
Thanks for your *very fast* review! :)
--
Thanks,
David / dhildenb
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 userspace to come up with the same answer.
E.g., HyperV always waits for a memory block to get onlined before
continuing, otherwise it might end up adding memory faster than
hotplugging it, which can result in strange OOM situations.
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/systemn/memory/auto_online_blocks
just like we are able to specify for a single memory block via
/sys/devices/systemn/memory/memoryX/state
Thank you for picking this up!
It's been awhile since I've added CONFIG_MEMORY_HOTPLUG_DEFAULT_ONLINE
but I vaguely recall one problem: memory hotplug may happen *very* early
(just because some memory is presented to a VM as hotplug memory, it is
not in e820). It happens way before we launch userspace (including
udev). The question is -- which ZONE will this memory be assigned too?
'memhp_default_state=' resolves the issue but nobody likes additional
kernel parameters for anything but
debug. CONFIG_MEMORY_HOTPLUG_DEFAULT_ONLINE was supposed to help, but it
is binary and distro-wide (so *all* deployments will get the same
default and as you validly stated we want it differently).
We could've added something like your example onlining script to the
kernel itself but this is likely going to be hard to sell: "policies
belong to userspace!" will likely be the answer.
So if we don't want to start the endless discussions (again), your
proposal is 'good enough'.
quoted hunk
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Michal Hocko <mhocko@kernel.org>
Cc: Oscar Salvador <osalvador@suse.de>
Cc: "Rafael J. Wysocki" <rafael@kernel.org>
Cc: Baoquan He <redacted>
Cc: Wei Yang <redacted>
Signed-off-by: David Hildenbrand <redacted>
---
drivers/base/memory.c | 11 +++++------
include/linux/memory_hotplug.h | 2 ++
mm/memory_hotplug.c | 8 ++++----
3 files changed, 11 insertions(+), 10 deletions(-)
From: David Hildenbrand <hidden> Date: 2020-03-11 17:06:09
On 11.03.20 17:55, Vitaly Kuznetsov wrote:
David Hildenbrand [off-list ref] writes:
quoted
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 userspace to come up with the same answer.
E.g., HyperV always waits for a memory block to get onlined before
continuing, otherwise it might end up adding memory faster than
hotplugging it, which can result in strange OOM situations.
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/systemn/memory/auto_online_blocks
just like we are able to specify for a single memory block via
/sys/devices/systemn/memory/memoryX/state
Thank you for picking this up!
It's been awhile since I've added CONFIG_MEMORY_HOTPLUG_DEFAULT_ONLINE
but I vaguely recall one problem: memory hotplug may happen *very* early
(just because some memory is presented to a VM as hotplug memory, it is
not in e820). It happens way before we launch userspace (including
udev). The question is -- which ZONE will this memory be assigned too?
If it's added via add_memory() ("hot/cold plugged memory") like ACPI
DIMMs not part of e820, Hyper-V balloon added memory, XEN balloon added
memory, s390x standby memory etc. the memory will be onlined as
configured via memhp_default_online_type. Assume that one is set to
"offline".
*If* userspace changes memhp_default_online_type (as in my script in the
cover letter), userspace has to online all memory that has been added
before userspace was active itself (again, as done in my script).
Memory not added via add_memory() is considered "initial memory" and not
as hot/cold plugged memory.
Same handling as for now using udev rules. (once userspace is up, udev
rules for all early added memory is triggered as well)
'memhp_default_state=' resolves the issue but nobody likes additional
kernel parameters for anything but
debug. CONFIG_MEMORY_HOTPLUG_DEFAULT_ONLINE was supposed to help, but it
is binary and distro-wide (so *all* deployments will get the same
default and as you validly stated we want it differently).
We could've added something like your example onlining script to the
kernel itself but this is likely going to be hard to sell: "policies
belong to userspace!" will likely be the answer.
From: Michal Hocko <mhocko@kernel.org> Date: 2020-03-16 15:12:30
On Wed 11-03-20 13:30:22, David Hildenbrand wrote:
The name is misleading. Let's just name it like the online_type name we
expose to user space ("online").
I would disagree the name is misleading. It just says that you want to
online and keep the zone type. Nothing I would insist on though.
quoted hunk
Add some documentation to the types.
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Michal Hocko <mhocko@kernel.org>
Cc: Oscar Salvador <osalvador@suse.de>
Cc: "Rafael J. Wysocki" <rafael@kernel.org>
Cc: Baoquan He <redacted>
Cc: Wei Yang <redacted>
Signed-off-by: David Hildenbrand <redacted>
---
drivers/base/memory.c | 9 +++++----
include/linux/memory_hotplug.h | 6 +++++-
2 files changed, 10 insertions(+), 5 deletions(-)
@@ -47,9 +47,13 @@ enum {/* Types for control the zone type of onlined and offlined memory */enum{+/* Offline the memory. */MMOP_OFFLINE=-1,-MMOP_ONLINE_KEEP,+/* Online the memory. Zone depends, see default_zone_for_pfn(). */+MMOP_ONLINE,+/* Online the memory to ZONE_NORMAL. */MMOP_ONLINE_KERNEL,+/* Online the memory to ZONE_MOVABLE. */MMOP_ONLINE_MOVABLE,};
From: Michal Hocko <mhocko@kernel.org> Date: 2020-03-16 15:19:32
On Wed 11-03-20 13:30:23, David Hildenbrand wrote:
I have no idea why we have to start at -1.
Because this is how the offline state offline was represented
originally.
Just treat 0 as the special
case. Clarify a comment (which was wrong, when we come via
device_online() the first time, the online_type would have been 0 /
MEM_ONLINE). The default is now always MMOP_OFFLINE.
git grep says that you have covered the only remaining place which
hasn't used the enum value.
This is a preparation to use the online_type as an array index.
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Michal Hocko <mhocko@kernel.org>
Cc: Oscar Salvador <osalvador@suse.de>
Cc: "Rafael J. Wysocki" <rafael@kernel.org>
Cc: Baoquan He <redacted>
Cc: Wei Yang <redacted>
Signed-off-by: David Hildenbrand <redacted>
@@ -48,7 +48,7 @@ enum {/* Types for control the zone type of onlined and offlined memory */enum{/* Offline the memory. */-MMOP_OFFLINE=-1,+MMOP_OFFLINE=0,/* Online the memory. Zone depends, see default_zone_for_pfn(). */MMOP_ONLINE,/* Online the memory to ZONE_NORMAL. */
From: Michal Hocko <mhocko@kernel.org> Date: 2020-03-16 15:20:59
On Wed 11-03-20 13:30:24, David Hildenbrand wrote:
Let's use a simple array which we can reuse soon. While at it, move the
string->mmop conversion out of the device hotplug lock.
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Michal Hocko <mhocko@kernel.org>
Cc: Oscar Salvador <osalvador@suse.de>
Cc: "Rafael J. Wysocki" <rafael@kernel.org>
Cc: Baoquan He <redacted>
Cc: Wei Yang <redacted>
Signed-off-by: David Hildenbrand <redacted>
From: Michal Hocko <mhocko@kernel.org> Date: 2020-03-16 15:31:37
On Wed 11-03-20 13:30:26, David Hildenbrand wrote:
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 userspace to come up with the same answer.
E.g., HyperV always waits for a memory block to get onlined before
continuing, otherwise it might end up adding memory faster than
hotplugging it, which can result in strange OOM situations.
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/systemn/memory/auto_online_blocks
just like we are able to specify for a single memory block via
/sys/devices/systemn/memory/memoryX/state
I still strongly believe that the whole interface is wrong. This is just
adding more lipstick on the pig. On the other hand I recognize that the
event based onlining is a PITA as well. The proper interface would
somehow communicate the type of the memory via the event or other sysfs
attribute and then the FW/HV could tell that this is an offline memory,
hotplugable memory or just an additional memory that doesn't need to
support hotremove by the consumer. The userspace or the kernel could
handle the hotadd request much more easier that way.
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Michal Hocko <mhocko@kernel.org>
Cc: Oscar Salvador <osalvador@suse.de>
Cc: "Rafael J. Wysocki" <rafael@kernel.org>
Cc: Baoquan He <redacted>
Cc: Wei Yang <redacted>
Signed-off-by: David Hildenbrand <redacted>
That being said, I will not object to this patch. I simply gave up
fighting this interface. So if it works for consumers and it doesn't
break the existing userspace (which is shouldn't AFAICS) then go ahead.
@@ -235,7 +235,7 @@ static int memtrace_online(void)*Ifkernelisn'tcompiledwiththeautoonlineoption*weneedtoonlinethememoryourselves.*/-if(!memhp_auto_online){+if(memhp_default_online_type==MMOP_OFFLINE){lock_device_hotplug();walk_memory_blocks(ent->start,ent->size,NULL,online_mem_block);
Whut? This stinks, doesn't it. For your defense, the original code is
fishy already but this just makes it even more ugly.
PPC64 onlines all memory directly from the kernel, and not triggered by
user space (I think that's ugly and not desired, but it is what it is
and I am not going to touch that).
See
arch/powerpc/platforms/pseries/hotplug-memory.c:dlpar_change_lmb_state().
Best I can do here is to also always online all memory.
What are your suggestions?
--
Thanks,
David / dhildenb
From: David Hildenbrand <hidden> Date: 2020-03-16 15:49:05
On 16.03.20 16:31, Michal Hocko wrote:
On Wed 11-03-20 13:30:26, David Hildenbrand wrote:
quoted
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 userspace to come up with the same answer.
E.g., HyperV always waits for a memory block to get onlined before
continuing, otherwise it might end up adding memory faster than
hotplugging it, which can result in strange OOM situations.
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/systemn/memory/auto_online_blocks
just like we are able to specify for a single memory block via
/sys/devices/systemn/memory/memoryX/state
I still strongly believe that the whole interface is wrong. This is just
adding more lipstick on the pig. On the other hand I recognize that the
event based onlining is a PITA as well. The proper interface would
somehow communicate the type of the memory via the event or other sysfs
attribute and then the FW/HV could tell that this is an offline memory,
hotplugable memory or just an additional memory that doesn't need to
support hotremove by the consumer. The userspace or the kernel could
handle the hotadd request much more easier that way.
Yeah, and I proposed patches like that which were not well received [1] [2].
But then, user space usually wants to online all memory the same way
right now. Also, HyperV and virtio-mem don't want to wait for onlining
to happen in user space, because it slows down the whole "add a hole
bunch of memory" process.
quoted
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Michal Hocko <mhocko@kernel.org>
Cc: Oscar Salvador <osalvador@suse.de>
Cc: "Rafael J. Wysocki" <rafael@kernel.org>
Cc: Baoquan He <redacted>
Cc: Wei Yang <redacted>
Signed-off-by: David Hildenbrand <redacted>
That being said, I will not object to this patch. I simply gave up
fighting this interface. So if it works for consumers and it doesn't
break the existing userspace (which is shouldn't AFAICS) then go ahead.