From: Takuya Yoshikawa <yoshikawa.takuya@xxxxxxxxxxxxx> Currently, mmu_shrink() tries to free a shadow page from one kvm and does not use nr_to_scan correctly. This patch fixes this by making it try to free some shadow pages from each kvm. The number of shadow pages each kvm frees becomes proportional to the number of shadow pages it is using. Note: an easy way to see how this code works is to do echo 3 > /proc/sys/vm/drop_caches during some virtual machines are running. Shadow pages will be zapped as expected by this. Signed-off-by: Takuya Yoshikawa <yoshikawa.takuya@xxxxxxxxxxxxx> --- arch/x86/kvm/mmu.c | 23 ++++++++++++++--------- 1 files changed, 14 insertions(+), 9 deletions(-) diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index fcd0dd1..c6c61dd 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c @@ -3921,7 +3921,7 @@ restart: static int mmu_shrink(struct shrinker *shrink, struct shrink_control *sc) { struct kvm *kvm; - struct kvm *kvm_freed = NULL; + int nr_to_zap, nr_total; int nr_to_scan = sc->nr_to_scan; if (nr_to_scan == 0) @@ -3929,25 +3929,30 @@ static int mmu_shrink(struct shrinker *shrink, struct shrink_control *sc) raw_spin_lock(&kvm_lock); + nr_total = percpu_counter_read_positive(&kvm_total_used_mmu_pages); + list_for_each_entry(kvm, &kvm_list, list) { int idx; LIST_HEAD(invalid_list); + if (nr_to_scan <= 0) { + /* next time from this kvm */ + list_move_tail(&kvm_list, &kvm->list); + break; + } + idx = srcu_read_lock(&kvm->srcu); spin_lock(&kvm->mmu_lock); - if (!kvm_freed && nr_to_scan > 0 && - kvm->arch.n_used_mmu_pages > 0) { - pre_zap_one_sp(kvm, &invalid_list); - kvm_freed = kvm; - } - nr_to_scan--; + /* proportional to how many shadow pages this kvm is using */ + nr_to_zap = sc->nr_to_scan * kvm->arch.n_used_mmu_pages; + nr_to_zap /= nr_total; + nr_to_scan -= pre_zap_some_sp(kvm, &invalid_list, nr_to_zap); kvm_mmu_commit_zap_page(kvm, &invalid_list); + spin_unlock(&kvm->mmu_lock); srcu_read_unlock(&kvm->srcu, idx); } - if (kvm_freed) - list_move_tail(&kvm_freed->list, &kvm_list); raw_spin_unlock(&kvm_lock); -- 1.7.5.4 -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html