Skip to content

Commit 4e10313

Browse files
Sean Christophersonbonzini
authored andcommitted
KVM: x86/mmu: Zap only the relevant pages when removing a memslot
Modify kvm_mmu_invalidate_zap_pages_in_memslot(), a.k.a. the x86 MMU's handler for kvm_arch_flush_shadow_memslot(), to zap only the pages/PTEs that actually belong to the memslot being removed. This improves performance, especially why the deleted memslot has only a few shadow entries, or even no entries. E.g. a microbenchmark to access regular memory while concurrently reading PCI ROM to trigger memslot deletion showed a 5% improvement in throughput. Cc: Xiao Guangrong <[email protected]> Signed-off-by: Sean Christopherson <[email protected]> Signed-off-by: Paolo Bonzini <[email protected]>
1 parent a211363 commit 4e10313

File tree

1 file changed

+32
-1
lines changed

1 file changed

+32
-1
lines changed

arch/x86/kvm/mmu.c

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5622,7 +5622,38 @@ static void kvm_mmu_invalidate_zap_pages_in_memslot(struct kvm *kvm,
56225622
struct kvm_memory_slot *slot,
56235623
struct kvm_page_track_notifier_node *node)
56245624
{
5625-
kvm_mmu_invalidate_zap_all_pages(kvm);
5625+
struct kvm_mmu_page *sp;
5626+
LIST_HEAD(invalid_list);
5627+
unsigned long i;
5628+
bool flush;
5629+
gfn_t gfn;
5630+
5631+
spin_lock(&kvm->mmu_lock);
5632+
5633+
if (list_empty(&kvm->arch.active_mmu_pages))
5634+
goto out_unlock;
5635+
5636+
flush = slot_handle_all_level(kvm, slot, kvm_zap_rmapp, false);
5637+
5638+
for (i = 0; i < slot->npages; i++) {
5639+
gfn = slot->base_gfn + i;
5640+
5641+
for_each_valid_sp(kvm, sp, gfn) {
5642+
if (sp->gfn != gfn)
5643+
continue;
5644+
5645+
kvm_mmu_prepare_zap_page(kvm, sp, &invalid_list);
5646+
}
5647+
if (need_resched() || spin_needbreak(&kvm->mmu_lock)) {
5648+
kvm_mmu_remote_flush_or_zap(kvm, &invalid_list, flush);
5649+
flush = false;
5650+
cond_resched_lock(&kvm->mmu_lock);
5651+
}
5652+
}
5653+
kvm_mmu_remote_flush_or_zap(kvm, &invalid_list, flush);
5654+
5655+
out_unlock:
5656+
spin_unlock(&kvm->mmu_lock);
56265657
}
56275658

56285659
void kvm_mmu_init_vm(struct kvm *kvm)

0 commit comments

Comments
 (0)