diff options
Diffstat (limited to 'include/linux')
| -rw-r--r-- | include/linux/alloc_tag.h | 4 | ||||
| -rw-r--r-- | include/linux/codetag.h | 3 | ||||
| -rw-r--r-- | include/linux/fs.h | 5 | ||||
| -rw-r--r-- | include/linux/huge_mm.h | 30 | ||||
| -rw-r--r-- | include/linux/pagemap.h | 52 | ||||
| -rw-r--r-- | include/linux/shmem_fs.h | 2 |
6 files changed, 36 insertions, 60 deletions
diff --git a/include/linux/alloc_tag.h b/include/linux/alloc_tag.h index 02de2ede560f..068ba2e77c5d 100644 --- a/include/linux/alloc_tag.h +++ b/include/linux/alloc_tag.h @@ -163,11 +163,11 @@ static inline void alloc_tag_sub_check(union codetag_ref *ref) { WARN_ONCE(ref && !ref->ct, "alloc_tag was not set\n"); } -void alloc_tag_add_early_pfn(unsigned long pfn); +void alloc_tag_add_early_pfn(unsigned long pfn, gfp_t gfp_flags); #else static inline void alloc_tag_add_check(union codetag_ref *ref, struct alloc_tag *tag) {} static inline void alloc_tag_sub_check(union codetag_ref *ref) {} -static inline void alloc_tag_add_early_pfn(unsigned long pfn) {} +static inline void alloc_tag_add_early_pfn(unsigned long pfn, gfp_t gfp_flags) {} #endif /* Caller should verify both ref and tag to be valid */ diff --git a/include/linux/codetag.h b/include/linux/codetag.h index 8ea2a5f7c98a..ddae7484ca45 100644 --- a/include/linux/codetag.h +++ b/include/linux/codetag.h @@ -74,8 +74,9 @@ struct codetag_iterator { .flags = 0, \ } -void codetag_lock_module_list(struct codetag_type *cttype, bool lock); +void codetag_lock_module_list(struct codetag_type *cttype); bool codetag_trylock_module_list(struct codetag_type *cttype); +void codetag_unlock_module_list(struct codetag_type *cttype); struct codetag_iterator codetag_get_ct_iter(struct codetag_type *cttype); struct codetag *codetag_next_ct(struct codetag_iterator *iter); diff --git a/include/linux/fs.h b/include/linux/fs.h index 6da44573ce45..d10897b3a1e3 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -460,7 +460,6 @@ struct mapping_metadata_bhs { * memory mappings. * @gfp_mask: Memory allocation flags to use for allocating pages. * @i_mmap_writable: Number of VM_SHARED, VM_MAYWRITE mappings. - * @nr_thps: Number of THPs in the pagecache (non-shmem only). * @i_mmap: Tree of private and shared mappings. * @i_mmap_rwsem: Protects @i_mmap and @i_mmap_writable. * @nrpages: Number of page entries, protected by the i_pages lock. @@ -476,10 +475,6 @@ struct address_space { struct rw_semaphore invalidate_lock; gfp_t gfp_mask; atomic_t i_mmap_writable; -#ifdef CONFIG_READ_ONLY_THP_FOR_FS - /* number of thp, only for non-shmem files */ - atomic_t nr_thps; -#endif struct rb_root_cached i_mmap; unsigned long nrpages; pgoff_t writeback_index; diff --git a/include/linux/huge_mm.h b/include/linux/huge_mm.h index c0d223d0c556..ad20f7f8c179 100644 --- a/include/linux/huge_mm.h +++ b/include/linux/huge_mm.h @@ -128,6 +128,8 @@ enum mthp_stat_item { MTHP_STAT_ANON_FAULT_ALLOC, MTHP_STAT_ANON_FAULT_FALLBACK, MTHP_STAT_ANON_FAULT_FALLBACK_CHARGE, + MTHP_STAT_COLLAPSE_ALLOC, + MTHP_STAT_COLLAPSE_ALLOC_FAILED, MTHP_STAT_ZSWPOUT, MTHP_STAT_SWPIN, MTHP_STAT_SWPIN_FALLBACK, @@ -142,6 +144,9 @@ enum mthp_stat_item { MTHP_STAT_SPLIT_DEFERRED, MTHP_STAT_NR_ANON, MTHP_STAT_NR_ANON_PARTIALLY_MAPPED, + MTHP_STAT_COLLAPSE_EXCEED_SWAP, + MTHP_STAT_COLLAPSE_EXCEED_NONE, + MTHP_STAT_COLLAPSE_EXCEED_SHARED, __MTHP_STAT_COUNT }; @@ -414,27 +419,6 @@ static inline int split_huge_page_to_order(struct page *page, unsigned int new_o return split_huge_page_to_list_to_order(page, NULL, new_order); } -/** - * try_folio_split_to_order() - try to split a @folio at @page to @new_order - * using non uniform split. - * @folio: folio to be split - * @page: split to @new_order at the given page - * @new_order: the target split order - * - * Try to split a @folio at @page using non uniform split to @new_order, if - * non uniform split is not supported, fall back to uniform split. After-split - * folios are put back to LRU list. Use min_order_for_split() to get the lower - * bound of @new_order. - * - * Return: 0 - split is successful, otherwise split failed. - */ -static inline int try_folio_split_to_order(struct folio *folio, - struct page *page, unsigned int new_order) -{ - if (folio_check_splittable(folio, new_order, SPLIT_TYPE_NON_UNIFORM)) - return split_huge_page_to_order(&folio->page, new_order); - return folio_split(folio, new_order, page, NULL); -} static inline int split_huge_page(struct page *page) { return split_huge_page_to_list_to_order(page, NULL, 0); @@ -672,8 +656,8 @@ static inline int split_folio_to_list(struct folio *folio, struct list_head *lis return -EINVAL; } -static inline int try_folio_split_to_order(struct folio *folio, - struct page *page, unsigned int new_order) +static inline int folio_split(struct folio *folio, unsigned int new_order, + struct page *page, struct list_head *list) { VM_WARN_ON_ONCE_FOLIO(1, folio); return -EINVAL; diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h index 1f50991b43e3..2c3718d592d6 100644 --- a/include/linux/pagemap.h +++ b/include/linux/pagemap.h @@ -513,39 +513,37 @@ static inline bool mapping_large_folio_support(const struct address_space *mappi return mapping_max_folio_order(mapping) > 0; } -/* Return the maximum folio size for this pagecache mapping, in bytes. */ -static inline size_t mapping_max_folio_size(const struct address_space *mapping) +/** + * mapping_pmd_folio_support() - Check if a mapping supports PMD-sized folio + * @mapping: The address_space + * + * While some mappings support large folios, they might not support PMD-sized + * folios. This function checks whether a mapping supports PMD-sized folios. + * For example, khugepaged needs this information before attempting to + * collapsing THPs. + * + * Return: True if PMD-sized folios are supported, otherwise false. + */ +#ifdef CONFIG_TRANSPARENT_HUGEPAGE +static inline bool mapping_pmd_folio_support(const struct address_space *mapping) { - return PAGE_SIZE << mapping_max_folio_order(mapping); -} + /* AS_FOLIO_ORDER is only reasonable for pagecache folios */ + VM_WARN_ON_ONCE((unsigned long)mapping & FOLIO_MAPPING_ANON); -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 + return mapping_min_folio_order(mapping) <= PMD_ORDER && + mapping_max_folio_order(mapping) >= PMD_ORDER; } - -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 bool mapping_pmd_folio_support(const struct address_space *mapping) +{ + return false; } +#endif -static inline void filemap_nr_thps_dec(struct address_space *mapping) +/* Return the maximum folio size for this pagecache mapping, in bytes. */ +static inline size_t mapping_max_folio_size(const 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 + return PAGE_SIZE << mapping_max_folio_order(mapping); } struct address_space *folio_mapping(const struct folio *folio); @@ -1350,7 +1348,6 @@ struct readahead_control { struct file_ra_state *ra; /* private: use the readahead_* accessors instead */ pgoff_t _index; - pgoff_t _max_index; /* limit readahead to _max_index, inclusive */ unsigned int _nr_pages; unsigned int _batch_count; bool dropbehind; @@ -1364,7 +1361,6 @@ struct readahead_control { .mapping = m, \ .ra = r, \ ._index = i, \ - ._max_index = ULONG_MAX, \ } #define VM_READAHEAD_PAGES (SZ_128K / PAGE_SIZE) diff --git a/include/linux/shmem_fs.h b/include/linux/shmem_fs.h index 69b0177da156..e729b9b0e38d 100644 --- a/include/linux/shmem_fs.h +++ b/include/linux/shmem_fs.h @@ -128,7 +128,7 @@ int shmem_writeout(struct folio *folio, struct swap_iocb **plug, void shmem_truncate_range(struct inode *inode, loff_t start, uoff_t end); int shmem_unuse(unsigned int type); -#ifdef CONFIG_TRANSPARENT_HUGEPAGE +#if defined(CONFIG_TRANSPARENT_HUGEPAGE) && defined(CONFIG_SHMEM) unsigned long shmem_allowable_huge_orders(struct inode *inode, struct vm_area_struct *vma, pgoff_t index, loff_t write_end, bool shmem_huge_force); |
