[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[RFC PATCH 14/19] KVM: guest_mem: Refactor cleanup to separate inode and
From: |
Ackerley Tng |
Subject: |
[RFC PATCH 14/19] KVM: guest_mem: Refactor cleanup to separate inode and file cleanup |
Date: |
Tue, 6 Jun 2023 19:03:59 +0000 |
Cleanup in kvm_gmem_release() should be the reverse of
kvm_gmem_create_file().
Cleanup in kvm_gmem_evict_inode() should be the reverse of
kvm_gmem_create_inode().
Signed-off-by: Ackerley Tng <ackerleytng@google.com>
---
virt/kvm/guest_mem.c | 105 +++++++++++++++++++++++++++++--------------
1 file changed, 71 insertions(+), 34 deletions(-)
diff --git a/virt/kvm/guest_mem.c b/virt/kvm/guest_mem.c
index 2f69ef666871..13253af40be6 100644
--- a/virt/kvm/guest_mem.c
+++ b/virt/kvm/guest_mem.c
@@ -247,42 +247,13 @@ static long kvm_gmem_fallocate(struct file *file, int
mode, loff_t offset,
static int kvm_gmem_release(struct inode *inode, struct file *file)
{
- struct kvm_gmem *gmem = inode->i_mapping->private_data;
- struct kvm_memory_slot *slot;
- struct kvm *kvm = gmem->kvm;
- unsigned long index;
-
/*
- * Prevent concurrent attempts to *unbind* a memslot. This is the last
- * reference to the file and thus no new bindings can be created, but
- * deferencing the slot for existing bindings needs to be protected
- * against memslot updates, specifically so that unbind doesn't race
- * and free the memslot (kvm_gmem_get_file() will return NULL).
+ * This is called when the last reference to the file is released. Only
+ * clean up file-related stuff. struct kvm_gmem is also referred to in
+ * the inode, so clean that up in kvm_gmem_evict_inode().
*/
- mutex_lock(&kvm->slots_lock);
-
- xa_for_each(&gmem->bindings, index, slot)
- rcu_assign_pointer(slot->gmem.file, NULL);
-
- synchronize_rcu();
-
- /*
- * All in-flight operations are gone and new bindings can be created.
- * Free the backing memory, and more importantly, zap all SPTEs that
- * pointed at this file.
- */
- kvm_gmem_invalidate_begin(kvm, gmem, 0, -1ul);
- truncate_inode_pages_final(file->f_mapping);
- kvm_gmem_invalidate_end(kvm, gmem, 0, -1ul);
-
- mutex_unlock(&kvm->slots_lock);
-
- WARN_ON_ONCE(!(mapping_empty(file->f_mapping)));
-
- xa_destroy(&gmem->bindings);
- kfree(gmem);
-
- kvm_put_kvm(kvm);
+ file->f_mapping = NULL;
+ file->private_data = NULL;
return 0;
}
@@ -603,11 +574,77 @@ int kvm_gmem_get_pfn(struct kvm *kvm, struct
kvm_memory_slot *slot,
}
EXPORT_SYMBOL_GPL(kvm_gmem_get_pfn);
+static void kvm_gmem_evict_inode(struct inode *inode)
+{
+ struct kvm_gmem *gmem = inode->i_mapping->private_data;
+ struct kvm_memory_slot *slot;
+ struct kvm *kvm;
+ unsigned long index;
+
+ /*
+ * If iput() was called before inode is completely set up due to some
+ * error in kvm_gmem_create_inode(), gmem will be NULL.
+ */
+ if (!gmem)
+ goto basic_cleanup;
+
+ kvm = gmem->kvm;
+
+ /*
+ * Prevent concurrent attempts to *unbind* a memslot. This is the last
+ * reference to the file and thus no new bindings can be created, but
+ * deferencing the slot for existing bindings needs to be protected
+ * against memslot updates, specifically so that unbind doesn't race
+ * and free the memslot (kvm_gmem_get_file() will return NULL).
+ */
+ mutex_lock(&kvm->slots_lock);
+
+ xa_for_each(&gmem->bindings, index, slot)
+ rcu_assign_pointer(slot->gmem.file, NULL);
+
+ synchronize_rcu();
+
+ /*
+ * All in-flight operations are gone and new bindings can be created.
+ * Free the backing memory, and more importantly, zap all SPTEs that
+ * pointed at this file.
+ */
+ kvm_gmem_invalidate_begin(kvm, gmem, 0, -1ul);
+ truncate_inode_pages_final(inode->i_mapping);
+ kvm_gmem_invalidate_end(kvm, gmem, 0, -1ul);
+
+ mutex_unlock(&kvm->slots_lock);
+
+ WARN_ON_ONCE(!(mapping_empty(inode->i_mapping)));
+
+ xa_destroy(&gmem->bindings);
+ kfree(gmem);
+
+ kvm_put_kvm(kvm);
+
+basic_cleanup:
+ clear_inode(inode);
+}
+
+static const struct super_operations kvm_gmem_super_operations = {
+ /*
+ * TODO update statfs handler for kvm_gmem. What should the statfs
+ * handler return?
+ */
+ .statfs = simple_statfs,
+ .evict_inode = kvm_gmem_evict_inode,
+};
+
static int kvm_gmem_init_fs_context(struct fs_context *fc)
{
+ struct pseudo_fs_context *ctx;
+
if (!init_pseudo(fc, GUEST_MEMORY_MAGIC))
return -ENOMEM;
+ ctx = fc->fs_private;
+ ctx->ops = &kvm_gmem_super_operations;
+
return 0;
}
--
2.41.0.rc0.172.g3f132b7071-goog
- [RFC PATCH 04/19] mm: hugetlb: Decouple hstate, subpool from inode, (continued)
- [RFC PATCH 04/19] mm: hugetlb: Decouple hstate, subpool from inode, Ackerley Tng, 2023/06/06
- [RFC PATCH 05/19] mm: hugetlb: Allow alloc_hugetlb_folio() to be parametrized by subpool and hstate, Ackerley Tng, 2023/06/06
- [RFC PATCH 06/19] mm: hugetlb: Provide hugetlb_filemap_add_folio(), Ackerley Tng, 2023/06/06
- [RFC PATCH 08/19] mm: hugetlb: Refactor restore_reserve_on_error, Ackerley Tng, 2023/06/06
- [RFC PATCH 07/19] mm: hugetlb: Refactor vma_*_reservation functions, Ackerley Tng, 2023/06/06
- [RFC PATCH 09/19] mm: hugetlb: Use restore_reserve_on_error directly in filesystems, Ackerley Tng, 2023/06/06
- [RFC PATCH 10/19] mm: hugetlb: Parametrize alloc_hugetlb_folio_from_subpool() by resv_map, Ackerley Tng, 2023/06/06
- [RFC PATCH 11/19] mm: hugetlb: Parametrize hugetlb functions by resv_map, Ackerley Tng, 2023/06/06
- [RFC PATCH 12/19] mm: truncate: Expose preparation steps for truncate_inode_pages_final, Ackerley Tng, 2023/06/06
- [RFC PATCH 13/19] KVM: guest_mem: Refactor kvm_gmem fd creation to be in layers, Ackerley Tng, 2023/06/06
- [RFC PATCH 14/19] KVM: guest_mem: Refactor cleanup to separate inode and file cleanup,
Ackerley Tng <=
- [RFC PATCH 15/19] KVM: guest_mem: hugetlb: initialization and cleanup, Ackerley Tng, 2023/06/06
- [RFC PATCH 16/19] KVM: guest_mem: hugetlb: allocate and truncate from hugetlb, Ackerley Tng, 2023/06/06
- [RFC PATCH 17/19] KVM: selftests: Add basic selftests for hugetlbfs-backed guest_mem, Ackerley Tng, 2023/06/06
- [RFC PATCH 18/19] KVM: selftests: Support various types of backing sources for private memory, Ackerley Tng, 2023/06/06
- [RFC PATCH 19/19] KVM: selftests: Update test for various private memory backing source types, Ackerley Tng, 2023/06/06
- Re: [RFC PATCH 00/19] hugetlb support for KVM guest_mem, Isaku Yamahata, 2023/06/08
- Re: [RFC PATCH 00/19] hugetlb support for KVM guest_mem, Mike Kravetz, 2023/06/16