Re: [RFC PATCH v1 09/37] KVM: guest_memfd: Skip LRU for guest_memfd folios
From: Yan Zhao <hidden>
Date: 2026-01-20 02:18:30
Also in:
cgroups, kvm, linux-doc, linux-fsdevel, linux-kselftest, linux-mm, lkml
+static struct folio *__kvm_gmem_get_folio(struct address_space *mapping,
+ pgoff_t index,
+ struct mempolicy *policy)
+{
+ const gfp_t gfp = mapping_gfp_mask(mapping);
+ struct folio *folio;
+ int err;
+
+ folio = filemap_lock_folio(mapping, index);
+ if (!IS_ERR(folio))
+ return folio;
+
+ folio = filemap_alloc_folio(gfp, 0, policy);
+ if (!folio)
+ return ERR_PTR(-ENOMEM);
+
+ err = mem_cgroup_charge(folio, NULL, gfp);
+ if (err)
+ goto err_put;
+
+ __folio_set_locked(folio);
+
+ err = __filemap_add_folio(mapping, folio, index, gfp, NULL);
+ if (err) {mem_cgroup_uncharge(folio);
quoted hunk ↗ jump to hunk
+ __folio_clear_locked(folio); + goto err_put; + } + + return folio; + +err_put: + folio_put(folio); + return ERR_PTR(err); +} + /* * Returns a locked folio on success. The caller is responsible for * setting the up-to-date flag before the memory is mapped into the guest.@@ -160,6 +195,7 @@ static struct mempolicy *kvm_gmem_get_folio_policy(struct gmem_inode *gi, static struct folio *kvm_gmem_get_folio(struct inode *inode, pgoff_t index) { /* TODO: Support huge pages. */ + struct address_space *mapping = inode->i_mapping; struct mempolicy *policy; struct folio *folio;@@ -167,16 +203,17 @@ static struct folio *kvm_gmem_get_folio(struct inode *inode, pgoff_t index) * Fast-path: See if folio is already present in mapping to avoid * policy_lookup. */ - folio = filemap_lock_folio(inode->i_mapping, index); + folio = filemap_lock_folio(mapping, index); if (!IS_ERR(folio)) return folio; policy = kvm_gmem_get_folio_policy(GMEM_I(inode), index); - folio = __filemap_get_folio_mpol(inode->i_mapping, index, - FGP_LOCK | FGP_CREAT, - mapping_gfp_mask(inode->i_mapping), policy); - mpol_cond_put(policy); + do { + folio = __kvm_gmem_get_folio(mapping, index, policy); + } while (IS_ERR(folio) && PTR_ERR(folio) == -EEXIST);
Why not just return ERR_PTR(-EEXIST) up to kvm_gmem_get_pfn() and have a higher level retry?
+ mpol_cond_put(policy); return folio; }