Use MMU shrinker to free unused pages in split_shadow_page_cache. Refactor the code and make common function to try emptying the page cache. Signed-off-by: Vipin Sharma <vipinsh@xxxxxxxxxx> --- arch/x86/kvm/mmu/mmu.c | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c index 0ebb8a2eaf47..73a0ac9c11ce 100644 --- a/arch/x86/kvm/mmu/mmu.c +++ b/arch/x86/kvm/mmu/mmu.c @@ -6696,13 +6696,24 @@ void kvm_mmu_invalidate_mmio_sptes(struct kvm *kvm, u64 gen) } } +static int mmu_memory_cache_try_empty(struct kvm_mmu_memory_cache *cache, + struct mutex *cache_lock) +{ + int freed = 0; + + if (mutex_trylock(cache_lock)) { + freed = cache->nobjs; + kvm_mmu_empty_memory_cache(cache); + mutex_unlock(cache_lock); + } + return freed; +} + static unsigned long mmu_shrink_scan(struct shrinker *shrink, struct shrink_control *sc) { struct kvm *kvm, *next_kvm, *first_kvm = NULL; - struct kvm_mmu_memory_cache *cache; unsigned long i, freed = 0; - struct mutex *cache_lock; struct kvm_vcpu *vcpu; mutex_lock(&kvm_lock); @@ -6716,18 +6727,15 @@ static unsigned long mmu_shrink_scan(struct shrinker *shrink, 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 (mutex_trylock(cache_lock)) { - if (cache->nobjs) { - freed += cache->nobjs; - kvm_mmu_empty_memory_cache(cache); - } - mutex_unlock(cache_lock); - if (freed >= sc->nr_to_scan) - goto out; - } + freed += mmu_memory_cache_try_empty(&vcpu->arch.mmu_shadow_page_cache, + &vcpu->arch.mmu_shadow_page_cache_lock); + if (freed >= sc->nr_to_scan) + goto out; } + freed += mmu_memory_cache_try_empty(&kvm->arch.split_shadow_page_cache, + &kvm->slots_lock); + if (freed >= sc->nr_to_scan) + goto out; } out: mutex_unlock(&kvm_lock); -- 2.40.0.rc0.216.gc4246ad0f0-goog