mm/memory_hotplug: Interface to add driver-managed system ram
Subsystems (7)
v3 cover mm/memory_hotplug: Interface to add driver-managed system ram
Third time is the charm? Let's see ... :)
This is the follow up of [1]:
[PATCH v1 0/3] mm/memory_hotplug: Make virtio-mem play nicely with kexec-tools
and [2]:
[PATCH v2 0/3] mm/memory_hotplug: Allow to not create firmware memmap entries
kexec (via kexec_load()) can currently not properly handle memory added via dax/kmem, and will have similar issues with virtio-mem. kexec-tools will currently add all memory to the fixed-up initial firmware memmap. In case of dax/kmem, this means that - in contrast to a proper reboot - how that persistent memory will be used can no longer be configured by the kexec'd kernel. In case of virtio-mem it will be harmful, because that memory might contain inaccessible pieces that require coordination with hypervisor first.
In both cases, we want to let the driver in the kexec'd kernel handle detecting and adding the memory, like during an ordinary reboot. Introduce add_memory_driver_managed(). More on the samentics are in patch #1.
In the future, we might want to make this behavior configurable for dax/kmem- either by configuring it in the kernel (which would then also allow to configure kexec_file_load()) or in kexec-tools by also adding "System RAM (kmem)" memory from /proc/iomem to the fixed-up initial firmware memmap.
More on the motivation can be found in [1] and [2].
v2 -> v3:
- Don't use flags for add_memory() and friends, provide add_memory_driver_managed() instead.
- Flag memory resources via IORESOURCE_MEM_DRIVER_MANAGED and handle them in kexec.
- Name memory resources "System RAM ($DRIVER)", visible via /proc/iomem
- Added more details to the patch descriptions, especially regarding the history of /sys/firmware/memmap
- Add a comment to the device-dax change. Dropped Dave's Ack as the
v1 -> v2:
- Don't change the resource name
- Rename the flag to MHP_NO_FIRMWARE_MEMMAP to reflect what it is doing
- Rephrase subjects/descriptions
- Use the flag for dax/kmem
[1] https://lkml.kernel.org/r/[email protected]
[2] https://lkml.kernel.org/r/[email protected]
David Hildenbrand (3):
mm/memory_hotplug: Introduce add_memory_device_managed()
kexec_file: Don't place kexec images on IORESOURCE_MEM_DRIVER_MANAGED
device-dax: Add memory via add_memory_driver_managed()
drivers/dax/kmem.c | 8 ++++- include/linux/ioport.h | 1 + include/linux/memory_hotplug.h | 2 ++ kernel/kexec_file.c | 5 +++ mm/memory_hotplug.c | 62 +++++++++++++++++++++++++++++++--- 5 files changed, 73 insertions(+), 5 deletions(-)
Signature · 1 line
2.25.3
PATCH v3 1/3 mm/memory_hotplug: Introduce add_memory_device_managed()
Some device drivers rely on memory they managed to not get added to the initial (firmware) memmap as system RAM - so it's not used as initial system RAM by the kernel and the driver is under control. While this is the case during cold boot and after a reboot, kexec is not aware of that and might add such memory to the initial (firmware) memmap of the kexec kernel. We need ways to teach kernel and userspace that this system ram is different.
For example, dax/kmem allows to decide at runtime if persistent memory is to be used as system ram. Another future user is virtio-mem, which has to coordinate with its hypervisor to deal with inaccessible parts within memory resources.
We want to let users in the kernel (esp. kexec) but also user space (esp. kexec-tools) know that this memory has different semantics and needs to be handled differently:
1. Don't create entries in /sys/firmware/memmap/
2. Name the memory resource "System RAM ($DRIVER)" (exposed via /proc/iomem) ($DRIVER might be "kmem", "virtio_mem").
3. Flag the memory resource IORESOURCE_MEM_DRIVER_MANAGED
/sys/firmware/memmap/ [1] represents the "raw firmware-provided memory map" because "on most architectures that firmware-provided memory map is modified afterwards by the kernel itself". The primary user is kexec on x86-64. Since commit d96ae5309165 ("memory-hotplug: create /sys/firmware/memmap entry for new memory"), we add all hotplugged memory to that firmware memmap - which makes perfect sense for traditional memory hotplug on x86-64, where real HW will also add hotplugged DIMMs to the firmware memmap. We replicate what the "raw firmware-provided memory map" looks like after hot(un)plug.
To keep things simple, let the user provide the full resource name instead of only the driver name - this way, we don't have to manually allocate/craft strings for memory resources. Also use the resource name to make decisions, to avoid passing additional flags. In case the name isn't "System RAM", it's special.
We don't have to worry about firmware_map_remove() on the removal path. If there is no entry, it will simply return with -EINVAL.
We'll adapt dax/kmem in a follow-up patch.
[1] https://www.kernel.org/doc/Documentation/ABI/testing/sysfs-firmware-memmap
--- include/linux/ioport.h | 1 + include/linux/memory_hotplug.h | 2 ++ mm/memory_hotplug.c | 62 +++++++++++++++++++++++++++++++--- 3 files changed, 61 insertions(+), 4 deletions(-)
include/linux/ioport.h +1 -0
@@ -103,6 +103,7 @@ struct resource {#define IORESOURCE_MEM_32BIT (3<<3)#define IORESOURCE_MEM_SHADOWABLE (1<<5)/* dup: IORESOURCE_SHADOWABLE */ #define IORESOURCE_MEM_EXPANSIONROM (1<<6) +#define IORESOURCE_MEM_DRIVER_MANAGED (1<<7)/* PnP I/O specific bits (IORESOURCE_BITS) */ #define IORESOURCE_IO_16BIT_ADDR (1<<0)
include/linux/memory_hotplug.h +2 -0
@@ -342,6 +342,8 @@ extern void __ref free_area_init_core_hotplug(int nid);extern int __add_memory (int nid,u64 start,u64 size);extern int add_memory (int nid,u64 start,u64 size);extern int add_memory_resource (int nid,struct resource *resource); +extern int add_memory_driver_managed (int nid,u64 start,u64 size, +const char *resource_name);extern void move_pfn_range_to_zone (struct zone *zone,unsigned long start_pfn,unsigned long nr_pages,struct vmem_altmap *altmap); extern void remove_pfn_range_from_zone(struct zone *zone,
mm/memory_hotplug.c +58 -4
89 lines not on this page · raw message
Signature · 1 line
2.25.3
Re: [PATCH v3 1/3] mm/memory_hotplug: Introduce add_memory_device_managed()
Looks good to me.
_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec
Re: [PATCH v3 1/3] mm/memory_hotplug: Introduce add_memory_device_managed()
In reply to David HildenbrandTypo in $SUBJECT, should be "add_memory_driver_managed" ...
Signature · 3 lines
Thanks, David / dhildenb
PATCH v3 2/3 kexec_file: Don't place kexec images on IORESOURCE_MEM_DRIVER_MANAGED
In reply to David HildenbrandMemory flagged with IORESOURCE_MEM_DRIVER_MANAGED is special - it won't be part of the initial memmap of the kexec kernel and not all memory might be accessible. Don't place any kexec images onto it.
--- kernel/kexec_file.c | 5 +++++ 1 file changed, 5 insertions(+)
kernel/kexec_file.c +5 -0
@@ -540,6 +540,11 @@ static int locate_mem_hole_callback(struct resource *res, void *arg)unsigned long sz = end - start +1 ;/* Returning 0 will take to next memory range */ + +/* Don't use memory that will be detected and handled by a driver. */ +if (res->flags &IORESOURCE_MEM_DRIVER_MANAGED ) +return 0 ; +if (sz < kbuf->memsz)return 0 ;
Signature · 1 line
2.25.3
PATCH v3 3/3 device-dax: Add memory via add_memory_driver_managed()
In reply to David HildenbrandCurrently, when adding memory, we create entries in /sys/firmware/memmap/ as "System RAM". This will lead to kexec-tools to add that memory to the fixed-up initial memmap for a kexec kernel (loaded via kexec_load()). The memory will be considered initial System RAM by the kexec'd kernel and can no longer be reconfigured. This is not what happens during a real reboot.
Let's add our memory via add_memory_driver_managed() now, so we won't create entries in /sys/firmware/memmap/ and indicate the memory as "System RAM (kmem)" in /proc/iomem. This allows everybody (especially kexec-tools) to identify that this memory is special and has to be treated differently than ordinary (hotplugged) System RAM.
Before configuring the namespace:
[root@localhost ~]# cat /proc/iomem ... 140000000-33fffffff : Persistent Memory 140000000-33fffffff : namespace0.0 3280000000-32ffffffff : PCI Bus 0000:00
After configuring the namespace:
[root@localhost ~]# cat /proc/iomem ... 140000000-33fffffff : Persistent Memory 140000000-1481fffff : namespace0.0 148200000-33fffffff : dax0.0 3280000000-32ffffffff : PCI Bus 0000:00
After loading kmem before this change:
[root@localhost ~]# cat /proc/iomem ... 140000000-33fffffff : Persistent Memory 140000000-1481fffff : namespace0.0 150000000-33fffffff : dax0.0 150000000-33fffffff : System RAM 3280000000-32ffffffff : PCI Bus 0000:00
After loading kmem after this change:
[root@localhost ~]# cat /proc/iomem ... 140000000-33fffffff : Persistent Memory 140000000-1481fffff : namespace0.0 150000000-33fffffff : dax0.0 150000000-33fffffff : System RAM (kmem) 3280000000-32ffffffff : PCI Bus 0000:00
After a proper reboot:
[root@localhost ~]# cat /proc/iomem ... 140000000-33fffffff : Persistent Memory 140000000-1481fffff : namespace0.0 148200000-33fffffff : dax0.0 3280000000-32ffffffff : PCI Bus 0000:00
Within the kexec kernel before this change:
[root@localhost ~]# cat /proc/iomem ... 140000000-33fffffff : Persistent Memory 140000000-1481fffff : namespace0.0 150000000-33fffffff : System RAM 3280000000-32ffffffff : PCI Bus 0000:00
Within the kexec kernel after this change:
[root@localhost ~]# cat /proc/iomem ... 140000000-33fffffff : Persistent Memory 140000000-1481fffff : namespace0.0 148200000-33fffffff : dax0.0 3280000000-32ffffffff : PCI Bus 0000:00
/sys/firmware/memmap/ before this change:
0000000000000000-000000000009fc00 (System RAM) 000000000009fc00-00000000000a0000 (Reserved) 00000000000f0000-0000000000100000 (Reserved) 0000000000100000-00000000bffdf000 (System RAM) 00000000bffdf000-00000000c0000000 (Reserved) 00000000feffc000-00000000ff000000 (Reserved) 00000000fffc0000-0000000100000000 (Reserved) 0000000100000000-0000000140000000 (System RAM) 0000000150000000-0000000340000000 (System RAM)
/sys/firmware/memmap/ after a proper reboot:
0000000000000000-000000000009fc00 (System RAM) 000000000009fc00-00000000000a0000 (Reserved) 00000000000f0000-0000000000100000 (Reserved) 0000000000100000-00000000bffdf000 (System RAM) 00000000bffdf000-00000000c0000000 (Reserved) 00000000feffc000-00000000ff000000 (Reserved) 00000000fffc0000-0000000100000000 (Reserved) 0000000100000000-0000000140000000 (System RAM)
/sys/firmware/memmap/ after this change:
0000000000000000-000000000009fc00 (System RAM) 000000000009fc00-00000000000a0000 (Reserved) 00000000000f0000-0000000000100000 (Reserved) 0000000000100000-00000000bffdf000 (System RAM) 00000000bffdf000-00000000c0000000 (Reserved) 00000000feffc000-00000000ff000000 (Reserved) 00000000fffc0000-0000000100000000 (Reserved) 0000000100000000-0000000140000000 (System RAM)
kexec-tools already seem to basically ignore any System RAM that's not on top level when searching for areas to place kexec images - but also for determining crash areas to dump via kdump. Changing the resource name won't have an impact.
--- drivers/dax/kmem.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
drivers/dax/kmem.c +7 -1
@@ -65,7 +65,13 @@ int dev_dax_kmem_probe(struct device *dev) new_res->flags =IORESOURCE_SYSTEM_RAM ; new_res->name =dev_name (dev); - rc =add_memory (numa_node, new_res->start,resource_size (new_res)); +/* +* Ensure that future kexec'd kernels will not treat this as RAM +* automatically. +*/ + rc =add_memory_driver_managed (numa_node, new_res->start, +resource_size (new_res), +"System RAM (kmem)" );if (rc) {release_resource (new_res);kfree (new_res);
Signature · 7 lines
2.25.3 _______________________________________________ kexec mailing list [email protected] http://lists.infradead.org/mailman/listinfo/kexec
Re: [PATCH v3 3/3] device-dax: Add memory via add_memory_driver_managed()
Quoted 130 lines
Currently, when adding memory, we create entries in
/sys/firmware/memmap/as "System RAM". This will lead to kexec-tools to add that memory to the fixed-up initial memmap for a kexec kernel (loaded viakexec_load()). The memory will be considered initial System RAM by the kexec'd kernel and can no longer be reconfigured. This is not what happens during a real reboot.Let's add our memory via
add_memory_driver_managed()now, so we won't create entries in/sys/firmware/memmap/and indicate the memory as "System RAM (kmem)" in/proc/iomem. This allows everybody (especially kexec-tools) to identify that this memory is special and has to be treated differently than ordinary (hotplugged) System RAM.Before configuring the namespace:
[root@localhost ~]# cat /proc/iomem ... 140000000-33fffffff : Persistent Memory 140000000-33fffffff : namespace0.0 3280000000-32ffffffff : PCI Bus 0000:00After configuring the namespace:
[root@localhost ~]# cat /proc/iomem ... 140000000-33fffffff : Persistent Memory 140000000-1481fffff : namespace0.0 148200000-33fffffff : dax0.0 3280000000-32ffffffff : PCI Bus 0000:00After loading kmem before this change:
[root@localhost ~]# cat /proc/iomem ... 140000000-33fffffff : Persistent Memory 140000000-1481fffff : namespace0.0 150000000-33fffffff : dax0.0 150000000-33fffffff : System RAM 3280000000-32ffffffff : PCI Bus 0000:00After loading kmem after this change:
[root@localhost ~]# cat /proc/iomem ... 140000000-33fffffff : Persistent Memory 140000000-1481fffff : namespace0.0 150000000-33fffffff : dax0.0 150000000-33fffffff : System RAM (kmem) 3280000000-32ffffffff : PCI Bus 0000:00After a proper reboot:
[root@localhost ~]# cat /proc/iomem ... 140000000-33fffffff : Persistent Memory 140000000-1481fffff : namespace0.0 148200000-33fffffff : dax0.0 3280000000-32ffffffff : PCI Bus 0000:00Within the kexec kernel before this change:
[root@localhost ~]# cat /proc/iomem ... 140000000-33fffffff : Persistent Memory 140000000-1481fffff : namespace0.0 150000000-33fffffff : System RAM 3280000000-32ffffffff : PCI Bus 0000:00Within the kexec kernel after this change:
[root@localhost ~]# cat /proc/iomem ... 140000000-33fffffff : Persistent Memory 140000000-1481fffff : namespace0.0 148200000-33fffffff : dax0.0 3280000000-32ffffffff : PCI Bus 0000:00
/sys/firmware/memmap/before this change:0000000000000000-000000000009fc00 (System RAM) 000000000009fc00-00000000000a0000 (Reserved) 00000000000f0000-0000000000100000 (Reserved) 0000000000100000-00000000bffdf000 (System RAM) 00000000bffdf000-00000000c0000000 (Reserved) 00000000feffc000-00000000ff000000 (Reserved) 00000000fffc0000-0000000100000000 (Reserved) 0000000100000000-0000000140000000 (System RAM) 0000000150000000-0000000340000000 (System RAM)
/sys/firmware/memmap/after a proper reboot:0000000000000000-000000000009fc00 (System RAM) 000000000009fc00-00000000000a0000 (Reserved) 00000000000f0000-0000000000100000 (Reserved) 0000000000100000-00000000bffdf000 (System RAM) 00000000bffdf000-00000000c0000000 (Reserved) 00000000feffc000-00000000ff000000 (Reserved) 00000000fffc0000-0000000100000000 (Reserved) 0000000100000000-0000000140000000 (System RAM)
/sys/firmware/memmap/after this change:0000000000000000-000000000009fc00 (System RAM) 000000000009fc00-00000000000a0000 (Reserved) 00000000000f0000-0000000000100000 (Reserved) 0000000000100000-00000000bffdf000 (System RAM) 00000000bffdf000-00000000c0000000 (Reserved) 00000000feffc000-00000000ff000000 (Reserved) 00000000fffc0000-0000000100000000 (Reserved) 0000000100000000-0000000140000000 (System RAM)kexec-tools already seem to basically ignore any System RAM that's not on top level when searching for areas to place kexec images - but also for determining crash areas to dump via kdump. Changing the resource name won't have an impact.
Cc Andrew Morton <[email protected]>Cc Michal Hocko <[email protected]>Cc Pankaj Gupta <[email protected]>Cc Wei Yang <[email protected]>Cc Baoquan He <[email protected]>Cc Dave Hansen <[email protected]>Cc Eric Biederman <[email protected]>Cc Pavel Tatashin <[email protected]>Cc Dan Williams <[email protected]>Signed-off-by David Hildenbrand <[email protected]>--- drivers/dax/kmem.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)drivers/dax/kmem.c +1
-1@@ -65,7 +65,13 @@ int dev_dax_kmem_probe(struct device *dev) new_res->flags =IORESOURCE_SYSTEM_RAM ; new_res->name =dev_name (dev); - rc =add_memory (numa_node, new_res->start,resource_size (new_res)); +/*
drivers/dax/kmem.c int dev_dax_kmem_probe(struct device *dev)
Quoted 10 lines
drivers/dax/kmem.c +6
-1+* Ensure that future kexec'd kernels will not treat this as RAM +* automatically. +*/ + rc =add_memory_driver_managed (numa_node, new_res->start, +resource_size (new_res), +"System RAM (kmem)" );if (rc) {release_resource (new_res);kfree (new_res); --
Quoted 2 lines
2.25.3
_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec