]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
mm: fs: remove filemap_nr_thps*() functions and their users
authorZi Yan <ziy@nvidia.com>
Sun, 17 May 2026 13:54:08 +0000 (09:54 -0400)
committerAndrew Morton <akpm@linux-foundation.org>
Sun, 21 Jun 2026 18:37:15 +0000 (11:37 -0700)
They are used by READ_ONLY_THP_FOR_FS to handle writes to FSes without
large folio support, so that read-only THPs created in these FSes are not
seen by the FSes when the underlying fd becomes writable.  Now read-only
PMD THPs only appear in a FS with large folio support and the supported
orders include PMD_ORDER.

READ_ONLY_THP_FOR_FS was using mapping->nr_thps, inode->i_writecount, and
smp_mb() to prevent writes to a read-only THP and collapsing writable
folios into a THP.  In collapse_file(), mapping->nr_thps is increased,
then smp_mb(), and if inode->i_writecount > 0, collapse is stopped, while
do_dentry_open() first increases inode->i_writecount, then a full memory
fence, and if mapping->nr_thps > 0, all read-only THPs are truncated.

Now this mechanism can be removed along with READ_ONLY_THP_FOR_FS code,
since a dirty folio check has been added after try_to_unmap() in
collapse_file() to prevent dirty folios from being collapsed as clean.

Link: https://lore.kernel.org/20260517135416.1434539-7-ziy@nvidia.com
Signed-off-by: Zi Yan <ziy@nvidia.com>
Reviewed-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Acked-by: David Hildenbrand (Arm) <david@kernel.org>
Reviewed-by: Baolin Wang <baolin.wang@linux.alibaba.com>
Reviewed-by: Lance Yang <lance.yang@linux.dev>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: Barry Song <baohua@kernel.org>
Cc: Chris Mason <clm@fb.com>
Cc: Christian Brauner <brauner@kernel.org>
Cc: David Sterba <dsterba@suse.com>
Cc: Dev Jain <dev.jain@arm.com>
Cc: Jan Kara <jack@suse.cz>
Cc: Liam Howlett <liam@infradead.org>
Cc: Lorenzo Stoakes <ljs@kernel.org>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Mike Rapoport <rppt@kernel.org>
Cc: Nico Pache <npache@redhat.com>
Cc: Ryan Roberts <ryan.roberts@arm.com>
Cc: Shuah Khan <shuah@kernel.org>
Cc: Song Liu <songliubraving@fb.com>
Cc: Suren Baghdasaryan <surenb@google.com>
Cc: Vlastimil Babka <vbabka@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
fs/open.c
include/linux/pagemap.h
mm/filemap.c
mm/huge_memory.c
mm/khugepaged.c

index 681d405bc61ebe1162cc6389bbd9de1cd498d752..c321b80027f135d311a7e9fe9cfba23c46ec00a7 100644 (file)
--- a/fs/open.c
+++ b/fs/open.c
@@ -968,33 +968,6 @@ static int do_dentry_open(struct file *f,
        if ((f->f_flags & O_DIRECT) && !(f->f_mode & FMODE_CAN_ODIRECT))
                return -EINVAL;
 
-       /*
-        * XXX: Huge page cache doesn't support writing yet. Drop all page
-        * cache for this file before processing writes.
-        */
-       if (f->f_mode & FMODE_WRITE) {
-               /*
-                * Depends on full fence from get_write_access() to synchronize
-                * against collapse_file() regarding i_writecount and nr_thps
-                * updates. Ensures subsequent insertion of THPs into the page
-                * cache will fail.
-                */
-               if (filemap_nr_thps(inode->i_mapping)) {
-                       struct address_space *mapping = inode->i_mapping;
-
-                       filemap_invalidate_lock(inode->i_mapping);
-                       /*
-                        * unmap_mapping_range just need to be called once
-                        * here, because the private pages is not need to be
-                        * unmapped mapping (e.g. data segment of dynamic
-                        * shared libraries here).
-                        */
-                       unmap_mapping_range(mapping, 0, 0, 0);
-                       truncate_inode_pages(mapping, 0);
-                       filemap_invalidate_unlock(inode->i_mapping);
-               }
-       }
-
        return 0;
 
 cleanup_all:
index 308d846531d030d7df7a4fbb38787da83b996682..627771e82eb162f52b4af04f4e871801d72e0d1a 100644 (file)
@@ -546,35 +546,6 @@ static inline size_t mapping_max_folio_size(const struct address_space *mapping)
        return PAGE_SIZE << mapping_max_folio_order(mapping);
 }
 
-static inline int filemap_nr_thps(const struct address_space *mapping)
-{
-#ifdef CONFIG_READ_ONLY_THP_FOR_FS
-       return atomic_read(&mapping->nr_thps);
-#else
-       return 0;
-#endif
-}
-
-static inline void filemap_nr_thps_inc(struct address_space *mapping)
-{
-#ifdef CONFIG_READ_ONLY_THP_FOR_FS
-       if (!mapping_large_folio_support(mapping))
-               atomic_inc(&mapping->nr_thps);
-#else
-       WARN_ON_ONCE(mapping_large_folio_support(mapping) == 0);
-#endif
-}
-
-static inline void filemap_nr_thps_dec(struct address_space *mapping)
-{
-#ifdef CONFIG_READ_ONLY_THP_FOR_FS
-       if (!mapping_large_folio_support(mapping))
-               atomic_dec(&mapping->nr_thps);
-#else
-       WARN_ON_ONCE(mapping_large_folio_support(mapping) == 0);
-#endif
-}
-
 struct address_space *folio_mapping(const struct folio *folio);
 
 /**
index 5d9f9b36e9d8a6a0bb4b3a7ad17d4abf63317c2c..dc3a0e960b9fd67dfac6478f4b1e2d521c9aaf6b 100644 (file)
@@ -189,7 +189,6 @@ static void filemap_unaccount_folio(struct address_space *mapping,
                        lruvec_stat_mod_folio(folio, NR_SHMEM_THPS, -nr);
        } else if (folio_test_pmd_mappable(folio)) {
                lruvec_stat_mod_folio(folio, NR_FILE_THPS, -nr);
-               filemap_nr_thps_dec(mapping);
        }
        if (test_bit(AS_KERNEL_FILE, &folio->mapping->flags))
                mod_node_page_state(folio_pgdat(folio),
index 8808eb56ef0e3c8bf44547fe2d8306f4d955d399..2fc3356d0a3c3206776636c1b2c35b66be7be283 100644 (file)
@@ -3877,7 +3877,6 @@ static int __folio_freeze_and_split_unmapped(struct folio *folio, unsigned int n
                                } else {
                                        lruvec_stat_mod_folio(folio,
                                                        NR_FILE_THPS, -nr);
-                                       filemap_nr_thps_dec(mapping);
                                }
                        }
                }
index d8fdcc7882adaa1fa2bf31673328d94b5823185a..d9de48423a2e8ede932afe8b98b24102b7c0b204 100644 (file)
@@ -2480,21 +2480,6 @@ out_unlock:
                goto xa_unlocked;
        }
 
-       if (!is_shmem) {
-               filemap_nr_thps_inc(mapping);
-               /*
-                * Paired with the fence in do_dentry_open() -> get_write_access()
-                * to ensure i_writecount is up to date and the update to nr_thps
-                * is visible. Ensures the page cache will be truncated if the
-                * file is opened writable.
-                */
-               smp_mb();
-               if (inode_is_open_for_write(mapping->host)) {
-                       result = SCAN_FAIL;
-                       filemap_nr_thps_dec(mapping);
-               }
-       }
-
 xa_locked:
        xas_unlock_irq(&xas);
 xa_unlocked:
@@ -2672,19 +2657,6 @@ rollback:
                folio_putback_lru(folio);
                folio_put(folio);
        }
-       /*
-        * Undo the updates of filemap_nr_thps_inc for non-SHMEM
-        * file only. This undo is not needed unless failure is
-        * due to SCAN_COPY_MC.
-        */
-       if (!is_shmem && result == SCAN_COPY_MC) {
-               filemap_nr_thps_dec(mapping);
-               /*
-                * Paired with the fence in do_dentry_open() -> get_write_access()
-                * to ensure the update to nr_thps is visible.
-                */
-               smp_mb();
-       }
 
        new_folio->mapping = NULL;