[PATCH] RISC-V: KVM: Avoid redundant page-table allocations in ioremap topup

Anup Patel anup at brainfault.org
Sun Jul 12 22:20:32 PDT 2026


On Wed, Jun 10, 2026 at 3:09 PM <fangyu.yu at linux.alibaba.com> wrote:
>
> From: Fangyu Yu <fangyu.yu at linux.alibaba.com>
>
> kvm_riscv_mmu_ioremap() currently tops up its on-stack page-table
> cache via kvm_mmu_topup_memory_cache(), which allocates up to
> KVM_ARCH_NR_OBJS_PER_MEMORY_CACHE (32) objects per topup.
>
> ioremap only consumes non-leaf page-table pages, at most
> pgd_levels - 1 (1 to 4) per call, and for contiguous mappings
> within the same huge page the non-leaf pages are allocated once
> and reused by subsequent pages. Topping up to 32 objects therefore
> triggers many unnecessary GFP_KERNEL_ACCOUNT allocations on every
> call, all of which are freed when the function returns. In hot
> paths (such as vCPU migration), this creates avoidable allocator
> churn and wastes CPU cycles.
>
> Use __kvm_mmu_topup_memory_cache() with a capacity of pgd_levels so
> the on-stack cache is sized to the maximum demand of a single
> mapping. This removes the redundant allocations and reduces per-call
> overhead without changing behavior.
>
> Signed-off-by: Fangyu Yu <fangyu.yu at linux.alibaba.com>

LGTM.

Reviewed-by: Anup Patel <anup at brainfault.org>

Queued this patch as a fix for Linux-7.2-rcX

Thanks,
Anup

> ---
>  arch/riscv/kvm/mmu.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/arch/riscv/kvm/mmu.c b/arch/riscv/kvm/mmu.c
> index 2d3def024270..873a5dde4b92 100644
> --- a/arch/riscv/kvm/mmu.c
> +++ b/arch/riscv/kvm/mmu.c
> @@ -39,6 +39,7 @@ int kvm_riscv_mmu_ioremap(struct kvm *kvm, gpa_t gpa, phys_addr_t hpa,
>         pgprot_t prot;
>         unsigned long pfn;
>         phys_addr_t addr, end;
> +       unsigned long pgd_levels = kvm->arch.pgd_levels;
>         struct kvm_mmu_memory_cache pcache = {
>                 .gfp_custom = (in_atomic) ? GFP_ATOMIC | __GFP_ACCOUNT : 0,
>                 .gfp_zero = __GFP_ZERO,
> @@ -61,7 +62,7 @@ int kvm_riscv_mmu_ioremap(struct kvm *kvm, gpa_t gpa, phys_addr_t hpa,
>                 if (!writable)
>                         map.pte = pte_wrprotect(map.pte);
>
> -               ret = kvm_mmu_topup_memory_cache(&pcache, kvm->arch.pgd_levels);
> +               ret = __kvm_mmu_topup_memory_cache(&pcache, pgd_levels, pgd_levels);
>                 if (ret)
>                         goto out;
>
> --
> 2.50.1
>



More information about the linux-riscv mailing list