aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm/x86.c
diff options
context:
space:
mode:
authorTakuya Yoshikawa <yoshikawa.takuya@oss.ntt.co.jp>2010-04-28 05:50:36 -0400
committerAvi Kivity <avi@redhat.com>2010-08-01 03:35:27 -0400
commit914ebccd2d8fa439e01fe93b5229534b9e179a69 (patch)
tree13341c1b1fcd6d4eeb39576c75417cccbcdee748 /arch/x86/kvm/x86.c
parentc332c83ae736c72dcf072e96e98a774fce39e722 (diff)
KVM: x86: avoid unnecessary bitmap allocation when memslot is clean
Although we always allocate a new dirty bitmap in x86's get_dirty_log(), it is only used as a zero-source of copy_to_user() and freed right after that when memslot is clean. This patch uses clear_user() instead of doing this unnecessary zero-source allocation. Performance improvement: as we can expect easily, the time needed to allocate a bitmap is completely reduced. In my test, the improved ioctl was about 4 to 10 times faster than the original one for clean slots. Furthermore, reducing memory allocations and copies will produce good effects to caches too. Signed-off-by: Takuya Yoshikawa <yoshikawa.takuya@oss.ntt.co.jp> Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'arch/x86/kvm/x86.c')
-rw-r--r--arch/x86/kvm/x86.c37
1 files changed, 23 insertions, 14 deletions
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 7fa89c39c64..1b270fd6063 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -2797,7 +2797,6 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
2797 struct kvm_memory_slot *memslot; 2797 struct kvm_memory_slot *memslot;
2798 unsigned long n; 2798 unsigned long n;
2799 unsigned long is_dirty = 0; 2799 unsigned long is_dirty = 0;
2800 unsigned long *dirty_bitmap = NULL;
2801 2800
2802 mutex_lock(&kvm->slots_lock); 2801 mutex_lock(&kvm->slots_lock);
2803 2802
@@ -2812,27 +2811,30 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
2812 2811
2813 n = kvm_dirty_bitmap_bytes(memslot); 2812 n = kvm_dirty_bitmap_bytes(memslot);
2814 2813
2815 r = -ENOMEM;
2816 dirty_bitmap = vmalloc(n);
2817 if (!dirty_bitmap)
2818 goto out;
2819 memset(dirty_bitmap, 0, n);
2820
2821 for (i = 0; !is_dirty && i < n/sizeof(long); i++) 2814 for (i = 0; !is_dirty && i < n/sizeof(long); i++)
2822 is_dirty = memslot->dirty_bitmap[i]; 2815 is_dirty = memslot->dirty_bitmap[i];
2823 2816
2824 /* If nothing is dirty, don't bother messing with page tables. */ 2817 /* If nothing is dirty, don't bother messing with page tables. */
2825 if (is_dirty) { 2818 if (is_dirty) {
2826 struct kvm_memslots *slots, *old_slots; 2819 struct kvm_memslots *slots, *old_slots;
2820 unsigned long *dirty_bitmap;
2827 2821
2828 spin_lock(&kvm->mmu_lock); 2822 spin_lock(&kvm->mmu_lock);
2829 kvm_mmu_slot_remove_write_access(kvm, log->slot); 2823 kvm_mmu_slot_remove_write_access(kvm, log->slot);
2830 spin_unlock(&kvm->mmu_lock); 2824 spin_unlock(&kvm->mmu_lock);
2831 2825
2832 slots = kzalloc(sizeof(struct kvm_memslots), GFP_KERNEL); 2826 r = -ENOMEM;
2833 if (!slots) 2827 dirty_bitmap = vmalloc(n);
2834 goto out_free; 2828 if (!dirty_bitmap)
2829 goto out;
2830 memset(dirty_bitmap, 0, n);
2835 2831
2832 r = -ENOMEM;
2833 slots = kzalloc(sizeof(struct kvm_memslots), GFP_KERNEL);
2834 if (!slots) {
2835 vfree(dirty_bitmap);
2836 goto out;
2837 }
2836 memcpy(slots, kvm->memslots, sizeof(struct kvm_memslots)); 2838 memcpy(slots, kvm->memslots, sizeof(struct kvm_memslots));
2837 slots->memslots[log->slot].dirty_bitmap = dirty_bitmap; 2839 slots->memslots[log->slot].dirty_bitmap = dirty_bitmap;
2838 2840
@@ -2841,13 +2843,20 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
2841 synchronize_srcu_expedited(&kvm->srcu); 2843 synchronize_srcu_expedited(&kvm->srcu);
2842 dirty_bitmap = old_slots->memslots[log->slot].dirty_bitmap; 2844 dirty_bitmap = old_slots->memslots[log->slot].dirty_bitmap;
2843 kfree(old_slots); 2845 kfree(old_slots);
2846
2847 r = -EFAULT;
2848 if (copy_to_user(log->dirty_bitmap, dirty_bitmap, n)) {
2849 vfree(dirty_bitmap);
2850 goto out;
2851 }
2852 vfree(dirty_bitmap);
2853 } else {
2854 r = -EFAULT;
2855 if (clear_user(log->dirty_bitmap, n))
2856 goto out;
2844 } 2857 }
2845 2858
2846 r = 0; 2859 r = 0;
2847 if (copy_to_user(log->dirty_bitmap, dirty_bitmap, n))
2848 r = -EFAULT;
2849out_free:
2850 vfree(dirty_bitmap);
2851out: 2860out:
2852 mutex_unlock(&kvm->slots_lock); 2861 mutex_unlock(&kvm->slots_lock);
2853 return r; 2862 return r;