aboutsummaryrefslogtreecommitdiffstats
path: root/virt/kvm
diff options
context:
space:
mode:
authorBen Gardon <bgardon@google.com>2019-02-11 14:02:49 -0500
committerPaolo Bonzini <pbonzini@redhat.com>2019-02-20 16:48:29 -0500
commitb12ce36a43f29dbff0bca14c5a51c276aea5662f (patch)
tree0c74c65ab47355b898f2dc4bf1f2faa78f3ee140 /virt/kvm
parent359a6c3ddc5184122989d5152a4b975c1c262d33 (diff)
kvm: Add memcg accounting to KVM allocations
There are many KVM kernel memory allocations which are tied to the life of the VM process and should be charged to the VM process's cgroup. If the allocations aren't tied to the process, the OOM killer will not know that killing the process will free the associated kernel memory. Add __GFP_ACCOUNT flags to many of the allocations which are not yet being charged to the VM process's cgroup. Tested: Ran all kvm-unit-tests on a 64 bit Haswell machine, the patch introduced no new failures. Ran a kernel memory accounting test which creates a VM to touch memory and then checks that the kernel memory allocated for the process is within certain bounds. With this patch we account for much more of the vmalloc and slab memory allocated for the VM. There remain a few allocations which should be charged to the VM's cgroup but are not. In they include: vcpu->run kvm->coalesced_mmio_ring There allocations are unaccounted in this patch because they are mapped to userspace, and accounting them to a cgroup causes problems. This should be addressed in a future patch. Signed-off-by: Ben Gardon <bgardon@google.com> Reviewed-by: Shakeel Butt <shakeelb@google.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'virt/kvm')
-rw-r--r--virt/kvm/coalesced_mmio.c3
-rw-r--r--virt/kvm/eventfd.c7
-rw-r--r--virt/kvm/irqchip.c4
-rw-r--r--virt/kvm/kvm_main.c29
-rw-r--r--virt/kvm/vfio.c4
5 files changed, 25 insertions, 22 deletions
diff --git a/virt/kvm/coalesced_mmio.c b/virt/kvm/coalesced_mmio.c
index 6855cce3e528..5294abb3f178 100644
--- a/virt/kvm/coalesced_mmio.c
+++ b/virt/kvm/coalesced_mmio.c
@@ -144,7 +144,8 @@ int kvm_vm_ioctl_register_coalesced_mmio(struct kvm *kvm,
144 if (zone->pio != 1 && zone->pio != 0) 144 if (zone->pio != 1 && zone->pio != 0)
145 return -EINVAL; 145 return -EINVAL;
146 146
147 dev = kzalloc(sizeof(struct kvm_coalesced_mmio_dev), GFP_KERNEL); 147 dev = kzalloc(sizeof(struct kvm_coalesced_mmio_dev),
148 GFP_KERNEL_ACCOUNT);
148 if (!dev) 149 if (!dev)
149 return -ENOMEM; 150 return -ENOMEM;
150 151
diff --git a/virt/kvm/eventfd.c b/virt/kvm/eventfd.c
index b20b751286fc..4325250afd72 100644
--- a/virt/kvm/eventfd.c
+++ b/virt/kvm/eventfd.c
@@ -297,7 +297,7 @@ kvm_irqfd_assign(struct kvm *kvm, struct kvm_irqfd *args)
297 if (!kvm_arch_intc_initialized(kvm)) 297 if (!kvm_arch_intc_initialized(kvm))
298 return -EAGAIN; 298 return -EAGAIN;
299 299
300 irqfd = kzalloc(sizeof(*irqfd), GFP_KERNEL); 300 irqfd = kzalloc(sizeof(*irqfd), GFP_KERNEL_ACCOUNT);
301 if (!irqfd) 301 if (!irqfd)
302 return -ENOMEM; 302 return -ENOMEM;
303 303
@@ -345,7 +345,8 @@ kvm_irqfd_assign(struct kvm *kvm, struct kvm_irqfd *args)
345 } 345 }
346 346
347 if (!irqfd->resampler) { 347 if (!irqfd->resampler) {
348 resampler = kzalloc(sizeof(*resampler), GFP_KERNEL); 348 resampler = kzalloc(sizeof(*resampler),
349 GFP_KERNEL_ACCOUNT);
349 if (!resampler) { 350 if (!resampler) {
350 ret = -ENOMEM; 351 ret = -ENOMEM;
351 mutex_unlock(&kvm->irqfds.resampler_lock); 352 mutex_unlock(&kvm->irqfds.resampler_lock);
@@ -797,7 +798,7 @@ static int kvm_assign_ioeventfd_idx(struct kvm *kvm,
797 if (IS_ERR(eventfd)) 798 if (IS_ERR(eventfd))
798 return PTR_ERR(eventfd); 799 return PTR_ERR(eventfd);
799 800
800 p = kzalloc(sizeof(*p), GFP_KERNEL); 801 p = kzalloc(sizeof(*p), GFP_KERNEL_ACCOUNT);
801 if (!p) { 802 if (!p) {
802 ret = -ENOMEM; 803 ret = -ENOMEM;
803 goto fail; 804 goto fail;
diff --git a/virt/kvm/irqchip.c b/virt/kvm/irqchip.c
index b1286c4e0712..3547b0d8c91e 100644
--- a/virt/kvm/irqchip.c
+++ b/virt/kvm/irqchip.c
@@ -196,7 +196,7 @@ int kvm_set_irq_routing(struct kvm *kvm,
196 nr_rt_entries += 1; 196 nr_rt_entries += 1;
197 197
198 new = kzalloc(sizeof(*new) + (nr_rt_entries * sizeof(struct hlist_head)), 198 new = kzalloc(sizeof(*new) + (nr_rt_entries * sizeof(struct hlist_head)),
199 GFP_KERNEL); 199 GFP_KERNEL_ACCOUNT);
200 200
201 if (!new) 201 if (!new)
202 return -ENOMEM; 202 return -ENOMEM;
@@ -208,7 +208,7 @@ int kvm_set_irq_routing(struct kvm *kvm,
208 208
209 for (i = 0; i < nr; ++i) { 209 for (i = 0; i < nr; ++i) {
210 r = -ENOMEM; 210 r = -ENOMEM;
211 e = kzalloc(sizeof(*e), GFP_KERNEL); 211 e = kzalloc(sizeof(*e), GFP_KERNEL_ACCOUNT);
212 if (!e) 212 if (!e)
213 goto out; 213 goto out;
214 214
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 791ced69dd0b..0a0ea8f4bb1b 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -525,7 +525,7 @@ static struct kvm_memslots *kvm_alloc_memslots(void)
525 int i; 525 int i;
526 struct kvm_memslots *slots; 526 struct kvm_memslots *slots;
527 527
528 slots = kvzalloc(sizeof(struct kvm_memslots), GFP_KERNEL); 528 slots = kvzalloc(sizeof(struct kvm_memslots), GFP_KERNEL_ACCOUNT);
529 if (!slots) 529 if (!slots)
530 return NULL; 530 return NULL;
531 531
@@ -601,12 +601,12 @@ static int kvm_create_vm_debugfs(struct kvm *kvm, int fd)
601 601
602 kvm->debugfs_stat_data = kcalloc(kvm_debugfs_num_entries, 602 kvm->debugfs_stat_data = kcalloc(kvm_debugfs_num_entries,
603 sizeof(*kvm->debugfs_stat_data), 603 sizeof(*kvm->debugfs_stat_data),
604 GFP_KERNEL); 604 GFP_KERNEL_ACCOUNT);
605 if (!kvm->debugfs_stat_data) 605 if (!kvm->debugfs_stat_data)
606 return -ENOMEM; 606 return -ENOMEM;
607 607
608 for (p = debugfs_entries; p->name; p++) { 608 for (p = debugfs_entries; p->name; p++) {
609 stat_data = kzalloc(sizeof(*stat_data), GFP_KERNEL); 609 stat_data = kzalloc(sizeof(*stat_data), GFP_KERNEL_ACCOUNT);
610 if (!stat_data) 610 if (!stat_data)
611 return -ENOMEM; 611 return -ENOMEM;
612 612
@@ -671,7 +671,7 @@ static struct kvm *kvm_create_vm(unsigned long type)
671 goto out_err_no_irq_srcu; 671 goto out_err_no_irq_srcu;
672 for (i = 0; i < KVM_NR_BUSES; i++) { 672 for (i = 0; i < KVM_NR_BUSES; i++) {
673 rcu_assign_pointer(kvm->buses[i], 673 rcu_assign_pointer(kvm->buses[i],
674 kzalloc(sizeof(struct kvm_io_bus), GFP_KERNEL)); 674 kzalloc(sizeof(struct kvm_io_bus), GFP_KERNEL_ACCOUNT));
675 if (!kvm->buses[i]) 675 if (!kvm->buses[i])
676 goto out_err; 676 goto out_err;
677 } 677 }
@@ -789,7 +789,7 @@ static int kvm_create_dirty_bitmap(struct kvm_memory_slot *memslot)
789{ 789{
790 unsigned long dirty_bytes = 2 * kvm_dirty_bitmap_bytes(memslot); 790 unsigned long dirty_bytes = 2 * kvm_dirty_bitmap_bytes(memslot);
791 791
792 memslot->dirty_bitmap = kvzalloc(dirty_bytes, GFP_KERNEL); 792 memslot->dirty_bitmap = kvzalloc(dirty_bytes, GFP_KERNEL_ACCOUNT);
793 if (!memslot->dirty_bitmap) 793 if (!memslot->dirty_bitmap)
794 return -ENOMEM; 794 return -ENOMEM;
795 795
@@ -1018,7 +1018,7 @@ int __kvm_set_memory_region(struct kvm *kvm,
1018 goto out_free; 1018 goto out_free;
1019 } 1019 }
1020 1020
1021 slots = kvzalloc(sizeof(struct kvm_memslots), GFP_KERNEL); 1021 slots = kvzalloc(sizeof(struct kvm_memslots), GFP_KERNEL_ACCOUNT);
1022 if (!slots) 1022 if (!slots)
1023 goto out_free; 1023 goto out_free;
1024 memcpy(slots, __kvm_memslots(kvm, as_id), sizeof(struct kvm_memslots)); 1024 memcpy(slots, __kvm_memslots(kvm, as_id), sizeof(struct kvm_memslots));
@@ -2683,7 +2683,7 @@ static long kvm_vcpu_ioctl(struct file *filp,
2683 struct kvm_regs *kvm_regs; 2683 struct kvm_regs *kvm_regs;
2684 2684
2685 r = -ENOMEM; 2685 r = -ENOMEM;
2686 kvm_regs = kzalloc(sizeof(struct kvm_regs), GFP_KERNEL); 2686 kvm_regs = kzalloc(sizeof(struct kvm_regs), GFP_KERNEL_ACCOUNT);
2687 if (!kvm_regs) 2687 if (!kvm_regs)
2688 goto out; 2688 goto out;
2689 r = kvm_arch_vcpu_ioctl_get_regs(vcpu, kvm_regs); 2689 r = kvm_arch_vcpu_ioctl_get_regs(vcpu, kvm_regs);
@@ -2711,7 +2711,8 @@ out_free1:
2711 break; 2711 break;
2712 } 2712 }
2713 case KVM_GET_SREGS: { 2713 case KVM_GET_SREGS: {
2714 kvm_sregs = kzalloc(sizeof(struct kvm_sregs), GFP_KERNEL); 2714 kvm_sregs = kzalloc(sizeof(struct kvm_sregs),
2715 GFP_KERNEL_ACCOUNT);
2715 r = -ENOMEM; 2716 r = -ENOMEM;
2716 if (!kvm_sregs) 2717 if (!kvm_sregs)
2717 goto out; 2718 goto out;
@@ -2803,7 +2804,7 @@ out_free1:
2803 break; 2804 break;
2804 } 2805 }
2805 case KVM_GET_FPU: { 2806 case KVM_GET_FPU: {
2806 fpu = kzalloc(sizeof(struct kvm_fpu), GFP_KERNEL); 2807 fpu = kzalloc(sizeof(struct kvm_fpu), GFP_KERNEL_ACCOUNT);
2807 r = -ENOMEM; 2808 r = -ENOMEM;
2808 if (!fpu) 2809 if (!fpu)
2809 goto out; 2810 goto out;
@@ -2980,7 +2981,7 @@ static int kvm_ioctl_create_device(struct kvm *kvm,
2980 if (test) 2981 if (test)
2981 return 0; 2982 return 0;
2982 2983
2983 dev = kzalloc(sizeof(*dev), GFP_KERNEL); 2984 dev = kzalloc(sizeof(*dev), GFP_KERNEL_ACCOUNT);
2984 if (!dev) 2985 if (!dev)
2985 return -ENOMEM; 2986 return -ENOMEM;
2986 2987
@@ -3715,7 +3716,7 @@ int kvm_io_bus_register_dev(struct kvm *kvm, enum kvm_bus bus_idx, gpa_t addr,
3715 return -ENOSPC; 3716 return -ENOSPC;
3716 3717
3717 new_bus = kmalloc(struct_size(bus, range, bus->dev_count + 1), 3718 new_bus = kmalloc(struct_size(bus, range, bus->dev_count + 1),
3718 GFP_KERNEL); 3719 GFP_KERNEL_ACCOUNT);
3719 if (!new_bus) 3720 if (!new_bus)
3720 return -ENOMEM; 3721 return -ENOMEM;
3721 3722
@@ -3761,7 +3762,7 @@ void kvm_io_bus_unregister_dev(struct kvm *kvm, enum kvm_bus bus_idx,
3761 return; 3762 return;
3762 3763
3763 new_bus = kmalloc(struct_size(bus, range, bus->dev_count - 1), 3764 new_bus = kmalloc(struct_size(bus, range, bus->dev_count - 1),
3764 GFP_KERNEL); 3765 GFP_KERNEL_ACCOUNT);
3765 if (!new_bus) { 3766 if (!new_bus) {
3766 pr_err("kvm: failed to shrink bus, removing it completely\n"); 3767 pr_err("kvm: failed to shrink bus, removing it completely\n");
3767 goto broken; 3768 goto broken;
@@ -4029,7 +4030,7 @@ static void kvm_uevent_notify_change(unsigned int type, struct kvm *kvm)
4029 active = kvm_active_vms; 4030 active = kvm_active_vms;
4030 spin_unlock(&kvm_lock); 4031 spin_unlock(&kvm_lock);
4031 4032
4032 env = kzalloc(sizeof(*env), GFP_KERNEL); 4033 env = kzalloc(sizeof(*env), GFP_KERNEL_ACCOUNT);
4033 if (!env) 4034 if (!env)
4034 return; 4035 return;
4035 4036
@@ -4045,7 +4046,7 @@ static void kvm_uevent_notify_change(unsigned int type, struct kvm *kvm)
4045 add_uevent_var(env, "PID=%d", kvm->userspace_pid); 4046 add_uevent_var(env, "PID=%d", kvm->userspace_pid);
4046 4047
4047 if (kvm->debugfs_dentry) { 4048 if (kvm->debugfs_dentry) {
4048 char *tmp, *p = kmalloc(PATH_MAX, GFP_KERNEL); 4049 char *tmp, *p = kmalloc(PATH_MAX, GFP_KERNEL_ACCOUNT);
4049 4050
4050 if (p) { 4051 if (p) {
4051 tmp = dentry_path_raw(kvm->debugfs_dentry, p, PATH_MAX); 4052 tmp = dentry_path_raw(kvm->debugfs_dentry, p, PATH_MAX);
diff --git a/virt/kvm/vfio.c b/virt/kvm/vfio.c
index d99850c462a1..524cbd20379f 100644
--- a/virt/kvm/vfio.c
+++ b/virt/kvm/vfio.c
@@ -219,7 +219,7 @@ static int kvm_vfio_set_group(struct kvm_device *dev, long attr, u64 arg)
219 } 219 }
220 } 220 }
221 221
222 kvg = kzalloc(sizeof(*kvg), GFP_KERNEL); 222 kvg = kzalloc(sizeof(*kvg), GFP_KERNEL_ACCOUNT);
223 if (!kvg) { 223 if (!kvg) {
224 mutex_unlock(&kv->lock); 224 mutex_unlock(&kv->lock);
225 kvm_vfio_group_put_external_user(vfio_group); 225 kvm_vfio_group_put_external_user(vfio_group);
@@ -405,7 +405,7 @@ static int kvm_vfio_create(struct kvm_device *dev, u32 type)
405 if (tmp->ops == &kvm_vfio_ops) 405 if (tmp->ops == &kvm_vfio_ops)
406 return -EBUSY; 406 return -EBUSY;
407 407
408 kv = kzalloc(sizeof(*kv), GFP_KERNEL); 408 kv = kzalloc(sizeof(*kv), GFP_KERNEL_ACCOUNT);
409 if (!kv) 409 if (!kv)
410 return -ENOMEM; 410 return -ENOMEM;
411 411