KVM: MMU: Optimize page unshadowing
authorAvi Kivity <avi@redhat.com>
Tue, 6 Jan 2009 11:00:27 +0000 (13:00 +0200)
committerAvi Kivity <avi@redhat.com>
Tue, 24 Mar 2009 09:03:02 +0000 (11:03 +0200)
Using kvm_mmu_lookup_page() will result in multiple scans of the hash chains;
use hlist_for_each_entry_safe() to achieve a single scan instead.

Signed-off-by: Avi Kivity <avi@redhat.com>
arch/x86/kvm/mmu.c

index 15850809b55b2bed64aeaa5bd3143571c2a45ecf..aac0499947d864786003b8b993f738b797a2877b 100644 (file)
@@ -1471,11 +1471,20 @@ static int kvm_mmu_unprotect_page(struct kvm *kvm, gfn_t gfn)
 
 static void mmu_unshadow(struct kvm *kvm, gfn_t gfn)
 {
+       unsigned index;
+       struct hlist_head *bucket;
        struct kvm_mmu_page *sp;
+       struct hlist_node *node, *nn;
 
-       while ((sp = kvm_mmu_lookup_page(kvm, gfn)) != NULL) {
-               pgprintk("%s: zap %lx %x\n", __func__, gfn, sp->role.word);
-               kvm_mmu_zap_page(kvm, sp);
+       index = kvm_page_table_hashfn(gfn);
+       bucket = &kvm->arch.mmu_page_hash[index];
+       hlist_for_each_entry_safe(sp, node, nn, bucket, hash_link) {
+               if (sp->gfn == gfn && !sp->role.metaphysical
+                   && !sp->role.invalid) {
+                       pgprintk("%s: zap %lx %x\n",
+                                __func__, gfn, sp->role.word);
+                       kvm_mmu_zap_page(kvm, sp);
+               }
        }
 }