[RFC PATCH 00/18] mm: arm64: Add kernel replication feature

Nikita Panov posted 18 patches 1 month ago
.../admin-guide/kernel-parameters.txt         |   7 +
arch/arm64/include/asm/efi.h                  |  18 +-
arch/arm64/include/asm/mmu_context.h          |   4 +
arch/arm64/include/asm/numa_replication.h     |  54 ++
arch/arm64/include/asm/pgtable.h              |   4 +
arch/arm64/kernel/alternative.c               |  33 +-
arch/arm64/kernel/hibernate.c                 |   5 +
arch/arm64/kernel/module.c                    |  11 +
arch/arm64/kernel/patching.c                  |  96 ++
arch/arm64/kernel/sleep.S                     |   8 +
arch/arm64/kernel/smp.c                       |   8 +
arch/arm64/kernel/vmlinux.lds.S               |  22 +
arch/arm64/mm/init.c                          |  49 ++
arch/arm64/mm/kasan_init.c                    |   2 +
arch/arm64/mm/mmu.c                           |  42 +-
arch/arm64/mm/pageattr.c                      |  72 +-
arch/arm64/mm/ptdump.c                        |  24 +-
arch/arm64/net/bpf_jit_comp.c                 |   4 +-
include/asm-generic/pgalloc.h                 |  90 ++
include/asm-generic/pgtable-nop4d.h           |   5 +
include/asm-generic/pgtable-nopmd.h           |   5 +
include/asm-generic/pgtable-nopud.h           |   5 +
include/asm-generic/set_memory.h              |  14 +
include/linux/mm.h                            |  92 +-
include/linux/mm_types.h                      |   3 +
include/linux/moduleloader.h                  |   4 +
include/linux/numa_kernel_replication.h       | 112 +++
include/linux/set_memory.h                    |  21 +
include/linux/vmalloc.h                       |  18 +
init/main.c                                   |  17 +
kernel/bpf/core.c                             |   4 +-
kernel/bpf/trampoline.c                       |   2 +-
kernel/module/main.c                          |  20 +
kernel/module/strict_rwx.c                    |  12 +-
mm/Kconfig                                    |  10 +
mm/Makefile                                   |   2 +
mm/execmem.c                                  |  39 +-
mm/memory.c                                   | 129 +++
mm/mm_init.c                                  |   3 +
mm/numa_kernel_replication.c                  | 821 ++++++++++++++++++
mm/vmalloc.c                                  | 454 ++++++++--
41 files changed, 2246 insertions(+), 99 deletions(-)
create mode 100644 arch/arm64/include/asm/numa_replication.h
create mode 100644 include/linux/numa_kernel_replication.h
create mode 100644 mm/numa_kernel_replication.c
[RFC PATCH 00/18] mm: arm64: Add kernel replication feature
Posted by Nikita Panov 1 month ago
Current status:

There were several prior submissions with some sort of replication
for NUMA systems, including one from our side for the x86_64 platform.
In the last couple years, several research articles related to solving
locality issues on NUMA machines through replication emerged as well.

[1]  - arm64 kernel text replication
[2]  - x86 NUMA-aware kernel replication
[3]  - x86 kernel text replication
[4]  - NUMA replication of user data
[5]  - Mitosis: Transparently Self-Replicating Page-Tables for Large-Memory Machines
[6]  - WASP: Workload-Aware Self-Replicating Page-Tables for NUMA Servers
[7]  - PaCaR: Improved Buffered I/O Locality on NUMA Systems with Page Cache Replication
[8]  - Memory page replication for Linux on X86 processors
[12] - Optimize this_cpu_*() ops for non-x86 (ARM64 for this series)

As of today, none of it was merged into mainline.

Patch set description:

This patchset implements initial support of the kernel
text and ro-data replication for arm64 platform.
Linux-next was used as a baseline.
(903c1cf6dff9 Add linux-next specific files for 20260821).
This patch set heavily relies on our previous submission [2],
their generic part is the same, these solutions might be merged into a single one.
However, after thorough re-evaluation, we were not able to observe
performance improvement for the x86 platform, so we have decided to stop this
direction and switch on arm64.

Current implementation supports the next functionality:

1. Replicated kernel text and rodata per NUMA node
2. Vmalloc is able to work with replicated areas, so
   kernel modules text and rodata are also replicated during
   modules loading stage.
3. KPROBES, KGDB and all functionality that depends on
   kernel text patching work without any limitation.
4. KPTI, KASLR, and KASAN are supported.
5. Only part of a translation table related to
   replicated text and rodata is replicated
   (up to 2 pgd entries if kaslr is enabled)
6. 4K + 48bit and 64K + 48/52bit are supported and tested.
7. New cmdline option: "kernel_replication=on|off",
   to configure on the boot stage
8. For verification check dmesg output or /sys/kernel/debug/numa_replication/

In general, setting up a new pgd entry in kernel translation table
not often scenario, most of them are covered by current patch set.

TT overview:
                   NODE 0                   NODE 1
                   KERNEL                   KERNEL
           ---------------------    ---------------------
     PGD   |@| | |@|   | | | |*|    |@| | |@|   | | | |*|
           ---------------------    ---------------------
                              |                        |
            -------------------      -------------------
            |                        |
           ---------------------    ---------------------
     PUD   | | | | |   |@| |*|*|    | | | | |   |@| |*|*|
           ---------------------    ---------------------
                              |                        |
            -------------------      -------------------
            |                        |
           ---------------------    ---------------------
     PMD   |READ-ONLY|MUTABLE  |    |READ-ONLY|MUTABLE  |
           ---------------------    ---------------------
                  |       |                  |     |
                  |       --------------------------
                  |               |          |
                --------       -------      --------
   PHYS         |      |       |     |      |      |
    MEM         --------       -------      --------
                <------>                    <------>
                 NODE 0        Shared        NODE 1
                               between
                               nodes
* - entries unique in each table
@ - same entries accross replicated tables

Since for kernel space and user space different tables are used,
user space tables are not replicated at all, so synchronization
is not required.

Known problems:

1. Other combinations of base page size and va size (especially with 16K pages)
   should be adapted and verified.
2. Replicated translation tables for the vmalloc region are not local right now.
   Allocation performed with default memory policy, so translation tables
   for kernel modules will not be local. However,
   replicated text and rodata of the modules are local.
   In general, vmalloc patch should be cleaned up.
3. Any modifications of kernel PGD level. These modifications
   should be synchronized across all replicated tables.
   Right now, for example, memory hotplug/hotunplug
   lacks this support, vmemmap and kasan regions for
   added memory might not be observed correctly. This could be fixed
   by patching all places in the kernel where swapper_pg_dir
   is modified, or by "lazy" propagation on kernel faults in the pgd-level.
   Propagation approach will not help in the case of pgd_clear()
   on swapper_pg_dir though.

Overall, this patch set in an early PoC stage and require some improvements.

Overhead:

Memory overhead for the kernel itself is about 30MB per NUMA node
  on our deployment. For kernel modules - depends on their sizes, but text
  and ro-data are not that big.
CPU overhead - replication performed on the boot stage. After boot
  only "rare" operations are slowed down -
  module loading, text patching, kernel table pgd-level modifications.

Performance evaluation:

Our local testing was performed on
Kunpeng 920, 128 CPU, 4 nodes, 100Gb for each node.

Microbenchmark:
Kernel module with a huge text section (~50MB) filled with CPU-bound
instructions. For each NUMA node thread is spawned, each thread in a loop
executes isntructions. Total execution time of each thread is measured.
The insmod call bound to node 0 through numactl (less time is better).

node                 0        1        2        3
Before time, s     5.567    7.598   13.294   18.905
After  time, s     5.469    6.960    6.777    5.531

Diff               ~0%      -8.5%    -49%     -70%
In this benchmark, interconnect was not used by any other actors,
so microbenchmark numbers might be significantly improved.

Customer's evaluation:
We were provided with the following feedback on this patch set
directly from our customers. Unfortunately, we do not have details
regarding how these measurements were done other than it was
a production setup.
Evaulation was performed on Kunpeng 920 and 920B platforms:
CEPH distributed storage +5%
StarRocksDB              +5%

Couple more words about patch set and technology:

This patchset was merged into the innovative branch of
the openEuler distributive 1.5 year ago (openEuler-25.03)
and was actively tested in production environment [9], [10].
In addition, besides the kernel part, we have published
user space replication (for translation tables and rodata) as well,
but it is very complex and experimental
even compared to this patch set [11]. With replication in user
space, we were able to achieve the following numbers in
performance improvement:
MySQL + sysbench      1-6%
Spark TPC-H           4-20%
Phoronix test-suite   0-25%

Discussion:

The main question we'd like to discuss is the following:
Should the kernel replication feature be merged into the Linux
somewhere in the future? In any form, not specifically this patch set,
but the core concept itself.

If the answer is yes, please share your thoughts on this patch set. What else
should be fixed (or reimplemented and redsigned completly) in this patch
for mainline in your opinion? We'd be glad to do it, and in that case
I'll send an updated version in the near future.

[1]  https://lwn.net/ml/linux-doc/ZHYCUVa8fzmB4XZV@shell.armlinux.org.uk/
[2]  https://lwn.net/ml/linux-mm/20231228131056.602411-1-artem.kuzin@huawei.com/
[3]  https://lwn.net/Articles/36602/
[4]  https://lwn.net/Articles/45082/
[5]  https://github.com/mitosis-project/mitosis-asplos20-artifact
[6]  https://dl.acm.org/doi/10.1145/3620665.3640369
[7]  https://dl.acm.org/doi/10.1145/3767295.3769359
[8]  https://github.com/Carrefour/linux-replication
[9]  https://mailweb.openeuler.org/archives/list/kernel@openeuler.org/message/C7M5E2K2UD7FV7XYPWPZREJBCOCBIVRN/
[10] https://www.openeuler.org/whitepaper/en/openEuler%2025.03%20Technical%20White%20Paper.pdf
[11] https://mailweb.openeuler.org/archives/list/kernel@openeuler.org/message/73MAUDM6WCGSSOKPZGPNZAYRNQGUR6DE/
[12] https://lore.kernel.org/linux-mm/20260715180455.515692-1-yang@os.amperecomputing.com/

Nikita Panov (18):
  mm: arm64 add Kconfig option for kernel replication
  arm64: align kernel text and rodata
  mm: allow per-NUMA node local P4D/PUD/PMD/PTE allocation
  arm64: add arch callbacks for kernel replication
  mm: per-NUMA node replication core infrastructure
  mm: add support of memory protection for NUMA replicas
  arm64: add support of memory protection for NUMA replicas
  mm: set memory permissions for BPF handlers replicas
  mm: add replicas allocation support for vmalloc
  arm64: enable per-NUMA node kernel text and rodata replication
  mm: enable per-NUMA node kernel text and rodata replication
  arm64: make power management aware about kernel replication
  arm64: make kernel text patching aware about replicas
  arm64: add correct alignment to kimage in efi code
  arm64: add support of NUMA replication for ptdump
  arm64: add kernel modules text and rodata replication support
  mm: init kernel modules with replication support
  mm: introduce kernel cmdline option "kernel_replication="

 .../admin-guide/kernel-parameters.txt         |   7 +
 arch/arm64/include/asm/efi.h                  |  18 +-
 arch/arm64/include/asm/mmu_context.h          |   4 +
 arch/arm64/include/asm/numa_replication.h     |  54 ++
 arch/arm64/include/asm/pgtable.h              |   4 +
 arch/arm64/kernel/alternative.c               |  33 +-
 arch/arm64/kernel/hibernate.c                 |   5 +
 arch/arm64/kernel/module.c                    |  11 +
 arch/arm64/kernel/patching.c                  |  96 ++
 arch/arm64/kernel/sleep.S                     |   8 +
 arch/arm64/kernel/smp.c                       |   8 +
 arch/arm64/kernel/vmlinux.lds.S               |  22 +
 arch/arm64/mm/init.c                          |  49 ++
 arch/arm64/mm/kasan_init.c                    |   2 +
 arch/arm64/mm/mmu.c                           |  42 +-
 arch/arm64/mm/pageattr.c                      |  72 +-
 arch/arm64/mm/ptdump.c                        |  24 +-
 arch/arm64/net/bpf_jit_comp.c                 |   4 +-
 include/asm-generic/pgalloc.h                 |  90 ++
 include/asm-generic/pgtable-nop4d.h           |   5 +
 include/asm-generic/pgtable-nopmd.h           |   5 +
 include/asm-generic/pgtable-nopud.h           |   5 +
 include/asm-generic/set_memory.h              |  14 +
 include/linux/mm.h                            |  92 +-
 include/linux/mm_types.h                      |   3 +
 include/linux/moduleloader.h                  |   4 +
 include/linux/numa_kernel_replication.h       | 112 +++
 include/linux/set_memory.h                    |  21 +
 include/linux/vmalloc.h                       |  18 +
 init/main.c                                   |  17 +
 kernel/bpf/core.c                             |   4 +-
 kernel/bpf/trampoline.c                       |   2 +-
 kernel/module/main.c                          |  20 +
 kernel/module/strict_rwx.c                    |  12 +-
 mm/Kconfig                                    |  10 +
 mm/Makefile                                   |   2 +
 mm/execmem.c                                  |  39 +-
 mm/memory.c                                   | 129 +++
 mm/mm_init.c                                  |   3 +
 mm/numa_kernel_replication.c                  | 821 ++++++++++++++++++
 mm/vmalloc.c                                  | 454 ++++++++--
 41 files changed, 2246 insertions(+), 99 deletions(-)
 create mode 100644 arch/arm64/include/asm/numa_replication.h
 create mode 100644 include/linux/numa_kernel_replication.h
 create mode 100644 mm/numa_kernel_replication.c

--
2.34.1
Re: [RFC PATCH 00/18] mm: arm64: Add kernel replication feature
Posted by Christoph Lameter (Ampere) 4 weeks, 1 day ago
On Fri, 28 Aug 2026, Nikita Panov wrote:

> There were several prior submissions with some sort of replication
> for NUMA systems, including one from our side for the x86_64 platform.
> In the last couple years, several research articles related to solving
> locality issues on NUMA machines through replication emerged as well.

Thank you for this work. This aligns with our efforts to increase data
locality and the performance of local data access. Yang Shi has a patchset
that introduces similar code to be able to map partial virtual ranges
differently. His code may be more mature and I think these mechanisms can
be used in a straightforward way in future iterations of your patchset.

If we combine our efforts then I think we could be rapidly come to a clean
implementation that can be merged.

This is an obvious signficant performance improvement that can be readily
seen and that is why we have the variety of patchsets being proposed over
the years. As ARM64 matures and is run on machines with larger core counts
the urge to have this increases.


Please see Yang Shi's patches. We can provide resources to push this
functionality forward and have seen significant performance improvements
with earlier approaches like this. There is significant customer demand as
well.

https://lore.kernel.org/all/0344c559-1959-4531-9265-d5a5180eb7cd@arm.com/
Re: [RFC PATCH 00/18] mm: arm64: Add kernel replication feature
Posted by Nikita Panov 4 weeks ago
Hello, thanks a lot for your reply.

On 8/28/2026 8:58 PM, Christoph Lameter (Ampere) wrote:
> On Fri, 28 Aug 2026, Nikita Panov wrote:
>
>> There were several prior submissions with some sort of replication
>> for NUMA systems, including one from our side for the x86_64 platform.
>> In the last couple years, several research articles related to solving
>> locality issues on NUMA machines through replication emerged as well.
>
> Thank you for this work. This aligns with our efforts to increase data
> locality and the performance of local data access. Yang Shi has a patchset
> that introduces similar code to be able to map partial virtual ranges
> differently. His code may be more mature and I think these mechanisms can
> be used in a straightforward way in future iterations of your patchset.
>
> If we combine our efforts then I think we could be rapidly come to a clean
> implementation that can be merged.
>

I will check these patches in detail and leave some comments during the
following week (or to the v3, if it will be published).
At a first glance, code is definitely more mature and can be reused
for the text replication patches.
It would be great if we merged our efforts to produce something clean
and viable.

>
> Please see Yang Shi's patches. We can provide resources to push this
> functionality forward and have seen significant performance improvements
> with earlier approaches like this. There is significant customer demand as
> well.
>
> https://lore.kernel.org/all/0344c559-1959-4531-9265-d5a5180eb7cd@arm.com/
>

For me, it looks like the kernel text and rodata replication could be
adapted on top of the "Optimize this_cpu_*" patch set.
Problems with pgd synchronizations are the same and should be fixed as well.
Since vmalloc code is used for percpu memory allocations, module replication
might be supported, the only thing that should be taken into account -
data locality.
Consider all of this, we can focus on preparing the new patch series, on top of
the Yang Shi's patches and share it. If that path is ok, we will start.

Thanks again for your input.

BR
Nikita Panov
Re: [RFC PATCH 00/18] mm: arm64: Add kernel replication feature
Posted by David Hildenbrand (Arm) 2 weeks, 5 days ago
> 
> For me, it looks like the kernel text and rodata replication could be
> adapted on top of the "Optimize this_cpu_*" patch set.
> Problems with pgd synchronizations are the same and should be fixed as well.
> Since vmalloc code is used for percpu memory allocations, module replication
> might be supported, the only thing that should be taken into account -
> data locality.
> Consider all of this, we can focus on preparing the new patch series, on top of
> the Yang Shi's patches and share it. If that path is ok, we will start.

I would wait for feedback from arm64 maintainers before moving forward with this
plan.

-- 
Cheers,

David
Re: [RFC PATCH 00/18] mm: arm64: Add kernel replication feature
Posted by Matthew Wilcox 1 month ago
On Fri, Aug 28, 2026 at 12:11:40AM +0800, Nikita Panov wrote:
> There were several prior submissions with some sort of replication
> for NUMA systems, including one from our side for the x86_64 platform.
> In the last couple years, several research articles related to solving
> locality issues on NUMA machines through replication emerged as well.

You're lumping a lot of different NUMA replication things together in
your list.  That doesn't give me confidence you know what you're doing.

I *think* what you're doing here is kernel text replication.  Other
architectures (mips, arm) have managed to do this without core MM
changes.  Why can't you?
Re: [RFC PATCH 00/18] mm: arm64: Add kernel replication feature
Posted by Nikita Panov 4 weeks, 1 day ago
Hello, thanks for your comment.

On 8/27/2026 10:11 PM, Matthew Wilcox wrote:
> On Fri, Aug 28, 2026 at 12:11:40AM +0800, Nikita Panov wrote:
>> There were several prior submissions with some sort of replication
>> for NUMA systems, including one from our side for the x86_64 platform.
>> In the last couple years, several research articles related to solving
>> locality issues on NUMA machines through replication emerged as well.
>
> You're lumping a lot of different NUMA replication things together in
> your list.  That doesn't give me confidence you know what you're doing.
>
> I *think* what you're doing here is kernel text replication.  Other
> architectures (mips, arm) have managed to do this without core MM
> changes.  Why can't you?

Yes, this patch set is for kernel text and rodata replication.
For arm such technique was not adapted by the Linux kernel.

Regarding mips, this is achieved through the TLB lockdown feature.
For aarch64 this feature is *implementation-defined*. Moreover, looks like
not a single vendor of modern enterprise aarch64 servers actually implements
it. But even having this feature would not allow us to implement
fully function kernel rodata replication:
1. TLB capacity is very limited, we can't lockdown a significant amount of
entries. In case if small pages are used for kernel text mapping (64k kernels)
this approach is not suitable.
2. Some core modifications are still required - text patching at least should
be aware of memory replicas. But yes, changes are significantly
smaller and easier.
3. Replication in kernel modules most likely will not be possible due to limited
TLB capacity as well.

Implementation could have been done only for 4K page size kernels
(maybe for 16K as well, if we do not mind some memory overconsumption),
only for kernel text and rodata. In addition, locking TLB entries for
the kernel reduces TLB capacity for user space applications.
How badly this will affect performance, I cannot say without actual hardware.

BR
Nikita Panov
Re: [RFC PATCH 00/18] mm: arm64: Add kernel replication feature
Posted by Lorenzo Stoakes (ARM) 1 month ago
Hi,

On Fri, Aug 28, 2026 at 12:11:40AM +0800, Nikita Panov wrote:
> Current status:
>
> There were several prior submissions with some sort of replication
> for NUMA systems, including one from our side for the x86_64 platform.
> In the last couple years, several research articles related to solving
> locality issues on NUMA machines through replication emerged as well.
>
> [1]  - arm64 kernel text replication
> [2]  - x86 NUMA-aware kernel replication
> [3]  - x86 kernel text replication
> [4]  - NUMA replication of user data
> [5]  - Mitosis: Transparently Self-Replicating Page-Tables for Large-Memory Machines
> [6]  - WASP: Workload-Aware Self-Replicating Page-Tables for NUMA Servers
> [7]  - PaCaR: Improved Buffered I/O Locality on NUMA Systems with Page Cache Replication
> [8]  - Memory page replication for Linux on X86 processors

(What happened to 9-11? :P)

> [12] - Optimize this_cpu_*() ops for non-x86 (ARM64 for this series)
>
> As of today, none of it was merged into mainline.

I mean :) maybe take that as a hint? If a number of series trying to do X get
rejected by upstream, that is maybe suggestive of barking up the wrong tree?

> However, after thorough re-evaluation, we were not able to observe
> performance improvement for the x86 platform, so we have decided to stop this
> direction and switch on arm64.

I mean, why? You should provide details here, this is quite hand-wavey. You are
also proposing core mm changes for something that seems specific to unique
hardware as far as I can tell, which is a big ask.

<snip>

> Known problems:
>
> 1. Other combinations of base page size and va size (especially with 16K pages)
>    should be adapted and verified.

Umm, yeah this is basic stuff for upstreamability :)

> 2. Replicated translation tables for the vmalloc region are not local right now.
>    Allocation performed with default memory policy, so translation tables
>    for kernel modules will not be local. However,
>    replicated text and rodata of the modules are local.
>    In general, vmalloc patch should be cleaned up.

Again, this is really more of an alpha pre-RFC I'd say.

> 3. Any modifications of kernel PGD level. These modifications
>    should be synchronized across all replicated tables.
>    Right now, for example, memory hotplug/hotunplug
>    lacks this support, vmemmap and kasan regions for
>    added memory might not be observed correctly. This could be fixed
>    by patching all places in the kernel where swapper_pg_dir
>    is modified, or by "lazy" propagation on kernel faults in the pgd-level.
>    Propagation approach will not help in the case of pgd_clear()
>    on swapper_pg_dir though.

Yeah OK this suggests to me you've got the locking and synchronisation all wrong
and it's worrying :)

In general I really oppose anything that adds additional kernel page tables or
complicates kernel page table handling.

We already have singificant complexity and bugs/races emerging from people doing
odd things with kernel page tables on assumption that it's 'safe'.

You'll need very compelling evidence to justify anything that touches such
sensitive stuff.

The code is also fiddling with PGD assignment in a way that could interact badly
with how these PGDs are synchronised. These things are very subtle, and even if
it's limited to one arch the core mm code is not.

>
> Overall, this patch set in an early PoC stage and require some improvements.
>
> Overhead:
>
> Memory overhead for the kernel itself is about 30MB per NUMA node
>   on our deployment. For kernel modules - depends on their sizes, but text
>   and ro-data are not that big.
> CPU overhead - replication performed on the boot stage. After boot
>   only "rare" operations are slowed down -
>   module loading, text patching, kernel table pgd-level modifications.

Hmm. I wonder if they're as rare as you think though? It all depends also on how
slowed down they are, how that manifests, etc.

>
> Performance evaluation:
>
> Our local testing was performed on
> Kunpeng 920, 128 CPU, 4 nodes, 100Gb for each node.

Thanks for providing details of the hardware used!

>
> Microbenchmark:
> Kernel module with a huge text section (~50MB) filled with CPU-bound
> instructions. For each NUMA node thread is spawned, each thread in a loop
> executes isntructions. Total execution time of each thread is measured.
> The insmod call bound to node 0 through numactl (less time is better).

So wait, you bound it to node 0, then rely on kernel text replication to improve
performance due to a bad hint?

That seems like you could fix the issue by binding correctly? :)

>
> node                 0        1        2        3
> Before time, s     5.567    7.598   13.294   18.905
> After  time, s     5.469    6.960    6.777    5.531
>
> Diff               ~0%      -8.5%    -49%     -70%
> In this benchmark, interconnect was not used by any other actors,
> so microbenchmark numbers might be significantly improved.

This benchmark seems entirely synthetic and it seems odd to me, prima facie, to
implement a feature to correct for incorrect NUMA binding?

Maybe I'm missing something though.

>
> Customer's evaluation:
> We were provided with the following feedback on this patch set
> directly from our customers. Unfortunately, we do not have details
> regarding how these measurements were done other than it was
> a production setup.
> Evaulation was performed on Kunpeng 920 and 920B platforms:
> CEPH distributed storage +5%
> StarRocksDB              +5%

This isn't hugely encouraging.

>
> Couple more words about patch set and technology:
>
> This patchset was merged into the innovative branch of
> the openEuler distributive 1.5 year ago (openEuler-25.03)
> and was actively tested in production environment [9], [10].
> In addition, besides the kernel part, we have published
> user space replication (for translation tables and rodata) as well,
> but it is very complex and experimental
> even compared to this patch set [11]. With replication in user
> space, we were able to achieve the following numbers in
> performance improvement:
> MySQL + sysbench      1-6%
> Spark TPC-H           4-20%
> Phoronix test-suite   0-25%

These seem very vague and wide-ranged, I'm not sure they're really saying much
at all?

>
> Discussion:
>
> The main question we'd like to discuss is the following:
> Should the kernel replication feature be merged into the Linux
> somewhere in the future? In any form, not specifically this patch set,
> but the core concept itself.

I will leave the broader topic to the NUMA experts.

>
> If the answer is yes, please share your thoughts on this patch set. What else
> should be fixed (or reimplemented and redsigned completly) in this patch
> for mainline in your opinion? We'd be glad to do it, and in that case
> I'll send an updated version in the near future.

Glancing thorugh, The patch set seems very far from being upstreamable:

	if (kernel_replication_enabled)
		pr_info("WARNING! WARNING! WARNING! Kernel replication enabled WARNING! WARNING! WARNING!\n");

For instance... this really shouts some alpha effort.

Annnd :) this:

	if (rwsem_is_locked(&mm->mmap_lock))
		locked = true;
	else
		mmap_read_lock(mm);

is just utterly, utterly broken.

rwsem_is_locked() can be raced at any time, you don't own the lock so it can
just be unlocked underneath you.

That you do that suggests to me you've not thought about locks correctly _at
all_ here.

And as I said above, locking issues around page table walking and manipulation
is very subtle and difficult to manage correctly.

Then there's stuff like this:

		/* TODO: remove last condition and do something better
		 * In the case of a folded P4D level, pgd_none and pgd_huge
		 * always return 0, so we might start to replicate empty entries.
		 * We obviously want to avoid this, so the last check is performed here.
		 */
		if (pgd_none(*orig_pgd) || pgd_val(*orig_pgd) == 0)
			goto skip;

This whole block seems confused, and it's nitty but you're using completely
incorrect comment style for the linux kernel which again doesn't fill me with
confidence that you've really thought things through or understand mm code
correctly.

Your replicate_memory() function seems to not synchronise _at all_, but you do
for some reason synchronise on dumping memory, bizarely.

You write a ton of duplicative page table code that doesn't seem to handle huge
pages at all, again doesn't seem to be performing any locking correctly at all,
and yeah the list goes on.

In general the code looks like an alpha experimental thing and a million miles
away from anything even vaguely upstreamable.

And in general for this kind of thing - the devil is in the detail.

So if you want to assert that something is viable, you need code that at
least looks _vaguely_ upstreamable and demonstates understanding of the
issues at play here, and you are not doing so.

In conclusion:

- 12 (or is it 9? :) attempts have been made at this kind of thing and all
  were rejected - this isn't an encouraging sign that the approach is
  viable.

- You've already found it has limited use, and your benchmark numbers seem
  either entirely synthetic or bordeline not statistically significant.

- The code is, as discussed, not even vaguely close to being upstreamable.

So overall it seems to me that perhaps better NUMA policy decisions could
solve your problems.

But yeah, what's presented in this series doesn't seem like a worthwhile
road to travel down to me.

--
Cheers, Lorenzo
Re: [RFC PATCH 00/18] mm: arm64: Add kernel replication feature
Posted by Nikita Panov 4 weeks, 1 day ago
Hello, thanks a lot for your comments.

On 8/27/2026 8:25 PM, Lorenzo Stoakes (ARM) wrote:
> Hi,
>
> On Fri, Aug 28, 2026 at 12:11:40AM +0800, Nikita Panov wrote:
>>
>> As of today, none of it was merged into mainline.
>
> I mean :) maybe take that as a hint? If a number of series trying to do X get
> rejected by upstream, that is maybe suggestive of barking up the wrong tree?
>

Patch sets related to NUMA text replication were not explicitly rejected before
(I might be missing something here). The main goal of this resubmissions - gather
feedback, whether *something* related to replicated kernel text, rodata
and translation tables should be even added to core mm. And should be more time
invested into this concept, or better leave it.

>> However, after thorough re-evaluation, we were not able to observe
>> performance improvement for the x86 platform, so we have decided to stop this
>> direction and switch on arm64.
>
> I mean, why? You should provide details here, this is quite hand-wavey.

For testing on x86 architecture, we had only an old machine,
with 2 NUMA nodes, Intel(R) Xeon(R) CPU E5-2690, 192G per node,
24 physical cores total. Interconnect on this machine is better,
than on Arm servers that are available to us, in both latency and bandwidth.
In addition, the x86 patch set introduces overhead to the user space,
since the pgd table is shared between user and kernel space, any
modification of user pgd entry should be immediately propagated
(handle_mm_fault() or free_pgd_range()).
That is the main reasoning why we focused on arm64.

> You are
> also proposing core mm changes for something that seems specific to unique
> hardware as far as I can tell, which is a big ask.

This technique is applicable for all NUMA platforms on aarch64 architecture.

>> 3. Any modifications of kernel PGD level. These modifications
>>     should be synchronized across all replicated tables.
>>     Right now, for example, memory hotplug/hotunplug
>>     lacks this support, vmemmap and kasan regions for
>>     added memory might not be observed correctly. This could be fixed
>>     by patching all places in the kernel where swapper_pg_dir
>>     is modified, or by "lazy" propagation on kernel faults in the pgd-level.
>>     Propagation approach will not help in the case of pgd_clear()
>>     on swapper_pg_dir though.
>
> Yeah OK this suggests to me you've got the locking and synchronisation all wrong
> and it's worrying :)
>
> In general I really oppose anything that adds additional kernel page tables or
> complicates kernel page table handling.
>
> We already have singificant complexity and bugs/races emerging from people doing
> odd things with kernel page tables on assumption that it's 'safe'.
>
> You'll need very compelling evidence to justify anything that touches such
> sensitive stuff.
>
> The code is also fiddling with PGD assignment in a way that could interact badly
> with how these PGDs are synchronised. These things are very subtle, and even if
> it's limited to one arch the core mm code is not.
>

Agree, interactions with PGD should be fixed.

>>
>> Overall, this patch set in an early PoC stage and require some improvements.
>>
>> Overhead:
>>
>> Memory overhead for the kernel itself is about 30MB per NUMA node
>>    on our deployment. For kernel modules - depends on their sizes, but text
>>    and ro-data are not that big.
>> CPU overhead - replication performed on the boot stage. After boot
>>    only "rare" operations are slowed down -
>>    module loading, text patching, kernel table pgd-level modifications.
>
> Hmm. I wonder if they're as rare as you think though? It all depends also on how
> slowed down they are, how that manifests, etc.
>

The rarity of these operations heavily depends on the workload. If someone
is loading/unloading some kernel module or actively tracing something
through kprobes (inserts new and removes old), or enables/disables
ftrace events, these operations are quite often. I am not sure that this is
a valid scenario for an enterprise server. Tracing itself might be running,
but I am not sure about constant reconfiguration.
Exact overhead should be measured, I agree.

>>
>> Microbenchmark:
>> Kernel module with a huge text section (~50MB) filled with CPU-bound
>> instructions. For each NUMA node thread is spawned, each thread in a loop
>> executes isntructions. Total execution time of each thread is measured.
>> The insmod call bound to node 0 through numactl (less time is better).
>
> So wait, you bound it to node 0, then rely on kernel text replication to improve
> performance due to a bad hint?
>
> That seems like you could fix the issue by binding correctly? :)
>
>>
>> node                 0        1        2        3
>> Before time, s     5.567    7.598   13.294   18.905
>> After  time, s     5.469    6.960    6.777    5.531
>>
>> Diff               ~0%      -8.5%    -49%     -70%
>> In this benchmark, interconnect was not used by any other actors,
>> so microbenchmark numbers might be significantly improved.
>
> This benchmark seems entirely synthetic and it seems odd to me, prima facie, to
> implement a feature to correct for incorrect NUMA binding?
>
> Maybe I'm missing something though.
>

You are right, this microbenchmark is absolutely synthetic and was implemented
to verify that replication is working and to test its *maximum*
potential for the kernel text.
Kernel image with its text and rodata loaded
entirely on a single NUMA node, its memory physically continuous,
there is no way to control this.
For kernel modules, mempolicy could be used, but still, text and rodata
will be either bound to a specific NUMA node, or interleaved between them.

>>
>> Customer's evaluation:
>> We were provided with the following feedback on this patch set
>> directly from our customers. Unfortunately, we do not have details
>> regarding how these measurements were done other than it was
>> a production setup.
>> Evaulation was performed on Kunpeng 920 and 920B platforms:
>> CEPH distributed storage +5%
>> StarRocksDB              +5%
>
> This isn't hugely encouraging.
>

I agree, numbers are not great, but it does not *affect* execution of
applications. MM for user space was not modified at all, I think, that
database application will not set kprobes or load kernel modules (at least
perform this other than on its startup). Any introduced overhead should not
affect normal enterprise applications. Memory overhead is also insignificant,
for servers with hundreds of GB.

>
> Annnd :) this:
>
> 	if (rwsem_is_locked(&mm->mmap_lock))
> 		locked = true;
> 	else
> 		mmap_read_lock(mm);
>
> is just utterly, utterly broken.
>
> rwsem_is_locked() can be raced at any time, you don't own the lock so it can
> just be unlocked underneath you.
>

Completely agree, this should be fixed. In general, tables dump mechanism should be
removed, it was added for debug and verification

> Then there's stuff like this:
>
> 		/* TODO: remove last condition and do something better
> 		 * In the case of a folded P4D level, pgd_none and pgd_huge
> 		 * always return 0, so we might start to replicate empty entries.
> 		 * We obviously want to avoid this, so the last check is performed here.
> 		 */
> 		if (pgd_none(*orig_pgd) || pgd_val(*orig_pgd) == 0)
> 			goto skip;
>
> This whole block seems confused, and it's nitty but you're using completely
> incorrect comment style for the linux kernel which again doesn't fill me with
> confidence that you've really thought things through or understand mm code
> correctly.
>
> Your replicate_memory() function seems to not synchronise _at all_, but you do
> for some reason synchronise on dumping memory, bizarely.

Comment style should be fixed.
For the kernel text, this function is called
prior to secondary CPU startup in start_kernel().
For the kernel rodata, this function is called in kernel_init(),
right after mark_readonly().
From my understanding, in both these cases additional synchronization
is not required.
Please point if I am missing something.

>
> You write a ton of duplicative page table code that doesn't seem to handle huge
> pages at all, again doesn't seem to be performing any locking correctly at all,
> and yeah the list goes on.
>

Code that replicates translation tables supports huge pages for the PMD level.
PUD-level hugepages are not supported yet, but for the kernel text and rodata
PUD hugepages are not used for the mapping (at least on Aarch64 and x86).
4K page size - kernel is mapped using PMD hugepages, 2MB each.
64K page size - normal pages with CONT_PTE_BIT.
This code is also executed prior to the secondary CPU boot.
I agree that implementation is very far from ideal, and there are a lot ways
to improve it, for example, the table's replication mechanism
should be implemented through walk_kernel_page_table_range().

> In general the code looks like an alpha experimental thing and a million miles
> away from anything even vaguely upstreamable.

Agree.

> So overall it seems to me that perhaps better NUMA policy decisions could
> solve your problems.
>

As I mentioned, policies might help only for the kernel modules, but not for
kernel text and rodata itself.
Perhaps some mechinsm similiar to NUMA balancer can be implemented
for the kernel text and rodata mappings, but I think it will be even more
complex and intrusive. Plus, in that case, memory will not be physically
continuous anymore which will definitely affect TLB performance,
in case of huge_pmd split.

> But yeah, what's presented in this series doesn't seem like a worthwhile
> road to travel down to me.
>
> --
> Cheers, Lorenzo

Ok, thanks for clarifying your position.


Thanks again for taking time to review.

BR
Nikita Panov
Re: [RFC PATCH 00/18] mm: arm64: Add kernel replication feature
Posted by David Hildenbrand (Arm) 1 month ago
[...]

About to go on PTO, some random points :)

> 
>> [12] - Optimize this_cpu_*() ops for non-x86 (ARM64 for this series)
>>
>> As of today, none of it was merged into mainline.
> 
> I mean :) maybe take that as a hint? If a number of series trying to do X get
> rejected by upstream, that is maybe suggestive of barking up the wrong tree?

I'd have expected an explanation at that point why previous approaches were not
merged and how this patch set is sufficiently different that it is worth
maintainer's time.

> 
>> However, after thorough re-evaluation, we were not able to observe
>> performance improvement for the x86 platform, so we have decided to stop this
>> direction and switch on arm64.
> 
> I mean, why? You should provide details here, this is quite hand-wavey. You are
> also proposing core mm changes for something that seems specific to unique
> hardware as far as I can tell, which is a big ask.

What I consider interesting is "after thorough re-evaluation, we were not able
to observe performance improvement for the x86 platform".

How confident are we that a thorough re-evaluation on arm64 will not similarly
have the same outcome? IOW, what was the problematic part when doing the x86
evaluation, and how was that avoided when evaluating the arm64 implementation?

-- 
Cheers,

David
Re: [RFC PATCH 00/18] mm: arm64: Add kernel replication feature
Posted by Artem Kuzin 4 weeks, 1 day ago
Hi!

On 8/27/2026 10:04 PM, David Hildenbrand (Arm) wrote:
> [...]
> 
> About to go on PTO, some random points :)
> 
>>
>>> [12] - Optimize this_cpu_*() ops for non-x86 (ARM64 for this series)
>>>
>>> As of today, none of it was merged into mainline.
>>
>> I mean :) maybe take that as a hint? If a number of series trying to do X get
>> rejected by upstream, that is maybe suggestive of barking up the wrong tree?
> 
> I'd have expected an explanation at that point why previous approaches were not
> merged and how this patch set is sufficiently different that it is worth
> maintainer's time.
> 
>>
>>> However, after thorough re-evaluation, we were not able to observe
>>> performance improvement for the x86 platform, so we have decided to stop this
>>> direction and switch on arm64.
>>
>> I mean, why? You should provide details here, this is quite hand-wavey. You are
>> also proposing core mm changes for something that seems specific to unique
>> hardware as far as I can tell, which is a big ask.
> 
> What I consider interesting is "after thorough re-evaluation, we were not able
> to observe performance improvement for the x86 platform".
> 
> How confident are we that a thorough re-evaluation on arm64 will not similarly
> have the same outcome? IOW, what was the problematic part when doing the x86
> evaluation, and how was that avoided when evaluating the arm64 implementation?
>
In the x86 kernel replication patchset, performance evaluation was done on a
relatively old platform. Garg Shivank <shivankg-AT-amd.com> evaluated it on
AMD EPYC 7713 64-Core processor (dual socket, 2 NUMA nodes, 64 CPUs on each node),
and the results were completely different - no performance benefits. At that time,
I was unable to reproduce and clarify the issue because I didn't have such machine.

Also, as Nikita mentioned, kernel replication on x86 machines introduces additional
overhead related to PGD management and user space updates propagation.

As for ARM, I remember that the guys from Phytium published relatively good
performance evaluation results. [1]

Yes, both patchsets (x86 and ARM) are far from ready for upstream state,
and there has been very little feedback on them. It was not completely clear if it
is worth continuing with the kernel replication idea.

[1] https://lwn.net/ml/linux-doc/ZbjOZ1YOQUBxftrR@shell.armlinux.org.uk/

Cheers, Artem
Re: [RFC PATCH 00/18] mm: arm64: Add kernel replication feature
Posted by Yang Shi 4 weeks, 1 day ago

On 8/27/26 9:11 AM, Nikita Panov wrote:
> Current status:
>
> There were several prior submissions with some sort of replication
> for NUMA systems, including one from our side for the x86_64 platform.
> In the last couple years, several research articles related to solving
> locality issues on NUMA machines through replication emerged as well.

Hi Nikita,

Thank you for the effort. As Christopher said we are working on the same 
feature. Please see the below inline comments.

>
> [1]  - arm64 kernel text replication
> [2]  - x86 NUMA-aware kernel replication
> [3]  - x86 kernel text replication
> [4]  - NUMA replication of user data
> [5]  - Mitosis: Transparently Self-Replicating Page-Tables for Large-Memory Machines
> [6]  - WASP: Workload-Aware Self-Replicating Page-Tables for NUMA Servers
> [7]  - PaCaR: Improved Buffered I/O Locality on NUMA Systems with Page Cache Replication
> [8]  - Memory page replication for Linux on X86 processors
> [12] - Optimize this_cpu_*() ops for non-x86 (ARM64 for this series)
>
> As of today, none of it was merged into mainline.
>
> Patch set description:
>
> This patchset implements initial support of the kernel
> text and ro-data replication for arm64 platform.
> Linux-next was used as a baseline.
> (903c1cf6dff9 Add linux-next specific files for 20260821).
> This patch set heavily relies on our previous submission [2],
> their generic part is the same, these solutions might be merged into a single one.
> However, after thorough re-evaluation, we were not able to observe
> performance improvement for the x86 platform, so we have decided to stop this
> direction and switch on arm64.
>
> Current implementation supports the next functionality:
>
> 1. Replicated kernel text and rodata per NUMA node
> 2. Vmalloc is able to work with replicated areas, so
>     kernel modules text and rodata are also replicated during
>     modules loading stage.
> 3. KPROBES, KGDB and all functionality that depends on
>     kernel text patching work without any limitation.
> 4. KPTI, KASLR, and KASAN are supported.
> 5. Only part of a translation table related to
>     replicated text and rodata is replicated
>     (up to 2 pgd entries if kaslr is enabled)
> 6. 4K + 48bit and 64K + 48/52bit are supported and tested.

I think 16K + 47 VA bits should work too. I guess it is because there 
are just 2 top level entries with 16K + 48 VA bits. That requires some 
extra effort to sync up kernel page tables.

> 7. New cmdline option: "kernel_replication=on|off",
>     to configure on the boot stage
> 8. For verification check dmesg output or /sys/kernel/debug/numa_replication/
>
> In general, setting up a new pgd entry in kernel translation table
> not often scenario, most of them are covered by current patch set.
>
> TT overview:
>                     NODE 0                   NODE 1
>                     KERNEL                   KERNEL
>             ---------------------    ---------------------
>       PGD   |@| | |@|   | | | |*|    |@| | |@|   | | | |*|
>             ---------------------    ---------------------
>                                |                        |
>              -------------------      -------------------
>              |                        |
>             ---------------------    ---------------------
>       PUD   | | | | |   |@| |*|*|    | | | | |   |@| |*|*|
>             ---------------------    ---------------------
>                                |                        |
>              -------------------      -------------------
>              |                        |
>             ---------------------    ---------------------
>       PMD   |READ-ONLY|MUTABLE  |    |READ-ONLY|MUTABLE  |
>             ---------------------    ---------------------
>                    |       |                  |     |
>                    |       --------------------------
>                    |               |          |
>                  --------       -------      --------
>     PHYS         |      |       |     |      |      |
>      MEM         --------       -------      --------
>                  <------>                    <------>
>                   NODE 0        Shared        NODE 1
>                                 between
>                                 nodes
> * - entries unique in each table
> @ - same entries accross replicated tables
>
> Since for kernel space and user space different tables are used,
> user space tables are not replicated at all, so synchronization
> is not required.
>
> Known problems:
>
> 1. Other combinations of base page size and va size (especially with 16K pages)
>     should be adapted and verified.
> 2. Replicated translation tables for the vmalloc region are not local right now.
>     Allocation performed with default memory policy, so translation tables
>     for kernel modules will not be local. However,
>     replicated text and rodata of the modules are local.
>     In general, vmalloc patch should be cleaned up.
> 3. Any modifications of kernel PGD level. These modifications
>     should be synchronized across all replicated tables.
>     Right now, for example, memory hotplug/hotunplug
>     lacks this support, vmemmap and kasan regions for
>     added memory might not be observed correctly. This could be fixed
>     by patching all places in the kernel where swapper_pg_dir
>     is modified, or by "lazy" propagation on kernel faults in the pgd-level.
>     Propagation approach will not help in the case of pgd_clear()
>     on swapper_pg_dir though.

My percpu patchset (I saw you mentioned it above) already had these 
problems solved. I have not looked into too much detail yet, but it 
seems like you have replicate kernel page tables per node. My patchset 
added percpu kernel page tables. It should be able to support kernel 
text replication as well without too much extra effort. And it can 
support multiple usecases, for example, this_cpu optimization 
implemented in my series, kernel text replication and some potential 
security features. Multiple usecases should be able to make it more 
attractive and convincing. So as Christopher suggested it may be better 
to combine the effort.

>
> Overall, this patch set in an early PoC stage and require some improvements.
>
> Overhead:
>
> Memory overhead for the kernel itself is about 30MB per NUMA node
>    on our deployment. For kernel modules - depends on their sizes, but text
>    and ro-data are not that big.
> CPU overhead - replication performed on the boot stage. After boot
>    only "rare" operations are slowed down -
>    module loading, text patching, kernel table pgd-level modifications.
>
> Performance evaluation:
>
> Our local testing was performed on
> Kunpeng 920, 128 CPU, 4 nodes, 100Gb for each node.
>
> Microbenchmark:
> Kernel module with a huge text section (~50MB) filled with CPU-bound
> instructions. For each NUMA node thread is spawned, each thread in a loop
> executes isntructions. Total execution time of each thread is measured.
> The insmod call bound to node 0 through numactl (less time is better).
>
> node                 0        1        2        3
> Before time, s     5.567    7.598   13.294   18.905
> After  time, s     5.469    6.960    6.777    5.531
>
> Diff               ~0%      -8.5%    -49%     -70%
> In this benchmark, interconnect was not used by any other actors,
> so microbenchmark numbers might be significantly improved.
>
> Customer's evaluation:
> We were provided with the following feedback on this patch set
> directly from our customers. Unfortunately, we do not have details
> regarding how these measurements were done other than it was
> a production setup.
> Evaulation was performed on Kunpeng 920 and 920B platforms:
> CEPH distributed storage +5%
> StarRocksDB              +5%
>
> Couple more words about patch set and technology:
>
> This patchset was merged into the innovative branch of
> the openEuler distributive 1.5 year ago (openEuler-25.03)
> and was actively tested in production environment [9], [10].
> In addition, besides the kernel part, we have published
> user space replication (for translation tables and rodata) as well,
> but it is very complex and experimental
> even compared to this patch set [11]. With replication in user
> space, we were able to achieve the following numbers in
> performance improvement:
> MySQL + sysbench      1-6%
> Spark TPC-H           4-20%
> Phoronix test-suite   0-25%

Thank you for sharing the performance data. Does the SUT with 4 nodes 
have 4 real sockets? Nowadays the CPU design is moving to multiple 
chiplets. Subnuma configuration may be more and more popular in the 
future, so we thought kernel text replication can help performance for 
more usecases other than multi sockets machines.

Thanks,
Yang

>
> Discussion:
>
> The main question we'd like to discuss is the following:
> Should the kernel replication feature be merged into the Linux
> somewhere in the future? In any form, not specifically this patch set,
> but the core concept itself.
>
> If the answer is yes, please share your thoughts on this patch set. What else
> should be fixed (or reimplemented and redsigned completly) in this patch
> for mainline in your opinion? We'd be glad to do it, and in that case
> I'll send an updated version in the near future.
>
> [1]  https://lwn.net/ml/linux-doc/ZHYCUVa8fzmB4XZV@shell.armlinux.org.uk/
> [2]  https://lwn.net/ml/linux-mm/20231228131056.602411-1-artem.kuzin@huawei.com/
> [3]  https://lwn.net/Articles/36602/
> [4]  https://lwn.net/Articles/45082/
> [5]  https://github.com/mitosis-project/mitosis-asplos20-artifact
> [6]  https://dl.acm.org/doi/10.1145/3620665.3640369
> [7]  https://dl.acm.org/doi/10.1145/3767295.3769359
> [8]  https://github.com/Carrefour/linux-replication
> [9]  https://mailweb.openeuler.org/archives/list/kernel@openeuler.org/message/C7M5E2K2UD7FV7XYPWPZREJBCOCBIVRN/
> [10] https://www.openeuler.org/whitepaper/en/openEuler%2025.03%20Technical%20White%20Paper.pdf
> [11] https://mailweb.openeuler.org/archives/list/kernel@openeuler.org/message/73MAUDM6WCGSSOKPZGPNZAYRNQGUR6DE/
> [12] https://lore.kernel.org/linux-mm/20260715180455.515692-1-yang@os.amperecomputing.com/
>
> Nikita Panov (18):
>    mm: arm64 add Kconfig option for kernel replication
>    arm64: align kernel text and rodata
>    mm: allow per-NUMA node local P4D/PUD/PMD/PTE allocation
>    arm64: add arch callbacks for kernel replication
>    mm: per-NUMA node replication core infrastructure
>    mm: add support of memory protection for NUMA replicas
>    arm64: add support of memory protection for NUMA replicas
>    mm: set memory permissions for BPF handlers replicas
>    mm: add replicas allocation support for vmalloc
>    arm64: enable per-NUMA node kernel text and rodata replication
>    mm: enable per-NUMA node kernel text and rodata replication
>    arm64: make power management aware about kernel replication
>    arm64: make kernel text patching aware about replicas
>    arm64: add correct alignment to kimage in efi code
>    arm64: add support of NUMA replication for ptdump
>    arm64: add kernel modules text and rodata replication support
>    mm: init kernel modules with replication support
>    mm: introduce kernel cmdline option "kernel_replication="
>
>   .../admin-guide/kernel-parameters.txt         |   7 +
>   arch/arm64/include/asm/efi.h                  |  18 +-
>   arch/arm64/include/asm/mmu_context.h          |   4 +
>   arch/arm64/include/asm/numa_replication.h     |  54 ++
>   arch/arm64/include/asm/pgtable.h              |   4 +
>   arch/arm64/kernel/alternative.c               |  33 +-
>   arch/arm64/kernel/hibernate.c                 |   5 +
>   arch/arm64/kernel/module.c                    |  11 +
>   arch/arm64/kernel/patching.c                  |  96 ++
>   arch/arm64/kernel/sleep.S                     |   8 +
>   arch/arm64/kernel/smp.c                       |   8 +
>   arch/arm64/kernel/vmlinux.lds.S               |  22 +
>   arch/arm64/mm/init.c                          |  49 ++
>   arch/arm64/mm/kasan_init.c                    |   2 +
>   arch/arm64/mm/mmu.c                           |  42 +-
>   arch/arm64/mm/pageattr.c                      |  72 +-
>   arch/arm64/mm/ptdump.c                        |  24 +-
>   arch/arm64/net/bpf_jit_comp.c                 |   4 +-
>   include/asm-generic/pgalloc.h                 |  90 ++
>   include/asm-generic/pgtable-nop4d.h           |   5 +
>   include/asm-generic/pgtable-nopmd.h           |   5 +
>   include/asm-generic/pgtable-nopud.h           |   5 +
>   include/asm-generic/set_memory.h              |  14 +
>   include/linux/mm.h                            |  92 +-
>   include/linux/mm_types.h                      |   3 +
>   include/linux/moduleloader.h                  |   4 +
>   include/linux/numa_kernel_replication.h       | 112 +++
>   include/linux/set_memory.h                    |  21 +
>   include/linux/vmalloc.h                       |  18 +
>   init/main.c                                   |  17 +
>   kernel/bpf/core.c                             |   4 +-
>   kernel/bpf/trampoline.c                       |   2 +-
>   kernel/module/main.c                          |  20 +
>   kernel/module/strict_rwx.c                    |  12 +-
>   mm/Kconfig                                    |  10 +
>   mm/Makefile                                   |   2 +
>   mm/execmem.c                                  |  39 +-
>   mm/memory.c                                   | 129 +++
>   mm/mm_init.c                                  |   3 +
>   mm/numa_kernel_replication.c                  | 821 ++++++++++++++++++
>   mm/vmalloc.c                                  | 454 ++++++++--
>   41 files changed, 2246 insertions(+), 99 deletions(-)
>   create mode 100644 arch/arm64/include/asm/numa_replication.h
>   create mode 100644 include/linux/numa_kernel_replication.h
>   create mode 100644 mm/numa_kernel_replication.c
>
> --
> 2.34.1
>
>
Re: [RFC PATCH 00/18] mm: arm64: Add kernel replication feature
Posted by Nikita Panov 4 weeks ago
Hello, thanks for your comments

On 8/28/2026 11:58 PM, Yang Shi wrote:
>>
>> [1]  - arm64 kernel text replication
>> [2]  - x86 NUMA-aware kernel replication
>> [3]  - x86 kernel text replication
>> [4]  - NUMA replication of user data
>> [5]  - Mitosis: Transparently Self-Replicating Page-Tables for
>> Large-Memory Machines
>> [6]  - WASP: Workload-Aware Self-Replicating Page-Tables for NUMA Servers
>> [7]  - PaCaR: Improved Buffered I/O Locality on NUMA Systems with Page
>> Cache Replication
>> [8]  - Memory page replication for Linux on X86 processors
>> [12] - Optimize this_cpu_*() ops for non-x86 (ARM64 for this series)
>>
>> As of today, none of it was merged into mainline.
>>
>> Patch set description:
>>
>> This patchset implements initial support of the kernel
>> text and ro-data replication for arm64 platform.
>> Linux-next was used as a baseline.
>> (903c1cf6dff9 Add linux-next specific files for 20260821).
>> This patch set heavily relies on our previous submission [2],
>> their generic part is the same, these solutions might be merged into a
>> single one.
>> However, after thorough re-evaluation, we were not able to observe
>> performance improvement for the x86 platform, so we have decided to
>> stop this
>> direction and switch on arm64.
>>
>> Current implementation supports the next functionality:
>>
>> 1. Replicated kernel text and rodata per NUMA node
>> 2. Vmalloc is able to work with replicated areas, so
>>     kernel modules text and rodata are also replicated during
>>     modules loading stage.
>> 3. KPROBES, KGDB and all functionality that depends on
>>     kernel text patching work without any limitation.
>> 4. KPTI, KASLR, and KASAN are supported.
>> 5. Only part of a translation table related to
>>     replicated text and rodata is replicated
>>     (up to 2 pgd entries if kaslr is enabled)
>> 6. 4K + 48bit and 64K + 48/52bit are supported and tested.
>
> I think 16K + 47 VA bits should work too. I guess it is because there
> are just 2 top level entries with 16K + 48 VA bits. That requires some
> extra effort to sync up kernel page tables.
>

You are right, it should work with 16K + 47VA.
I did not test it on real hardware, so decided not to mention it here.

>> Known problems:
>>
>> 1. Other combinations of base page size and va size (especially with
>> 16K pages)
>>     should be adapted and verified.
>> 2. Replicated translation tables for the vmalloc region are not local
>> right now.
>>     Allocation performed with default memory policy, so translation
>> tables
>>     for kernel modules will not be local. However,
>>     replicated text and rodata of the modules are local.
>>     In general, vmalloc patch should be cleaned up.
>> 3. Any modifications of kernel PGD level. These modifications
>>     should be synchronized across all replicated tables.
>>     Right now, for example, memory hotplug/hotunplug
>>     lacks this support, vmemmap and kasan regions for
>>     added memory might not be observed correctly. This could be fixed
>>     by patching all places in the kernel where swapper_pg_dir
>>     is modified, or by "lazy" propagation on kernel faults in the
>> pgd-level.
>>     Propagation approach will not help in the case of pgd_clear()
>>     on swapper_pg_dir though.
>
> My percpu patchset (I saw you mentioned it above) already had these
> problems solved. I have not looked into too much detail yet, but it
> seems like you have replicate kernel page tables per node. My patchset
> added percpu kernel page tables. It should be able to support kernel
> text replication as well without too much extra effort. And it can
> support multiple usecases, for example, this_cpu optimization
> implemented in my series, kernel text replication and some potential
> security features. Multiple usecases should be able to make it more
> attractive and convincing. So as Christopher suggested it may be better
> to combine the effort.
>

I am going to check details of your patch set in the following week.
Preliminary - it can be reused for text replication, so yes,
I think it is better to combine our efforts.
The core problems of having replicated pgd are the same
for both per-cpu and per-node table cases.
Management of translation tables might become more complicated,
if both types are used (per-cpu and per-node).
But I do not think it will be a problem for kernel text and rodata replication.

>>
>> Overall, this patch set in an early PoC stage and require some
>> improvements.
>>
>> Overhead:
>>
>> Memory overhead for the kernel itself is about 30MB per NUMA node
>>    on our deployment. For kernel modules - depends on their sizes, but
>> text
>>    and ro-data are not that big.
>> CPU overhead - replication performed on the boot stage. After boot
>>    only "rare" operations are slowed down -
>>    module loading, text patching, kernel table pgd-level modifications.
>>
>> Performance evaluation:
>>
>> Our local testing was performed on
>> Kunpeng 920, 128 CPU, 4 nodes, 100Gb for each node.
>>
>> Microbenchmark:
>> Kernel module with a huge text section (~50MB) filled with CPU-bound
>> instructions. For each NUMA node thread is spawned, each thread in a loop
>> executes isntructions. Total execution time of each thread is measured.
>> The insmod call bound to node 0 through numactl (less time is better).
>>
>> node                 0        1        2        3
>> Before time, s     5.567    7.598   13.294   18.905
>> After  time, s     5.469    6.960    6.777    5.531
>>
>> Diff               ~0%      -8.5%    -49%     -70%
>> In this benchmark, interconnect was not used by any other actors,
>> so microbenchmark numbers might be significantly improved.
>>
>> Customer's evaluation:
>> We were provided with the following feedback on this patch set
>> directly from our customers. Unfortunately, we do not have details
>> regarding how these measurements were done other than it was
>> a production setup.
>> Evaulation was performed on Kunpeng 920 and 920B platforms:
>> CEPH distributed storage +5%
>> StarRocksDB              +5%
>>
>> Couple more words about patch set and technology:
>>
>> This patchset was merged into the innovative branch of
>> the openEuler distributive 1.5 year ago (openEuler-25.03)
>> and was actively tested in production environment [9], [10].
>> In addition, besides the kernel part, we have published
>> user space replication (for translation tables and rodata) as well,
>> but it is very complex and experimental
>> even compared to this patch set [11]. With replication in user
>> space, we were able to achieve the following numbers in
>> performance improvement:
>> MySQL + sysbench      1-6%
>> Spark TPC-H           4-20%
>> Phoronix test-suite   0-25%
>
> Thank you for sharing the performance data. Does the SUT with 4 nodes
> have 4 real sockets? Nowadays the CPU design is moving to multiple
> chiplets. Subnuma configuration may be more and more popular in the
> future, so we thought kernel text replication can help performance for
> more usecases other than multi sockets machines.
>
> Thanks,
> Yang
>

Our test machine has two physical sockets.
Each socket consists of two dies, 4 NUMA nodes in total.

We will start developing v2 on top of your patch set,
and share it when it is done. If you think we should do it differently,
please let us know.

Thanks again for taking the time to reply.

BR
Nikita Panov