[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <a7a0eb4053059731f70c18d4aa4736b6cf1b4e35.1747264138.git.ackerleytng@google.com>
Date: Wed, 14 May 2025 16:42:16 -0700
From: Ackerley Tng <ackerleytng@...gle.com>
To: kvm@...r.kernel.org, linux-mm@...ck.org, linux-kernel@...r.kernel.org,
x86@...nel.org, linux-fsdevel@...r.kernel.org
Cc: ackerleytng@...gle.com, aik@....com, ajones@...tanamicro.com,
akpm@...ux-foundation.org, amoorthy@...gle.com, anthony.yznaga@...cle.com,
anup@...infault.org, aou@...s.berkeley.edu, bfoster@...hat.com,
binbin.wu@...ux.intel.com, brauner@...nel.org, catalin.marinas@....com,
chao.p.peng@...el.com, chenhuacai@...nel.org, dave.hansen@...el.com,
david@...hat.com, dmatlack@...gle.com, dwmw@...zon.co.uk,
erdemaktas@...gle.com, fan.du@...el.com, fvdl@...gle.com, graf@...zon.com,
haibo1.xu@...el.com, hch@...radead.org, hughd@...gle.com, ira.weiny@...el.com,
isaku.yamahata@...el.com, jack@...e.cz, james.morse@....com,
jarkko@...nel.org, jgg@...pe.ca, jgowans@...zon.com, jhubbard@...dia.com,
jroedel@...e.de, jthoughton@...gle.com, jun.miao@...el.com,
kai.huang@...el.com, keirf@...gle.com, kent.overstreet@...ux.dev,
kirill.shutemov@...el.com, liam.merwick@...cle.com,
maciej.wieczor-retman@...el.com, mail@...iej.szmigiero.name, maz@...nel.org,
mic@...ikod.net, michael.roth@....com, mpe@...erman.id.au,
muchun.song@...ux.dev, nikunj@....com, nsaenz@...zon.es,
oliver.upton@...ux.dev, palmer@...belt.com, pankaj.gupta@....com,
paul.walmsley@...ive.com, pbonzini@...hat.com, pdurrant@...zon.co.uk,
peterx@...hat.com, pgonda@...gle.com, pvorel@...e.cz, qperret@...gle.com,
quic_cvanscha@...cinc.com, quic_eberman@...cinc.com,
quic_mnalajal@...cinc.com, quic_pderrin@...cinc.com, quic_pheragu@...cinc.com,
quic_svaddagi@...cinc.com, quic_tsoni@...cinc.com, richard.weiyang@...il.com,
rick.p.edgecombe@...el.com, rientjes@...gle.com, roypat@...zon.co.uk,
rppt@...nel.org, seanjc@...gle.com, shuah@...nel.org, steven.price@....com,
steven.sistare@...cle.com, suzuki.poulose@....com, tabba@...gle.com,
thomas.lendacky@....com, usama.arif@...edance.com, vannapurve@...gle.com,
vbabka@...e.cz, viro@...iv.linux.org.uk, vkuznets@...hat.com,
wei.w.wang@...el.com, will@...nel.org, willy@...radead.org,
xiaoyao.li@...el.com, yan.y.zhao@...el.com, yilun.xu@...el.com,
yuzenghui@...wei.com, zhiquan1.li@...el.com, Mike Day <michael.day@....com>
Subject: [RFC PATCH v2 37/51] filemap: Pass address_space mapping to ->free_folio()
From: Elliot Berman <quic_eberman@...cinc.com>
The plan is to be able to support multiple allocators for guest_memfd
folios. To allow each allocator to handle release of a folio from a
guest_memfd filemap, ->free_folio() needs to retrieve allocator
information that is stored on the guest_memfd inode.
->free_folio() shouldn't assume that folio->mapping is set/valid, and
the mapping is well-known to callers of .free_folio(). Hence, pass
address_space mapping to ->free_folio() for the callback to retrieve
any necessary information.
Link: https://lore.kernel.org/all/15f665b4-2d33-41ca-ac50-fafe24ade32f@redhat.com/
Suggested-by: David Hildenbrand <david@...hat.com>
Acked-by: David Hildenbrand <david@...hat.com>
Change-Id: I8bac907832a0b2491fa403a6ab72fcef1b4713ee
Signed-off-by: Elliot Berman <quic_eberman@...cinc.com>
Tested-by: Mike Day <michael.day@....com>
Signed-off-by: Ackerley Tng <ackerleytng@...gle.com>
---
Documentation/filesystems/locking.rst | 2 +-
Documentation/filesystems/vfs.rst | 15 +++++++++------
fs/nfs/dir.c | 9 +++++++--
fs/orangefs/inode.c | 3 ++-
include/linux/fs.h | 2 +-
mm/filemap.c | 9 +++++----
mm/secretmem.c | 3 ++-
mm/vmscan.c | 4 ++--
virt/kvm/guest_memfd.c | 3 ++-
9 files changed, 31 insertions(+), 19 deletions(-)
diff --git a/Documentation/filesystems/locking.rst b/Documentation/filesystems/locking.rst
index 0ec0bb6eb0fb..c3d7430481ae 100644
--- a/Documentation/filesystems/locking.rst
+++ b/Documentation/filesystems/locking.rst
@@ -263,7 +263,7 @@ prototypes::
sector_t (*bmap)(struct address_space *, sector_t);
void (*invalidate_folio) (struct folio *, size_t start, size_t len);
bool (*release_folio)(struct folio *, gfp_t);
- void (*free_folio)(struct folio *);
+ void (*free_folio)(struct address_space *, struct folio *);
int (*direct_IO)(struct kiocb *, struct iov_iter *iter);
int (*migrate_folio)(struct address_space *, struct folio *dst,
struct folio *src, enum migrate_mode);
diff --git a/Documentation/filesystems/vfs.rst b/Documentation/filesystems/vfs.rst
index ae79c30b6c0c..bba1ac848f96 100644
--- a/Documentation/filesystems/vfs.rst
+++ b/Documentation/filesystems/vfs.rst
@@ -833,7 +833,7 @@ cache in your filesystem. The following members are defined:
sector_t (*bmap)(struct address_space *, sector_t);
void (*invalidate_folio) (struct folio *, size_t start, size_t len);
bool (*release_folio)(struct folio *, gfp_t);
- void (*free_folio)(struct folio *);
+ void (*free_folio)(struct address_space *, struct folio *);
ssize_t (*direct_IO)(struct kiocb *, struct iov_iter *iter);
int (*migrate_folio)(struct mapping *, struct folio *dst,
struct folio *src, enum migrate_mode);
@@ -1011,11 +1011,14 @@ cache in your filesystem. The following members are defined:
clear the uptodate flag if it cannot free private data yet.
``free_folio``
- free_folio is called once the folio is no longer visible in the
- page cache in order to allow the cleanup of any private data.
- Since it may be called by the memory reclaimer, it should not
- assume that the original address_space mapping still exists, and
- it should not block.
+ free_folio is called once the folio is no longer visible in
+ the page cache in order to allow the cleanup of any private
+ data. Since it may be called by the memory reclaimer, it
+ should not assume that the original address_space mapping
+ still exists at folio->mapping. The mapping the folio used to
+ belong to is instead passed for free_folio to read any
+ information it might need from the mapping. free_folio should
+ not block.
``direct_IO``
called by the generic read/write routines to perform direct_IO -
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index bd23fc736b39..148433f6d9d4 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -55,7 +55,7 @@ static int nfs_closedir(struct inode *, struct file *);
static int nfs_readdir(struct file *, struct dir_context *);
static int nfs_fsync_dir(struct file *, loff_t, loff_t, int);
static loff_t nfs_llseek_dir(struct file *, loff_t, int);
-static void nfs_readdir_clear_array(struct folio *);
+static void nfs_free_folio(struct address_space *, struct folio *);
static int nfs_do_create(struct inode *dir, struct dentry *dentry,
umode_t mode, int open_flags);
@@ -69,7 +69,7 @@ const struct file_operations nfs_dir_operations = {
};
const struct address_space_operations nfs_dir_aops = {
- .free_folio = nfs_readdir_clear_array,
+ .free_folio = nfs_free_folio,
};
#define NFS_INIT_DTSIZE PAGE_SIZE
@@ -230,6 +230,11 @@ static void nfs_readdir_clear_array(struct folio *folio)
kunmap_local(array);
}
+static void nfs_free_folio(struct address_space *mapping, struct folio *folio)
+{
+ nfs_readdir_clear_array(folio);
+}
+
static void nfs_readdir_folio_reinit_array(struct folio *folio, u64 last_cookie,
u64 change_attr)
{
diff --git a/fs/orangefs/inode.c b/fs/orangefs/inode.c
index 5ac743c6bc2e..884cc5295f3e 100644
--- a/fs/orangefs/inode.c
+++ b/fs/orangefs/inode.c
@@ -449,7 +449,8 @@ static bool orangefs_release_folio(struct folio *folio, gfp_t foo)
return !folio_test_private(folio);
}
-static void orangefs_free_folio(struct folio *folio)
+static void orangefs_free_folio(struct address_space *mapping,
+ struct folio *folio)
{
kfree(folio_detach_private(folio));
}
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 0fded2e3c661..9862ea92a2af 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -455,7 +455,7 @@ struct address_space_operations {
sector_t (*bmap)(struct address_space *, sector_t);
void (*invalidate_folio) (struct folio *, size_t offset, size_t len);
bool (*release_folio)(struct folio *, gfp_t);
- void (*free_folio)(struct folio *folio);
+ void (*free_folio)(struct address_space *mapping, struct folio *folio);
ssize_t (*direct_IO)(struct kiocb *, struct iov_iter *iter);
/*
* migrate the contents of a folio to the specified target. If
diff --git a/mm/filemap.c b/mm/filemap.c
index bed7160db214..a02c3d8e00e8 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -226,11 +226,11 @@ void __filemap_remove_folio(struct folio *folio, void *shadow)
void filemap_free_folio(struct address_space *mapping, struct folio *folio)
{
- void (*free_folio)(struct folio *);
+ void (*free_folio)(struct address_space*, struct folio *);
free_folio = mapping->a_ops->free_folio;
if (free_folio)
- free_folio(folio);
+ free_folio(mapping, folio);
folio_put_refs(folio, folio_nr_pages(folio));
}
@@ -820,7 +820,8 @@ EXPORT_SYMBOL(file_write_and_wait_range);
void replace_page_cache_folio(struct folio *old, struct folio *new)
{
struct address_space *mapping = old->mapping;
- void (*free_folio)(struct folio *) = mapping->a_ops->free_folio;
+ void (*free_folio)(struct address_space *, struct folio *) =
+ mapping->a_ops->free_folio;
pgoff_t offset = old->index;
XA_STATE(xas, &mapping->i_pages, offset);
@@ -849,7 +850,7 @@ void replace_page_cache_folio(struct folio *old, struct folio *new)
__lruvec_stat_add_folio(new, NR_SHMEM);
xas_unlock_irq(&xas);
if (free_folio)
- free_folio(old);
+ free_folio(mapping, old);
folio_put(old);
}
EXPORT_SYMBOL_GPL(replace_page_cache_folio);
diff --git a/mm/secretmem.c b/mm/secretmem.c
index c0e459e58cb6..178507c1b900 100644
--- a/mm/secretmem.c
+++ b/mm/secretmem.c
@@ -152,7 +152,8 @@ static int secretmem_migrate_folio(struct address_space *mapping,
return -EBUSY;
}
-static void secretmem_free_folio(struct folio *folio)
+static void secretmem_free_folio(struct address_space *mapping,
+ struct folio *folio)
{
set_direct_map_default_noflush(&folio->page);
folio_zero_segment(folio, 0, folio_size(folio));
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 3783e45bfc92..b8add4d0cf18 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -788,7 +788,7 @@ static int __remove_mapping(struct address_space *mapping, struct folio *folio,
xa_unlock_irq(&mapping->i_pages);
put_swap_folio(folio, swap);
} else {
- void (*free_folio)(struct folio *);
+ void (*free_folio)(struct address_space *, struct folio *);
free_folio = mapping->a_ops->free_folio;
/*
@@ -817,7 +817,7 @@ static int __remove_mapping(struct address_space *mapping, struct folio *folio,
spin_unlock(&mapping->host->i_lock);
if (free_folio)
- free_folio(folio);
+ free_folio(mapping, folio);
}
return 1;
diff --git a/virt/kvm/guest_memfd.c b/virt/kvm/guest_memfd.c
index 24d270b9b725..c578d0ebe314 100644
--- a/virt/kvm/guest_memfd.c
+++ b/virt/kvm/guest_memfd.c
@@ -1319,7 +1319,8 @@ static void kvm_gmem_invalidate(struct folio *folio)
static inline void kvm_gmem_invalidate(struct folio *folio) {}
#endif
-static void kvm_gmem_free_folio(struct folio *folio)
+static void kvm_gmem_free_folio(struct address_space *mapping,
+ struct folio *folio)
{
folio_clear_unevictable(folio);
--
2.49.0.1045.g170613ef41-goog
Powered by blists - more mailing lists