linux/virt/kvm
Paolo Bonzini 91248a2e41 KVM: x86: switch hugepage recovery thread to vhost_task
commit d96c77bd4e upstream.

kvm_vm_create_worker_thread() is meant to be used for kthreads that
can consume significant amounts of CPU time on behalf of a VM or in
response to how the VM behaves (for example how it accesses its memory).
Therefore it wants to charge the CPU time consumed by that work to
the VM's container.

However, because of these threads, cgroups which have kvm instances
inside never complete freezing.  This can be trivially reproduced:

  root@test ~# mkdir /sys/fs/cgroup/test
  root@test ~# echo $$ > /sys/fs/cgroup/test/cgroup.procs
  root@test ~# qemu-system-x86_64 -nographic -enable-kvm

and in another terminal:

  root@test ~# echo 1 > /sys/fs/cgroup/test/cgroup.freeze
  root@test ~# cat /sys/fs/cgroup/test/cgroup.events
  populated 1
  frozen 0

The cgroup freezing happens in the signal delivery path but
kvm_nx_huge_page_recovery_worker, while joining non-root cgroups, never
calls into the signal delivery path and thus never gets frozen. Because
the cgroup freezer determines whether a given cgroup is frozen by
comparing the number of frozen threads to the total number of threads
in the cgroup, the cgroup never becomes frozen and users waiting for
the state transition may hang indefinitely.

Since the worker kthread is tied to a user process, it's better if
it behaves similarly to user tasks as much as possible, including
being able to send SIGSTOP and SIGCONT.  In fact, vhost_task is all
that kvm_vm_create_worker_thread() wanted to be and more: not only it
inherits the userspace process's cgroups, it has other niceties like
being parented properly in the process tree.  Use it instead of the
homegrown alternative.

Incidentally, the new code is also better behaved when you flip recovery
back and forth to disabled and back to enabled.  If your recovery period
is 1 minute, it will run the next recovery after 1 minute independent
of how many times you flipped the parameter.

(Commit message based on emails from Tejun).

Reported-by: Tejun Heo <tj@kernel.org>
Reported-by: Luca Boccassi <bluca@debian.org>
Acked-by: Tejun Heo <tj@kernel.org>
Tested-by: Luca Boccassi <bluca@debian.org>
Cc: stable@vger.kernel.org
Reviewed-by: Sean Christopherson <seanjc@google.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
History 2024-12-05 14:02:43 +01:00
..
async_pf.c Revert "KVM: async_pf: avoid recursive flushing of work items" 2024-06-03 08:55:55 -07:00
async_pf.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 504 2019-06-19 17:09:56 +02:00
binary_stats.c KVM: stats: remove dead stores 2021-08-13 03:35:15 -04:00
coalesced_mmio.c KVM: Clean up coalesced MMIO ring full check 2024-08-29 19:38:33 -07:00
coalesced_mmio.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
dirty_ring.c KVM: Discard zero mask with function kvm_dirty_ring_reset 2024-06-20 17:20:11 -04:00
eventfd.c struct fd layout change (and conversion to accessor helpers) 2024-09-23 09:35:36 -07:00
guest_memfd.c KVM: guest_memfd: abstract how prepared folios are recorded 2024-07-26 14:46:15 -04:00
irqchip.c KVM: Setup empty IRQ routing when creating a VM 2024-06-11 14:18:34 -07:00
Kconfig KVM: rename CONFIG_HAVE_KVM_GMEM_* to CONFIG_HAVE_KVM_ARCH_GMEM_* 2024-07-26 14:46:14 -04:00
kvm_main.c KVM: x86: switch hugepage recovery thread to vhost_task 2024-12-05 14:02:43 +01:00
kvm_mm.h KVM: Drop unused @may_block param from gfn_to_pfn_cache_invalidate_start() 2024-04-11 12:58:53 -07:00
Makefile.kvm KVM: Add KVM_CREATE_GUEST_MEMFD ioctl() for guest-specific backing memory 2023-11-14 08:01:03 -05:00
pfncache.c KVM: Validate hva in kvm_gpc_activate_hva() to fix __kvm_gpc_refresh() WARN 2024-06-28 08:31:46 -07:00
vfio.c introduce fd_file(), convert all accessors to it. 2024-08-12 22:00:43 -04:00
vfio.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00