From: Vipin Sharma <vipinsh@google.com>
To: seanjc@google.com, pbonzini@redhat.com, bgardon@google.com,
dmatlack@google.com
Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org,
Vipin Sharma <vipinsh@google.com>
Subject: [Patch v3 3/9] KVM: x86/mmu: Shrink split_shadow_page_cache via KVM MMU shrinker
Date: Wed, 21 Dec 2022 18:34:51 -0800 [thread overview]
Message-ID: <20221222023457.1764-4-vipinsh@google.com> (raw)
In-Reply-To: <20221222023457.1764-1-vipinsh@google.com>
split_shadow_page_cache is not used after dirty log is disabled. It is a
good candidate to free memory in case of mmu_shrink_scan kicks in.
Account for split_shadow_page_cache via kvm_total_unused_mmu_pages and
use it in mmu_shrink_scan.
Signed-off-by: Vipin Sharma <vipinsh@google.com>
---
arch/x86/include/asm/kvm_host.h | 5 +++
arch/x86/kvm/mmu/mmu.c | 63 +++++++++++++++++++--------------
2 files changed, 42 insertions(+), 26 deletions(-)
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index f89f02e18080..293994fabae3 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -1413,6 +1413,11 @@ struct kvm_arch {
struct kvm_mmu_memory_cache split_shadow_page_cache;
struct kvm_mmu_memory_cache split_page_header_cache;
+ /*
+ * Protects change in size of split_shadow_page_cache cache.
+ */
+ spinlock_t split_shadow_page_cache_lock;
+
/*
* Memory cache used to allocate pte_list_desc structs while splitting
* huge pages. In the worst case, to split one huge page, 512
diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c
index 3364760a1695..6f6a10d7a871 100644
--- a/arch/x86/kvm/mmu/mmu.c
+++ b/arch/x86/kvm/mmu/mmu.c
@@ -659,14 +659,15 @@ static void walk_shadow_page_lockless_end(struct kvm_vcpu *vcpu)
}
static int mmu_topup_sp_memory_cache(struct kvm_mmu_memory_cache *cache,
- spinlock_t *cache_lock)
+ spinlock_t *cache_lock,
+ int min)
{
int orig_nobjs;
int r;
spin_lock(cache_lock);
orig_nobjs = cache->nobjs;
- r = kvm_mmu_topup_memory_cache(cache, PT64_ROOT_MAX_LEVEL);
+ r = kvm_mmu_topup_memory_cache(cache, min);
if (orig_nobjs != cache->nobjs)
percpu_counter_add(&kvm_total_unused_mmu_pages,
(cache->nobjs - orig_nobjs));
@@ -684,7 +685,8 @@ static int mmu_topup_memory_caches(struct kvm_vcpu *vcpu, bool maybe_indirect)
if (r)
return r;
r = mmu_topup_sp_memory_cache(&vcpu->arch.mmu_shadow_page_cache,
- &vcpu->arch.mmu_shadow_page_cache_lock);
+ &vcpu->arch.mmu_shadow_page_cache_lock,
+ PT64_ROOT_MAX_LEVEL);
if (r)
return r;
if (maybe_indirect) {
@@ -2184,16 +2186,12 @@ void *kvm_mmu_sp_memory_cache_alloc(struct kvm_mmu_memory_cache *shadow_page_cac
int orig_nobjs;
void *page;
- if (!cache_lock) {
- spin_lock(cache_lock);
- orig_nobjs = shadow_page_cache->nobjs;
- }
+ spin_lock(cache_lock);
+ orig_nobjs = shadow_page_cache->nobjs;
page = kvm_mmu_memory_cache_alloc(shadow_page_cache);
- if (!cache_lock) {
- if (orig_nobjs)
- percpu_counter_dec(&kvm_total_unused_mmu_pages);
- spin_unlock(cache_lock);
- }
+ if (orig_nobjs)
+ percpu_counter_dec(&kvm_total_unused_mmu_pages);
+ spin_unlock(cache_lock);
return page;
}
@@ -6130,6 +6128,7 @@ int kvm_mmu_init_vm(struct kvm *kvm)
kvm->arch.split_page_header_cache.gfp_zero = __GFP_ZERO;
kvm->arch.split_shadow_page_cache.gfp_zero = __GFP_ZERO;
+ spin_lock_init(&kvm->arch.split_shadow_page_cache_lock);
kvm->arch.split_desc_cache.kmem_cache = pte_list_desc_cache;
kvm->arch.split_desc_cache.gfp_zero = __GFP_ZERO;
@@ -6141,7 +6140,8 @@ static void mmu_free_vm_memory_caches(struct kvm *kvm)
{
kvm_mmu_free_memory_cache(&kvm->arch.split_desc_cache);
kvm_mmu_free_memory_cache(&kvm->arch.split_page_header_cache);
- kvm_mmu_free_memory_cache(&kvm->arch.split_shadow_page_cache);
+ mmu_free_sp_memory_cache(&kvm->arch.split_shadow_page_cache,
+ &kvm->arch.split_shadow_page_cache_lock);
}
void kvm_mmu_uninit_vm(struct kvm *kvm)
@@ -6295,7 +6295,9 @@ static int topup_split_caches(struct kvm *kvm)
if (r)
return r;
- return kvm_mmu_topup_memory_cache(&kvm->arch.split_shadow_page_cache, 1);
+ return mmu_topup_sp_memory_cache(&kvm->arch.split_shadow_page_cache,
+ &kvm->arch.split_shadow_page_cache_lock,
+ 1);
}
static struct kvm_mmu_page *shadow_mmu_get_sp_for_split(struct kvm *kvm, u64 *huge_sptep)
@@ -6320,7 +6322,7 @@ static struct kvm_mmu_page *shadow_mmu_get_sp_for_split(struct kvm *kvm, u64 *hu
/* Direct SPs do not require a shadowed_info_cache. */
caches.page_header_cache = &kvm->arch.split_page_header_cache;
caches.shadow_page_cache = &kvm->arch.split_shadow_page_cache;
- caches.shadow_page_cache_lock = NULL;
+ caches.shadow_page_cache_lock = &kvm->arch.split_shadow_page_cache_lock;
/* Safe to pass NULL for vCPU since requesting a direct SP. */
return __kvm_mmu_get_shadow_page(kvm, NULL, &caches, gfn, role);
@@ -6687,14 +6689,23 @@ void kvm_mmu_invalidate_mmio_sptes(struct kvm *kvm, u64 gen)
}
}
+static unsigned long mmu_shrink_cache(struct kvm_mmu_memory_cache *cache,
+ spinlock_t *cache_lock)
+{
+ unsigned long freed = 0;
+
+ spin_lock(cache_lock);
+ if (cache->nobjs)
+ freed = kvm_mmu_empty_memory_cache(cache);
+ spin_unlock(cache_lock);
+ return freed;
+}
+
static unsigned long
mmu_shrink_scan(struct shrinker *shrink, struct shrink_control *sc)
{
- struct kvm_mmu_memory_cache *cache;
struct kvm *kvm, *first_kvm = NULL;
unsigned long freed = 0;
- /* spinlock for memory cache */
- spinlock_t *cache_lock;
struct kvm_vcpu *vcpu;
unsigned long i;
@@ -6707,15 +6718,15 @@ mmu_shrink_scan(struct shrinker *shrink, struct shrink_control *sc)
first_kvm = kvm;
list_move_tail(&kvm->vm_list, &vm_list);
- kvm_for_each_vcpu(i, vcpu, kvm) {
- cache = &vcpu->arch.mmu_shadow_page_cache;
- cache_lock = &vcpu->arch.mmu_shadow_page_cache_lock;
- if (READ_ONCE(cache->nobjs)) {
- spin_lock(cache_lock);
- freed += kvm_mmu_empty_memory_cache(cache);
- spin_unlock(cache_lock);
- }
+ freed += mmu_shrink_cache(&kvm->arch.split_shadow_page_cache,
+ &kvm->arch.split_shadow_page_cache_lock);
+ if (freed >= sc->nr_to_scan)
+ break;
+
+ kvm_for_each_vcpu(i, vcpu, kvm) {
+ freed += mmu_shrink_cache(&vcpu->arch.mmu_shadow_page_cache,
+ &vcpu->arch.mmu_shadow_page_cache_lock);
}
if (freed >= sc->nr_to_scan)
--
2.39.0.314.g84b9a713c41-goog
next prev parent reply other threads:[~2022-12-22 2:35 UTC|newest]
Thread overview: 47+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-12-22 2:34 [Patch v3 0/9] NUMA aware page table's pages allocation Vipin Sharma
2022-12-22 2:34 ` [Patch v3 1/9] KVM: x86/mmu: Repurpose KVM MMU shrinker to purge shadow page caches Vipin Sharma
2022-12-27 18:37 ` Ben Gardon
2022-12-28 22:07 ` Vipin Sharma
2022-12-29 21:15 ` David Matlack
2023-01-03 17:38 ` Vipin Sharma
2022-12-29 21:54 ` David Matlack
2023-01-03 18:01 ` Vipin Sharma
2023-01-04 0:25 ` Vipin Sharma
2023-01-18 17:43 ` Sean Christopherson
2023-01-03 19:32 ` Mingwei Zhang
2023-01-04 1:00 ` Vipin Sharma
2023-01-04 6:29 ` Mingwei Zhang
2023-01-04 6:57 ` Mingwei Zhang
2023-01-18 17:36 ` Sean Christopherson
2023-01-16 4:14 ` kernel test robot
2022-12-22 2:34 ` [Patch v3 2/9] KVM: x86/mmu: Remove zapped_obsolete_pages from struct kvm_arch{} Vipin Sharma
2022-12-29 21:59 ` David Matlack
2022-12-22 2:34 ` Vipin Sharma [this message]
2022-12-22 2:34 ` [Patch v3 4/9] KVM: Add module param to make page tables NUMA aware Vipin Sharma
2022-12-29 22:05 ` David Matlack
2022-12-22 2:34 ` [Patch v3 5/9] KVM: x86/mmu: Allocate TDP page table's page on correct NUMA node on split Vipin Sharma
2022-12-27 19:02 ` Ben Gardon
2022-12-28 22:07 ` Vipin Sharma
2022-12-29 22:30 ` David Matlack
2023-01-03 18:26 ` Vipin Sharma
2022-12-22 2:34 ` [Patch v3 6/9] KVM: Provide NUMA node support to kvm_mmu_memory_cache{} Vipin Sharma
2022-12-27 19:09 ` Ben Gardon
2022-12-28 22:07 ` Vipin Sharma
2022-12-29 18:22 ` Ben Gardon
2023-01-03 17:36 ` Vipin Sharma
2022-12-29 23:08 ` David Matlack
2022-12-29 23:11 ` David Matlack
2023-01-03 18:45 ` Vipin Sharma
2023-01-03 18:55 ` David Matlack
2022-12-22 2:34 ` [Patch v3 7/9] KVM: x86/mmu: Allocate page table's pages on NUMA node of the underlying pages Vipin Sharma
2022-12-27 19:34 ` Ben Gardon
2022-12-28 22:08 ` Vipin Sharma
2022-12-29 18:20 ` Ben Gardon
2022-12-22 2:34 ` [Patch v3 8/9] KVM: x86/mmu: Make split_shadow_page_cache NUMA aware Vipin Sharma
2022-12-27 19:42 ` Ben Gardon
2022-12-28 22:08 ` Vipin Sharma
2022-12-29 23:18 ` David Matlack
2023-01-03 18:49 ` Vipin Sharma
2022-12-22 2:34 ` [Patch v3 9/9] KVM: x86/mmu: Reduce default cache size in KVM from 40 to PT64_ROOT_MAX_LEVEL Vipin Sharma
2022-12-27 19:52 ` Ben Gardon
2022-12-28 22:08 ` Vipin Sharma
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20221222023457.1764-4-vipinsh@google.com \
--to=vipinsh@google.com \
--cc=bgardon@google.com \
--cc=dmatlack@google.com \
--cc=kvm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=pbonzini@redhat.com \
--cc=seanjc@google.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®