The directory under /sys/kernel/debug/kvm is named <pid>-<fd>, but is removed only together with the VM. A VM can outlive its fd: VFIO keeps a reference to it for an open passthrough device, and QEMU's cpr-exec closes the fd and creates a new VM in the same process, often on the same fd number. The new VM then finds its directory taken, logs "duplicate directory" and runs without debugfs stats. Seen on every other live update of a vGPU VM.
Remove only the directory when the fd is released: the name belongs to the fd, which is free to reuse from then on. The stat data stays until kvm_destroy_vm(): an open stat file reaches it through the inode at release, which debugfs runs even after the file was removed. Two things change with that: the destroy uevent no longer carries STATS_PATH, and a VM that lives on after its fd on the vcpu fds has no stats directory for that time. https://virtuozzo.atlassian.net/browse/VSTOR-150597 Feature: fix ms/kvm Assisted-by: LLM Signed-off-by: Andrey Drobyshev <[email protected]> --- virt/kvm/kvm_main.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 8d92a649c063..9a0ee933a6a3 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -995,21 +995,28 @@ static umode_t kvm_stats_debugfs_mode(const struct _kvm_stats_desc *pdesc) } +static void kvm_remove_vm_debugfs(struct kvm *kvm) +{ + if (IS_ERR(kvm->debugfs_dentry)) + return; + + debugfs_remove_recursive(kvm->debugfs_dentry); + kvm->debugfs_dentry = ERR_PTR(-ENOENT); +} + static void kvm_destroy_vm_debugfs(struct kvm *kvm) { int i; int kvm_debugfs_num_entries = kvm_vm_stats_header.num_desc + kvm_vcpu_stats_header.num_desc; - if (IS_ERR(kvm->debugfs_dentry)) - return; - - debugfs_remove_recursive(kvm->debugfs_dentry); + kvm_remove_vm_debugfs(kvm); if (kvm->debugfs_stat_data) { for (i = 0; i < kvm_debugfs_num_entries; i++) kfree(kvm->debugfs_stat_data[i]); kfree(kvm->debugfs_stat_data); + kvm->debugfs_stat_data = NULL; } } @@ -1364,6 +1371,9 @@ static int kvm_vm_release(struct inode *inode, struct file *filp) kvm_irqfd_release(kvm); + /* The directory is named after this fd, which is free to reuse now */ + kvm_remove_vm_debugfs(kvm); + kvm_put_kvm(kvm); return 0; } -- 2.47.1 _______________________________________________ Devel mailing list [email protected] https://lists.openvz.org/mailman/listinfo/devel
