Message ID | 20220823004639.2387269-5-yosryahmed@google.com (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | KVM: mm: count KVM mmu usage in memory stats | expand |
> Count the pages used by KVM in arm64 for stage2 mmu in memory stats > under secondary pagetable stats (e.g. "SecPageTables" in /proc/meminfo) > to give better visibility into the memory consumption of KVM mmu in a > similar way to how normal user page tables are accounted. > > Signed-off-by: Yosry Ahmed <yosryahmed@google.com> > Reviewed-by: Oliver Upton <oliver.upton@linux.dev> > Reviewed-by: Marc Zyngier <maz@kernel.org> > --- I see that you are not including the memory reserved for the host stage2 table when using protected KVM. Is this something worth adding? (See arch/arm64/kvm/pkvm.c:kvm_hyp_reserve()). This reservation is done pretty early on in bootmem_init() so not sure if this could cause some init ordering issues that might be tricky to solve though. Thanks, Ryan
On Wed, 24 Aug 2022 14:43:43 +0100, Ryan Roberts <ryan.roberts@arm.com> wrote: > > > Count the pages used by KVM in arm64 for stage2 mmu in memory stats > > under secondary pagetable stats (e.g. "SecPageTables" in /proc/meminfo) > > to give better visibility into the memory consumption of KVM mmu in a > > similar way to how normal user page tables are accounted. > > > > Signed-off-by: Yosry Ahmed <yosryahmed@google.com> > > Reviewed-by: Oliver Upton <oliver.upton@linux.dev> > > Reviewed-by: Marc Zyngier <maz@kernel.org> > > --- > > I see that you are not including the memory reserved for the host > stage2 table when using protected KVM. Is this something worth adding? > (See arch/arm64/kvm/pkvm.c:kvm_hyp_reserve()). > > This reservation is done pretty early on in bootmem_init() so not sure > if this could cause some init ordering issues that might be tricky to > solve though. I also don't see what this buys us. This memory can't be reclaimed, and is not part of KVM's job for the purpose of running guests, which is what this series is about. If anything, it should be accounted separately. M.
On 24/08/2022 15:24, Marc Zyngier wrote: > On Wed, 24 Aug 2022 14:43:43 +0100, > Ryan Roberts <ryan.roberts@arm.com> wrote: >> >>> Count the pages used by KVM in arm64 for stage2 mmu in memory stats >>> under secondary pagetable stats (e.g. "SecPageTables" in /proc/meminfo) >>> to give better visibility into the memory consumption of KVM mmu in a >>> similar way to how normal user page tables are accounted. >>> >>> Signed-off-by: Yosry Ahmed <yosryahmed@google.com> >>> Reviewed-by: Oliver Upton <oliver.upton@linux.dev> >>> Reviewed-by: Marc Zyngier <maz@kernel.org> >>> --- >> >> I see that you are not including the memory reserved for the host >> stage2 table when using protected KVM. Is this something worth adding? >> (See arch/arm64/kvm/pkvm.c:kvm_hyp_reserve()). >> >> This reservation is done pretty early on in bootmem_init() so not sure >> if this could cause some init ordering issues that might be tricky to >> solve though. > > I also don't see what this buys us. This memory can't be reclaimed, > and is not part of KVM's job for the purpose of running guests, which > is what this series is about. > > If anything, it should be accounted separately. OK fair enough. It just struck me from the patch description that the host stage2 might qualify as "pages used by KVM in arm64 for stage2 mmu". But I don't have any understanding of the use case this is for. Sorry for the noise! Thanks, Ryan
diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c index c9a13e487187..34c5feed9dc1 100644 --- a/arch/arm64/kvm/mmu.c +++ b/arch/arm64/kvm/mmu.c @@ -92,9 +92,13 @@ static bool kvm_is_device_pfn(unsigned long pfn) static void *stage2_memcache_zalloc_page(void *arg) { struct kvm_mmu_memory_cache *mc = arg; + void *virt; /* Allocated with __GFP_ZERO, so no need to zero */ - return kvm_mmu_memory_cache_alloc(mc); + virt = kvm_mmu_memory_cache_alloc(mc); + if (virt) + kvm_account_pgtable_pages(virt, 1); + return virt; } static void *kvm_host_zalloc_pages_exact(size_t size) @@ -102,6 +106,21 @@ static void *kvm_host_zalloc_pages_exact(size_t size) return alloc_pages_exact(size, GFP_KERNEL_ACCOUNT | __GFP_ZERO); } +static void *kvm_s2_zalloc_pages_exact(size_t size) +{ + void *virt = kvm_host_zalloc_pages_exact(size); + + if (virt) + kvm_account_pgtable_pages(virt, (size >> PAGE_SHIFT)); + return virt; +} + +static void kvm_s2_free_pages_exact(void *virt, size_t size) +{ + kvm_account_pgtable_pages(virt, -(size >> PAGE_SHIFT)); + free_pages_exact(virt, size); +} + static void kvm_host_get_page(void *addr) { get_page(virt_to_page(addr)); @@ -112,6 +131,15 @@ static void kvm_host_put_page(void *addr) put_page(virt_to_page(addr)); } +static void kvm_s2_put_page(void *addr) +{ + struct page *p = virt_to_page(addr); + /* Dropping last refcount, the page will be freed */ + if (page_count(p) == 1) + kvm_account_pgtable_pages(addr, -1); + put_page(p); +} + static int kvm_host_page_count(void *addr) { return page_count(virt_to_page(addr)); @@ -625,10 +653,10 @@ static int get_user_mapping_size(struct kvm *kvm, u64 addr) static struct kvm_pgtable_mm_ops kvm_s2_mm_ops = { .zalloc_page = stage2_memcache_zalloc_page, - .zalloc_pages_exact = kvm_host_zalloc_pages_exact, - .free_pages_exact = free_pages_exact, + .zalloc_pages_exact = kvm_s2_zalloc_pages_exact, + .free_pages_exact = kvm_s2_free_pages_exact, .get_page = kvm_host_get_page, - .put_page = kvm_host_put_page, + .put_page = kvm_s2_put_page, .page_count = kvm_host_page_count, .phys_to_virt = kvm_host_va, .virt_to_phys = kvm_host_pa,