[PATCH RFC v2 01/50] KVM: guest_memfd: Split folio allocation and insertion in kvm_gmem_get_folio
From: Ackerley Tng via B4 Relay
Date: Thu Oct 22 2026 - 19:27:57 EST
From: Ackerley Tng <ackerleytng@xxxxxxxxxx>
Separate __filemap_get_folio_mpol() call in kvm_gmem_get_folio() into two
distinct steps:
1. Allocating a folio via filemap_alloc_folio() with the NUMA policy.
2. Inserting the allocated folio into the inode filemap.
Handle -EEXIST from filemap_add_folio() by retrying filemap_lock_folio()
safely to manage concurrent insertions.
Decouple folio allocation from filemap insertion to prepare for supporting
other memory providers.
No functional change intended.
Signed-off-by: Ackerley Tng <ackerleytng@xxxxxxxxxx>
---
virt/kvm/guest_memfd.c | 19 +++++++++++++++----
1 file changed, 15 insertions(+), 4 deletions(-)
diff --git a/virt/kvm/guest_memfd.c b/virt/kvm/guest_memfd.c
index 93f3d29d5751a..f865fa0e46840 100644
--- a/virt/kvm/guest_memfd.c
+++ b/virt/kvm/guest_memfd.c
@@ -131,7 +131,9 @@ static struct folio *kvm_gmem_get_folio(struct inode *inode, pgoff_t index)
/* TODO: Support huge pages. */
struct mempolicy *policy;
struct folio *folio;
+ int r;
+retry:
/*
* Fast-path: See if folio is already present in mapping to avoid
* policy_lookup.
@@ -141,10 +143,19 @@ static struct folio *kvm_gmem_get_folio(struct inode *inode, pgoff_t index)
return folio;
policy = mpol_shared_policy_lookup(&GMEM_I(inode)->policy, index);
- folio = __filemap_get_folio_mpol(inode->i_mapping, index,
- FGP_LOCK | FGP_CREAT,
- mapping_gfp_mask(inode->i_mapping), policy);
+ folio = filemap_alloc_folio(mapping_gfp_mask(inode->i_mapping), 0,
+ policy);
mpol_cond_put(policy);
+ if (!folio)
+ return ERR_PTR(-ENOMEM);
+
+ r = filemap_add_folio(inode->i_mapping, folio, index, GFP_KERNEL);
+ if (r) {
+ folio_put(folio);
+ if (r == -EEXIST)
+ goto retry;
+ return ERR_PTR(r);
+ }
/*
* External interfaces like kvm_gmem_get_pfn() support dealing
@@ -153,7 +164,7 @@ static struct folio *kvm_gmem_get_folio(struct inode *inode, pgoff_t index)
* to be updated for anything otherwise (e.g. page-clearing
* operations).
*/
- WARN_ON_ONCE(!IS_ERR(folio) && folio_order(folio));
+ WARN_ON_ONCE(folio_order(folio));
return folio;
}
--
2.56.0.257.gf7497c7d27-goog