2022-06-14 09:26:42

by mawupeng

[permalink] [raw]
Subject: [PATCH v5 0/5] introduce mirrored memory support for arm64

From: Ma Wupeng <[email protected]>

Commit b05b9f5f9dcf ("x86, mirror: x86 enabling - find mirrored memory ranges")
introduced mirrored memory support for x86. This support rely on UEFI to
report mirrored memory address ranges. See UEFI 2.5 spec pages 157-158:

http://www.uefi.org/sites/default/files/resources/UEFI%202_5.pdf

Memory mirroring is a technique used to separate memory into two separate
channels, usually on a memory device, like a server. In memory mirroring,
one channel is copied to another to create redundancy. This method makes
input/output (I/O) registers and memory appear with more than one address
range because the same physical byte is accessible at more than one
address. Using memory mirroring, higher memory reliability and a higher
level of memory consolidation are possible.

These EFI memory regions have various attributes, and the "mirrored"
attribute is one of them. The physical memory region whose descriptors
in EFI memory map has EFI_MEMORY_MORE_RELIABLE attribute (bit: 16) are
mirrored. The address range mirroring feature of the kernel arranges such
mirrored regions into normal zones and other regions into movable zones.

Arm64 can support this too. So mirrored memory support is added to support
arm64.

The main purpose of this patch set is to introduce mirrored support for
arm64 and we have already fixed the problems we had which is shown in
patch #5 to patch #8 and try to bring total isolation in patch #9 which
will disable mirror feature if kernelcore is not specified.

In order to test this support in arm64:
- patch this patch set
- add kernelcore=mirror in kernel parameter
- start you kernel

Patch #1 introduce mirrored memory support form arm64.
Patch #2-#4 fix some bugs for arm64 if memory reliable is enabled.
Patch #5 disable mirror feature if kernelcore is not specified.

Thanks to Ard Biesheuvel's hard work [1], now kernel will perfer mirrored
memory if kaslr is enabled.

[1] https://lore.kernel.org/linux-arm-kernel/CAMj1kXEPVEzMgOM4+Yj6PxHA-jFuDOAUdDJSiSxy_XaP4P7LSw@mail.gmail.com/T/

Changelog since v4:
- merge the first two patches into one
- change __initdata to __initdata_memblock in patch #5

Changelog since v3:
- limit warning message in vmemmap_verify via pr_warn_once()
- only clear memblock_nomap flags rather than bring the mirrored flag back
- disable mirrored feature in memblock_mark_mirror()

Changelog since v2:
- remove efi_fake_mem support
- remove Commit ("remove some redundant code in ia64 efi_init") since
efi_print_memmap() is not public
- add mirror flag back on initrd memory

Changelog since v1:
- update changelog in cover letter
- use PHYS_PFN in patch #7

Ma Wupeng (5):
efi: arm64: Introduce ability to find mirrored memory ranges
mm: Ratelimited mirrored memory related warning messages
mm: Limit warning message in vmemmap_verify() to once
arm64: mm: Only remove nomap flag for initrd
memblock: Disable mirror feature if kernelcore is not specified

arch/arm64/mm/init.c | 2 +-
arch/x86/include/asm/efi.h | 4 ----
arch/x86/platform/efi/efi.c | 23 -----------------------
drivers/firmware/efi/efi-init.c | 1 +
drivers/firmware/efi/efi.c | 23 +++++++++++++++++++++++
include/linux/efi.h | 3 +++
mm/internal.h | 2 ++
mm/memblock.c | 7 +++++--
mm/page_alloc.c | 2 +-
mm/sparse-vmemmap.c | 2 +-
10 files changed, 37 insertions(+), 32 deletions(-)

--
2.25.1


2022-06-14 09:27:59

by mawupeng

[permalink] [raw]
Subject: [PATCH v5 3/5] mm: Limit warning message in vmemmap_verify() to once

From: Ma Wupeng <[email protected]>

For a system only have limited mirrored memory or some numa node without
mirrored memory, the per node vmemmap page_structs prefer to allocate
memory from mirrored region, which will lead to vmemmap_verify() in
vmemmap_populate_basepages() report lots of warning message.

This patch change the frequency of "potential offnode page_structs" warning
messages to only once to avoid a very long print during bootup.

Signed-off-by: Ma Wupeng <[email protected]>
Acked-by: David Hildenbrand <[email protected]>
---
mm/sparse-vmemmap.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/mm/sparse-vmemmap.c b/mm/sparse-vmemmap.c
index f4fa61dbbee3..f34c6889b0a6 100644
--- a/mm/sparse-vmemmap.c
+++ b/mm/sparse-vmemmap.c
@@ -528,7 +528,7 @@ void __meminit vmemmap_verify(pte_t *pte, int node,
int actual_node = early_pfn_to_nid(pfn);

if (node_distance(actual_node, node) > LOCAL_DISTANCE)
- pr_warn("[%lx-%lx] potential offnode page_structs\n",
+ pr_warn_once("[%lx-%lx] potential offnode page_structs\n",
start, end - 1);
}

--
2.25.1

2022-06-14 09:28:38

by mawupeng

[permalink] [raw]
Subject: [PATCH v5 1/5] efi: arm64: Introduce ability to find mirrored memory ranges

From: Ma Wupeng <[email protected]>

Commit b05b9f5f9dcf ("x86, mirror: x86 enabling - find mirrored memory
ranges") introduce the efi_find_mirror() function on x86. In order to reuse
the API we make it public.

Arm64 can support mirrored memory too, so function efi_find_mirror() is added to
efi_init() to this support for arm64.

Since efi_init() is shared by ARM, arm64 and riscv, this patch will bring
mirror memory support for these architectures, but this support is only tested
in arm64.

Signed-off-by: Ma Wupeng <[email protected]>
---
arch/x86/include/asm/efi.h | 4 ----
arch/x86/platform/efi/efi.c | 23 -----------------------
drivers/firmware/efi/efi-init.c | 1 +
drivers/firmware/efi/efi.c | 23 +++++++++++++++++++++++
include/linux/efi.h | 3 +++
5 files changed, 27 insertions(+), 27 deletions(-)

diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h
index 71943dce691e..eb90206eae80 100644
--- a/arch/x86/include/asm/efi.h
+++ b/arch/x86/include/asm/efi.h
@@ -383,7 +383,6 @@ static inline bool efi_is_64bit(void)
extern bool efi_reboot_required(void);
extern bool efi_is_table_address(unsigned long phys_addr);

-extern void efi_find_mirror(void);
extern void efi_reserve_boot_services(void);
#else
static inline void parse_efi_setup(u64 phys_addr, u32 data_len) {}
@@ -395,9 +394,6 @@ static inline bool efi_is_table_address(unsigned long phys_addr)
{
return false;
}
-static inline void efi_find_mirror(void)
-{
-}
static inline void efi_reserve_boot_services(void)
{
}
diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index 1591d67e0bcd..6e598bd78eef 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -108,29 +108,6 @@ static int __init setup_add_efi_memmap(char *arg)
}
early_param("add_efi_memmap", setup_add_efi_memmap);

-void __init efi_find_mirror(void)
-{
- efi_memory_desc_t *md;
- u64 mirror_size = 0, total_size = 0;
-
- if (!efi_enabled(EFI_MEMMAP))
- return;
-
- for_each_efi_memory_desc(md) {
- unsigned long long start = md->phys_addr;
- unsigned long long size = md->num_pages << EFI_PAGE_SHIFT;
-
- total_size += size;
- if (md->attribute & EFI_MEMORY_MORE_RELIABLE) {
- memblock_mark_mirror(start, size);
- mirror_size += size;
- }
- }
- if (mirror_size)
- pr_info("Memory: %lldM/%lldM mirrored memory\n",
- mirror_size>>20, total_size>>20);
-}
-
/*
* Tell the kernel about the EFI memory map. This might include
* more than the max 128 entries that can fit in the passed in e820
diff --git a/drivers/firmware/efi/efi-init.c b/drivers/firmware/efi/efi-init.c
index b2c829e95bd1..8e3a0d14dac5 100644
--- a/drivers/firmware/efi/efi-init.c
+++ b/drivers/firmware/efi/efi-init.c
@@ -241,6 +241,7 @@ void __init efi_init(void)
*/
early_init_dt_check_for_usable_mem_range();
+ efi_find_mirror();
efi_esrt_init();
efi_mokvar_table_init();

memblock_reserve(data.phys_map & PAGE_MASK,
diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
index 860534bcfdac..79c232e07de7 100644
--- a/drivers/firmware/efi/efi.c
+++ b/drivers/firmware/efi/efi.c
@@ -446,6 +446,29 @@ static int __init efisubsys_init(void)

subsys_initcall(efisubsys_init);

+void __init efi_find_mirror(void)
+{
+ efi_memory_desc_t *md;
+ u64 mirror_size = 0, total_size = 0;
+
+ if (!efi_enabled(EFI_MEMMAP))
+ return;
+
+ for_each_efi_memory_desc(md) {
+ unsigned long long start = md->phys_addr;
+ unsigned long long size = md->num_pages << EFI_PAGE_SHIFT;
+
+ total_size += size;
+ if (md->attribute & EFI_MEMORY_MORE_RELIABLE) {
+ memblock_mark_mirror(start, size);
+ mirror_size += size;
+ }
+ }
+ if (mirror_size)
+ pr_info("Memory: %lldM/%lldM mirrored memory\n",
+ mirror_size>>20, total_size>>20);
+}
+
/*
* Find the efi memory descriptor for a given physical address. Given a
* physical address, determine if it exists within an EFI Memory Map entry,
diff --git a/include/linux/efi.h b/include/linux/efi.h
index 7d9b0bb47eb3..53f64c14a525 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -872,6 +872,7 @@ static inline bool efi_rt_services_supported(unsigned int mask)
{
return (efi.runtime_supported_mask & mask) == mask;
}
+extern void efi_find_mirror(void);
#else
static inline bool efi_enabled(int feature)
{
@@ -889,6 +890,8 @@ static inline bool efi_rt_services_supported(unsigned int mask)
{
return false;
}
+
+static inline void efi_find_mirror(void) {}
#endif

extern int efi_status_to_err(efi_status_t status);
--
2.25.1

2022-06-15 04:25:27

by Kefeng Wang

[permalink] [raw]
Subject: Re: [PATCH v5 0/5] introduce mirrored memory support for arm64


On 2022/6/14 17:21, Wupeng Ma wrote:
> From: Ma Wupeng <[email protected]>
>
> Commit b05b9f5f9dcf ("x86, mirror: x86 enabling - find mirrored memory ranges")
> introduced mirrored memory support for x86. This support rely on UEFI to
> report mirrored memory address ranges. See UEFI 2.5 spec pages 157-158:
>
> http://www.uefi.org/sites/default/files/resources/UEFI%202_5.pdf
>
> Memory mirroring is a technique used to separate memory into two separate
> channels, usually on a memory device, like a server. In memory mirroring,
> one channel is copied to another to create redundancy. This method makes
> input/output (I/O) registers and memory appear with more than one address
> range because the same physical byte is accessible at more than one
> address. Using memory mirroring, higher memory reliability and a higher
> level of memory consolidation are possible.
>
> These EFI memory regions have various attributes, and the "mirrored"
> attribute is one of them. The physical memory region whose descriptors
> in EFI memory map has EFI_MEMORY_MORE_RELIABLE attribute (bit: 16) are
> mirrored. The address range mirroring feature of the kernel arranges such
> mirrored regions into normal zones and other regions into movable zones.
>
> Arm64 can support this too. So mirrored memory support is added to support
> arm64.
>
> The main purpose of this patch set is to introduce mirrored support for
> arm64 and we have already fixed the problems we had which is shown in
> patch #5 to patch #8 and try to bring total isolation in patch #9 which
> will disable mirror feature if kernelcore is not specified.
>
> In order to test this support in arm64:
> - patch this patch set
> - add kernelcore=mirror in kernel parameter
> - start you kernel
>
> Patch #1 introduce mirrored memory support form arm64.
> Patch #2-#4 fix some bugs for arm64 if memory reliable is enabled.
> Patch #5 disable mirror feature if kernelcore is not specified.
>
> Thanks to Ard Biesheuvel's hard work [1], now kernel will perfer mirrored
> memory if kaslr is enabled.
>
> [1] https://lore.kernel.org/linux-arm-kernel/CAMj1kXEPVEzMgOM4+Yj6PxHA-jFuDOAUdDJSiSxy_XaP4P7LSw@mail.gmail.com/T/

For series,

Reviewed-by: Kefeng Wang<[email protected]>

>
> Changelog since v4:
> - merge the first two patches into one
> - change __initdata to __initdata_memblock in patch #5
>
> Changelog since v3:
> - limit warning message in vmemmap_verify via pr_warn_once()
> - only clear memblock_nomap flags rather than bring the mirrored flag back
> - disable mirrored feature in memblock_mark_mirror()
>
> Changelog since v2:
> - remove efi_fake_mem support
> - remove Commit ("remove some redundant code in ia64 efi_init") since
> efi_print_memmap() is not public
> - add mirror flag back on initrd memory
>
> Changelog since v1:
> - update changelog in cover letter
> - use PHYS_PFN in patch #7
>
> Ma Wupeng (5):
> efi: arm64: Introduce ability to find mirrored memory ranges
> mm: Ratelimited mirrored memory related warning messages
> mm: Limit warning message in vmemmap_verify() to once
> arm64: mm: Only remove nomap flag for initrd
> memblock: Disable mirror feature if kernelcore is not specified
>
> arch/arm64/mm/init.c | 2 +-
> arch/x86/include/asm/efi.h | 4 ----
> arch/x86/platform/efi/efi.c | 23 -----------------------
> drivers/firmware/efi/efi-init.c | 1 +
> drivers/firmware/efi/efi.c | 23 +++++++++++++++++++++++
> include/linux/efi.h | 3 +++
> mm/internal.h | 2 ++
> mm/memblock.c | 7 +++++--
> mm/page_alloc.c | 2 +-
> mm/sparse-vmemmap.c | 2 +-
> 10 files changed, 37 insertions(+), 32 deletions(-)
>

2022-06-15 08:14:31

by Mike Rapoport

[permalink] [raw]
Subject: Re: [PATCH v5 0/5] introduce mirrored memory support for arm64

On Tue, Jun 14, 2022 at 05:21:51PM +0800, Wupeng Ma wrote:
> From: Ma Wupeng <[email protected]>
>
> Patch #1 introduce mirrored memory support form arm64.
> Patch #2-#4 fix some bugs for arm64 if memory reliable is enabled.
> Patch #5 disable mirror feature if kernelcore is not specified.
>
> Thanks to Ard Biesheuvel's hard work [1], now kernel will perfer mirrored
> memory if kaslr is enabled.
>
> [1] https://lore.kernel.org/linux-arm-kernel/CAMj1kXEPVEzMgOM4+Yj6PxHA-jFuDOAUdDJSiSxy_XaP4P7LSw@mail.gmail.com/T/
>
>
> Ma Wupeng (5):
> efi: arm64: Introduce ability to find mirrored memory ranges
> mm: Ratelimited mirrored memory related warning messages
> mm: Limit warning message in vmemmap_verify() to once
> arm64: mm: Only remove nomap flag for initrd
> memblock: Disable mirror feature if kernelcore is not specified
>
> arch/arm64/mm/init.c | 2 +-
> arch/x86/include/asm/efi.h | 4 ----
> arch/x86/platform/efi/efi.c | 23 -----------------------
> drivers/firmware/efi/efi-init.c | 1 +
> drivers/firmware/efi/efi.c | 23 +++++++++++++++++++++++
> include/linux/efi.h | 3 +++
> mm/internal.h | 2 ++
> mm/memblock.c | 7 +++++--
> mm/page_alloc.c | 2 +-
> mm/sparse-vmemmap.c | 2 +-
> 10 files changed, 37 insertions(+), 32 deletions(-)

For the series: Acked-by: Mike Rapoport <[email protected]>

> --
> 2.25.1
>

--
Sincerely yours,
Mike.

2022-06-15 10:14:51

by Catalin Marinas

[permalink] [raw]
Subject: Re: [PATCH v5 1/5] efi: arm64: Introduce ability to find mirrored memory ranges

On Tue, Jun 14, 2022 at 05:21:52PM +0800, Wupeng Ma wrote:
> From: Ma Wupeng <[email protected]>
>
> Commit b05b9f5f9dcf ("x86, mirror: x86 enabling - find mirrored memory
> ranges") introduce the efi_find_mirror() function on x86. In order to reuse
> the API we make it public.
>
> Arm64 can support mirrored memory too, so function efi_find_mirror() is added to
> efi_init() to this support for arm64.
>
> Since efi_init() is shared by ARM, arm64 and riscv, this patch will bring
> mirror memory support for these architectures, but this support is only tested
> in arm64.
>
> Signed-off-by: Ma Wupeng <[email protected]>
> ---
> arch/x86/include/asm/efi.h | 4 ----
> arch/x86/platform/efi/efi.c | 23 -----------------------
> drivers/firmware/efi/efi-init.c | 1 +
> drivers/firmware/efi/efi.c | 23 +++++++++++++++++++++++
> include/linux/efi.h | 3 +++

The subject prefix says "efi: arm64: " but it looks like x86 diffstat
here. You may want to get an ack from the x86 maintainers.

--
Catalin

2022-06-15 10:20:28

by Ard Biesheuvel

[permalink] [raw]
Subject: Re: [PATCH v5 0/5] introduce mirrored memory support for arm64

On Wed, 15 Jun 2022 at 09:54, Mike Rapoport <[email protected]> wrote:
>
> On Tue, Jun 14, 2022 at 05:21:51PM +0800, Wupeng Ma wrote:
> > From: Ma Wupeng <[email protected]>
> >
> > Patch #1 introduce mirrored memory support form arm64.
> > Patch #2-#4 fix some bugs for arm64 if memory reliable is enabled.
> > Patch #5 disable mirror feature if kernelcore is not specified.
> >
> > Thanks to Ard Biesheuvel's hard work [1], now kernel will perfer mirrored
> > memory if kaslr is enabled.
> >
> > [1] https://lore.kernel.org/linux-arm-kernel/CAMj1kXEPVEzMgOM4+Yj6PxHA-jFuDOAUdDJSiSxy_XaP4P7LSw@mail.gmail.com/T/
> >
> >
> > Ma Wupeng (5):
> > efi: arm64: Introduce ability to find mirrored memory ranges
> > mm: Ratelimited mirrored memory related warning messages
> > mm: Limit warning message in vmemmap_verify() to once
> > arm64: mm: Only remove nomap flag for initrd
> > memblock: Disable mirror feature if kernelcore is not specified
> >
> > arch/arm64/mm/init.c | 2 +-
> > arch/x86/include/asm/efi.h | 4 ----
> > arch/x86/platform/efi/efi.c | 23 -----------------------
> > drivers/firmware/efi/efi-init.c | 1 +
> > drivers/firmware/efi/efi.c | 23 +++++++++++++++++++++++
> > include/linux/efi.h | 3 +++
> > mm/internal.h | 2 ++
> > mm/memblock.c | 7 +++++--
> > mm/page_alloc.c | 2 +-
> > mm/sparse-vmemmap.c | 2 +-
> > 10 files changed, 37 insertions(+), 32 deletions(-)
>
> For the series: Acked-by: Mike Rapoport <[email protected]>
>


Thanks all, I've queued these up now.

2022-06-15 10:30:16

by Ard Biesheuvel

[permalink] [raw]
Subject: Re: [PATCH v5 1/5] efi: arm64: Introduce ability to find mirrored memory ranges

On Wed, 15 Jun 2022 at 12:02, Catalin Marinas <[email protected]> wrote:
>
> On Tue, Jun 14, 2022 at 05:21:52PM +0800, Wupeng Ma wrote:
> > From: Ma Wupeng <[email protected]>
> >
> > Commit b05b9f5f9dcf ("x86, mirror: x86 enabling - find mirrored memory
> > ranges") introduce the efi_find_mirror() function on x86. In order to reuse
> > the API we make it public.
> >
> > Arm64 can support mirrored memory too, so function efi_find_mirror() is added to
> > efi_init() to this support for arm64.
> >
> > Since efi_init() is shared by ARM, arm64 and riscv, this patch will bring
> > mirror memory support for these architectures, but this support is only tested
> > in arm64.
> >
> > Signed-off-by: Ma Wupeng <[email protected]>
> > ---
> > arch/x86/include/asm/efi.h | 4 ----
> > arch/x86/platform/efi/efi.c | 23 -----------------------
> > drivers/firmware/efi/efi-init.c | 1 +
> > drivers/firmware/efi/efi.c | 23 +++++++++++++++++++++++
> > include/linux/efi.h | 3 +++
>
> The subject prefix says "efi: arm64: " but it looks like x86 diffstat
> here. You may want to get an ack from the x86 maintainers.
>

This just moves efi code around, and this is going through the EFI
tree, so that should be fine. I'll fix the subject in any case,
though.