diff options
author | Avi Kivity <avi@redhat.com> | 2009-01-06 06:00:27 -0500 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2009-03-24 05:03:02 -0400 |
commit | 4677a3b693e035f186e2875259b9a0bb94c42fbe (patch) | |
tree | bd5aec1050ee534ef9e9dc5c8628f81bf815a96c /arch/x86/kvm/mmu.c | |
parent | c8a73f186bf62235b6fb5dd52601d641917dd50b (diff) |
KVM: MMU: Optimize page unshadowing
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>
Diffstat (limited to 'arch/x86/kvm/mmu.c')
-rw-r--r-- | arch/x86/kvm/mmu.c | 15 |
1 files changed, 12 insertions, 3 deletions
diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index 15850809b55b..aac0499947d8 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c | |||
@@ -1471,11 +1471,20 @@ static int kvm_mmu_unprotect_page(struct kvm *kvm, gfn_t gfn) | |||
1471 | 1471 | ||
1472 | static void mmu_unshadow(struct kvm *kvm, gfn_t gfn) | 1472 | static void mmu_unshadow(struct kvm *kvm, gfn_t gfn) |
1473 | { | 1473 | { |
1474 | unsigned index; | ||
1475 | struct hlist_head *bucket; | ||
1474 | struct kvm_mmu_page *sp; | 1476 | struct kvm_mmu_page *sp; |
1477 | struct hlist_node *node, *nn; | ||
1475 | 1478 | ||
1476 | while ((sp = kvm_mmu_lookup_page(kvm, gfn)) != NULL) { | 1479 | index = kvm_page_table_hashfn(gfn); |
1477 | pgprintk("%s: zap %lx %x\n", __func__, gfn, sp->role.word); | 1480 | bucket = &kvm->arch.mmu_page_hash[index]; |
1478 | kvm_mmu_zap_page(kvm, sp); | 1481 | hlist_for_each_entry_safe(sp, node, nn, bucket, hash_link) { |
1482 | if (sp->gfn == gfn && !sp->role.metaphysical | ||
1483 | && !sp->role.invalid) { | ||
1484 | pgprintk("%s: zap %lx %x\n", | ||
1485 | __func__, gfn, sp->role.word); | ||
1486 | kvm_mmu_zap_page(kvm, sp); | ||
1487 | } | ||
1479 | } | 1488 | } |
1480 | } | 1489 | } |
1481 | 1490 | ||