diff options
author | Alex Williamson <alex.williamson@redhat.com> | 2012-12-10 12:33:03 -0500 |
---|---|---|
committer | Marcelo Tosatti <mtosatti@redhat.com> | 2012-12-13 20:21:53 -0500 |
commit | b7f69c555ca430129b6cde81e9f0927531420c5c (patch) | |
tree | 7b325611705e6293ce1fe3c87eeeb30746e2fe0e | |
parent | e40f193f5bb022e927a57a4f5d5194e4f12ddb74 (diff) |
KVM: Minor memory slot optimization
If a slot is removed or moved in the guest physical address space, we
first allocate and install a new slot array with the invalidated
entry. The old array is then freed. We then proceed to allocate yet
another slot array to install the permanent replacement. Re-use the
original array when this occurs and avoid the extra kfree/kmalloc.
Reviewed-by: Gleb Natapov <gleb@redhat.com>
Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
-rw-r--r-- | virt/kvm/kvm_main.c | 21 |
1 files changed, 14 insertions, 7 deletions
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 9a56ca2fa257..4c8c0657e370 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c | |||
@@ -716,7 +716,7 @@ int __kvm_set_memory_region(struct kvm *kvm, | |||
716 | unsigned long npages; | 716 | unsigned long npages; |
717 | struct kvm_memory_slot *memslot, *slot; | 717 | struct kvm_memory_slot *memslot, *slot; |
718 | struct kvm_memory_slot old, new; | 718 | struct kvm_memory_slot old, new; |
719 | struct kvm_memslots *slots, *old_memslots; | 719 | struct kvm_memslots *slots = NULL, *old_memslots; |
720 | 720 | ||
721 | r = check_memory_region_flags(mem); | 721 | r = check_memory_region_flags(mem); |
722 | if (r) | 722 | if (r) |
@@ -832,18 +832,25 @@ int __kvm_set_memory_region(struct kvm *kvm, | |||
832 | * - kvm_is_visible_gfn (mmu_check_roots) | 832 | * - kvm_is_visible_gfn (mmu_check_roots) |
833 | */ | 833 | */ |
834 | kvm_arch_flush_shadow_memslot(kvm, slot); | 834 | kvm_arch_flush_shadow_memslot(kvm, slot); |
835 | kfree(old_memslots); | 835 | slots = old_memslots; |
836 | } | 836 | } |
837 | 837 | ||
838 | r = kvm_arch_prepare_memory_region(kvm, &new, old, mem, user_alloc); | 838 | r = kvm_arch_prepare_memory_region(kvm, &new, old, mem, user_alloc); |
839 | if (r) | 839 | if (r) |
840 | goto out_free; | 840 | goto out_slots; |
841 | 841 | ||
842 | r = -ENOMEM; | 842 | r = -ENOMEM; |
843 | slots = kmemdup(kvm->memslots, sizeof(struct kvm_memslots), | 843 | /* |
844 | GFP_KERNEL); | 844 | * We can re-use the old_memslots from above, the only difference |
845 | if (!slots) | 845 | * from the currently installed memslots is the invalid flag. This |
846 | goto out_free; | 846 | * will get overwritten by update_memslots anyway. |
847 | */ | ||
848 | if (!slots) { | ||
849 | slots = kmemdup(kvm->memslots, sizeof(struct kvm_memslots), | ||
850 | GFP_KERNEL); | ||
851 | if (!slots) | ||
852 | goto out_free; | ||
853 | } | ||
847 | 854 | ||
848 | /* map new memory slot into the iommu */ | 855 | /* map new memory slot into the iommu */ |
849 | if (npages) { | 856 | if (npages) { |