Commit c1a7b32a14138f908df52d7c53b5ce3415ec6b50

Authored by Takuya Yoshikawa
Committed by Avi Kivity
1 parent 92eca8faad

KVM: Avoid wasting pages for small lpage_info arrays

lpage_info is created for each large level even when the memory slot is
not for RAM.  This means that when we add one slot for a PCI device, we
end up allocating at least KVM_NR_PAGE_SIZES - 1 pages by vmalloc().

To make things worse, there is an increasing number of devices which
would result in more pages being wasted this way.

This patch mitigates this problem by using kvm_kvzalloc().

Signed-off-by: Takuya Yoshikawa <yoshikawa.takuya@oss.ntt.co.jp>
Signed-off-by: Avi Kivity <avi@redhat.com>

Showing 3 changed files with 7 additions and 4 deletions Side-by-side Diff

... ... @@ -6304,7 +6304,7 @@
6304 6304  
6305 6305 for (i = 0; i < KVM_NR_PAGE_SIZES - 1; ++i) {
6306 6306 if (!dont || free->arch.lpage_info[i] != dont->arch.lpage_info[i]) {
6307   - vfree(free->arch.lpage_info[i]);
  6307 + kvm_kvfree(free->arch.lpage_info[i]);
6308 6308 free->arch.lpage_info[i] = NULL;
6309 6309 }
6310 6310 }
... ... @@ -6323,7 +6323,7 @@
6323 6323 slot->base_gfn, level) + 1;
6324 6324  
6325 6325 slot->arch.lpage_info[i] =
6326   - vzalloc(lpages * sizeof(*slot->arch.lpage_info[i]));
  6326 + kvm_kvzalloc(lpages * sizeof(*slot->arch.lpage_info[i]));
6327 6327 if (!slot->arch.lpage_info[i])
6328 6328 goto out_free;
6329 6329  
include/linux/kvm_host.h
... ... @@ -535,6 +535,9 @@
535 535  
536 536 void kvm_free_physmem(struct kvm *kvm);
537 537  
  538 +void *kvm_kvzalloc(unsigned long size);
  539 +void kvm_kvfree(const void *addr);
  540 +
538 541 #ifndef __KVM_HAVE_ARCH_VM_ALLOC
539 542 static inline struct kvm *kvm_arch_alloc_vm(void)
540 543 {
... ... @@ -520,7 +520,7 @@
520 520 * Avoid using vmalloc for a small buffer.
521 521 * Should not be used when the size is statically known.
522 522 */
523   -static void *kvm_kvzalloc(unsigned long size)
  523 +void *kvm_kvzalloc(unsigned long size)
524 524 {
525 525 if (size > PAGE_SIZE)
526 526 return vzalloc(size);
... ... @@ -528,7 +528,7 @@
528 528 return kzalloc(size, GFP_KERNEL);
529 529 }
530 530  
531   -static void kvm_kvfree(const void *addr)
  531 +void kvm_kvfree(const void *addr)
532 532 {
533 533 if (is_vmalloc_addr(addr))
534 534 vfree(addr);