Some cleanups for shmem
Subsystems (3)
Baolin Wang
reviewerPATCH v3 1/3 mm: shmem: simplify the suitable huge orders validation for tmpfs
In reply to Baolin WangMove the suitable huge orders validation into shmem_suitable_orders() for tmpfs, which can reuse some code to simplify the logic.
In addition, we don't have special handling for the error code -E2BIG when checking for conflicts with PMD sized THP in the pagecache for tmpfs, instead, it will just fallback to order-0 allocations like this patch does, so this simplification will not add functional changes.
--- mm/shmem.c | 39 +++++++++++++++------------------------ 1 file changed, 15 insertions(+), 24 deletions(-)
mm/shmem.c +15 -24
@@ -1685,19 +1685,29 @@ static unsigned long shmem_suitable_orders(struct inode *inode, struct vm_fault struct address_space *mapping, pgoff_t index, unsigned long orders) { - struct vm_area_struct *vma = vmf->vma; + struct vm_area_struct *vma = vmf ? vmf->vma : NULL;unsigned long pages;int order; - orders =thp_vma_suitable_orders (vma, vmf->address, orders); -if (!orders) -return 0 ; +if (vma) { + orders =thp_vma_suitable_orders (vma, vmf->address, orders); +if (!orders) +return 0 ; + }/* Find the highest order that can add into the page cache */ order =highest_order (orders);while (orders) { pages =1UL << order; index =round_down (index, pages); +/* +* Check for conflict before waiting on a huge allocation. +* Conflict might be that a huge page has just been allocated +* and added to page cache by a racing thread, or that there +* is already at least one small page in the huge extent. +* Be careful to retry when appropriate, but not forever! +* Elsewhere -EEXIST would be the right code, but not here. +*/ if (!xa_find (&mapping->i_pages, &index, index + pages -1 ,XA_PRESENT ))break ;
@@ -1735,7 +1745,6 @@ static struct folio *shmem_alloc_and_add_folio(struct vm_fault *vmf, {struct address_space *mapping = inode->i_mapping;struct shmem_inode_info *info =SHMEM_I (inode); -struct vm_area_struct *vma = vmf ? vmf->vma :NULL ;unsigned long suitable_orders =0 ;struct folio *folio =NULL ;long pages;
@@ -1745,26 +1754,8 @@ static struct folio *shmem_alloc_and_add_folio(struct vm_fault *vmf, orders =0 ;if (orders >0 ) { -if (vma &&vma_is_anon_shmem (vma)) { - suitable_orders =shmem_suitable_orders (inode, vmf, + suitable_orders =shmem_suitable_orders (inode, vmf, mapping, index, orders); - }else if (orders &BIT (HPAGE_PMD_ORDER )) { - pages =HPAGE_PMD_NR ; - suitable_orders =BIT (HPAGE_PMD_ORDER ); - index =round_down (index,HPAGE_PMD_NR ); - -/* -* Check for conflict before waiting on a huge allocation. -* Conflict might be that a huge page has just been allocated -* and added to page cache by a racing thread, or that there -* is already at least one small page in the huge extent. -* Be careful to retry when appropriate, but not forever! -* Elsewhere -EEXIST would be the right code, but not here. -*/ -if (xa_find (&mapping->i_pages, &index, - index +HPAGE_PMD_NR -1 ,XA_PRESENT )) -return ERR_PTR (-E2BIG ); - } order =highest_order (suitable_orders);while (suitable_orders) {
Signature · 1 line
2.39.3
Baolin Wang
reviewerPATCH v3 2/3 mm: shmem: rename shmem_is_huge() to shmem_huge_global_enabled()
In reply to Baolin WangThe shmem_is_huge() is now used to check if the top-level huge page is enabled, thus rename it to reflect its usage.
--- include/linux/shmem_fs.h | 9 +++++---- mm/huge_memory.c | 5 +++-- mm/shmem.c | 15 ++++++++------- 3 files changed, 16 insertions(+), 13 deletions(-)
include/linux/shmem_fs.h +5 -4
@@ -111,14 +111,15 @@ extern void shmem_truncate_range(struct inode *inode, loff_t start, loff_t end);int shmem_unuse (unsigned int type);#ifdef CONFIG_TRANSPARENT_HUGEPAGE -extern bool shmem_is_huge (struct inode *inode,pgoff_t index,bool shmem_huge_force, -struct mm_struct *mm,unsigned long vm_flags); +extern bool shmem_huge_global_enabled (struct inode *inode,pgoff_t index,bool shmem_huge_force, +struct mm_struct *mm,unsigned long vm_flags);unsigned long shmem_allowable_huge_orders (struct inode *inode,struct vm_area_struct *vma,pgoff_t index,bool global_huge);#else -static __always_inline bool shmem_is_huge(struct inode *inode, pgoff_t index, bool shmem_huge_force, -struct mm_struct *mm,unsigned long vm_flags) +static __always_inline bool shmem_huge_global_enabled(struct inode *inode, pgoff_t index, +bool shmem_huge_force,struct mm_struct *mm, +unsigned long vm_flags) {return false; }
mm/huge_memory.c +3 -2
@@ -160,8 +160,9 @@ unsigned long __thp_vma_allowable_orders(struct vm_area_struct *vma,* own flags. */ if (!in_pf &&shmem_file (vma->vm_file)) { -bool global_huge =shmem_is_huge (file_inode (vma->vm_file), vma->vm_pgoff, - !enforce_sysfs, vma->vm_mm, vm_flags); +bool global_huge =shmem_huge_global_enabled (file_inode (vma->vm_file), + vma->vm_pgoff, !enforce_sysfs, + vma->vm_mm, vm_flags);if (!vma_is_anon_shmem (vma))return global_huge ? orders :0 ;
mm/shmem.c +8 -7
@@ -548,9 +548,9 @@ static bool shmem_confirm_swap(struct address_space *mapping,static int shmem_huge__read_mostly =SHMEM_HUGE_NEVER ; -static bool __shmem_is_huge (struct inode *inode,pgoff_t index, -bool shmem_huge_force,struct mm_struct *mm, -unsigned long vm_flags) +static bool __shmem_huge_global_enabled (struct inode *inode,pgoff_t index, +bool shmem_huge_force,struct mm_struct *mm, +unsigned long vm_flags) {loff_t i_size;
@@ -581,14 +581,15 @@ static bool __shmem_is_huge(struct inode *inode, pgoff_t index, } } -bool shmem_is_huge (struct inode *inode,pgoff_t index, +bool shmem_huge_global_enabled (struct inode *inode,pgoff_t index,bool shmem_huge_force,struct mm_struct *mm,unsigned long vm_flags) {if (HPAGE_PMD_ORDER >MAX_PAGECACHE_ORDER )return false; -return __shmem_is_huge (inode, index, shmem_huge_force, mm, vm_flags); +return __shmem_huge_global_enabled (inode, index, shmem_huge_force, + mm, vm_flags); }#if defined(CONFIG_SYSFS )
@@ -1156,7 +1157,7 @@ static int shmem_getattr(struct mnt_idmap *idmap, STATX_ATTR_NODUMP);generic_fillattr (idmap, request_mask, inode, stat); -if (shmem_is_huge (inode,0 , false,NULL ,0 )) +if (shmem_huge_global_enabled (inode,0 , false,NULL ,0 )) stat->blksize =HPAGE_PMD_SIZE ;if (request_mask &STATX_BTIME ) {
@@ -2153,7 +2154,7 @@ static int shmem_get_folio_gfp(struct inode *inode, pgoff_t index,return 0 ; } - huge =shmem_is_huge (inode, index, false, fault_mm, + huge =shmem_huge_global_enabled (inode, index, false, fault_mm, vma ? vma->vm_flags :0 );/* Find hugepage orders that are allowed for anonymous shmem. */ if (vma &&vma_is_anon_shmem (vma))
Signature · 1 line
2.39.3
Baolin Wang
reviewerPATCH v3 3/3 mm: shmem: move shmem_huge_global_enabled() into shmem_allowable_huge_orders()
In reply to Baolin WangMove shmem_huge_global_enabled() into the shmem_allowable_huge_orders() function, so that shmem_allowable_huge_orders() can also help to find the allowable huge orders for tmpfs. Moreover the shmem_huge_global_enabled() can become static. While we are at it, passing the vma instead of mm for shmem_huge_global_enabled() makes code cleaner.
No functional changes.
--- include/linux/shmem_fs.h | 12 ++-------- mm/huge_memory.c | 12 +++------- mm/shmem.c | 47 +++++++++++++++++++++++++--------------- 3 files changed, 35 insertions(+), 36 deletions(-)
include/linux/shmem_fs.h +2 -10
@@ -111,21 +111,13 @@ extern void shmem_truncate_range(struct inode *inode, loff_t start, loff_t end);int shmem_unuse (unsigned int type);#ifdef CONFIG_TRANSPARENT_HUGEPAGE -extern bool shmem_huge_global_enabled (struct inode *inode,pgoff_t index,bool shmem_huge_force, -struct mm_struct *mm,unsigned long vm_flags);unsigned long shmem_allowable_huge_orders (struct inode *inode,struct vm_area_struct *vma,pgoff_t index, -bool global_huge); +bool shmem_huge_force);#else -static __always_inline bool shmem_huge_global_enabled(struct inode *inode, pgoff_t index, -bool shmem_huge_force,struct mm_struct *mm, -unsigned long vm_flags) -{ -return false; -}static inline unsigned long shmem_allowable_huge_orders (struct inode *inode,struct vm_area_struct *vma,pgoff_t index, -bool global_huge) +bool shmem_huge_force) {return 0 ; }
mm/huge_memory.c +3 -9
@@ -159,16 +159,10 @@ unsigned long __thp_vma_allowable_orders(struct vm_area_struct *vma,* Must be done before hugepage flags check since shmem has its * own flags. */ -if (!in_pf &&shmem_file (vma->vm_file)) { -bool global_huge =shmem_huge_global_enabled (file_inode (vma->vm_file), - vma->vm_pgoff, !enforce_sysfs, - vma->vm_mm, vm_flags); - -if (!vma_is_anon_shmem (vma)) -return global_huge ? orders :0 ; +if (!in_pf &&shmem_file (vma->vm_file))return shmem_allowable_huge_orders (file_inode (vma->vm_file), - vma, vma->vm_pgoff, global_huge); - } + vma, vma->vm_pgoff, + !enforce_sysfs);if (!vma_is_anonymous (vma)) {/*
mm/shmem.c +30 -17
108 lines not on this page · raw message
Signature · 1 line
2.39.3
Baolin Wang
reviewerv3 cover Some cleanups for shmem
Hi,
This series does some cleanups to reuse code, rename functions and simplify logic to make code more clear. No functional changes are expected.
Changes from v2:
- Add reviewed tag from Ryan. Thanks.
- Pass vma instead of mm to shmem_huge_global_enabled(), per Ryan.
Changes from v1:
- Add a dummy function in case CONFIG_TRANSPARENT_HUGEPAGE is not enabled, which fixes a building error reported by kernel test robot.
Baolin Wang (3):
mm: shmem: simplify the suitable huge orders validation for tmpfs
mm: shmem: rename shmem_is_huge() to shmem_huge_global_enabled()
mm: shmem: move shmem_huge_global_enabled() into
shmem_allowable_huge_orders()
include/linux/shmem_fs.h | 11 +---- mm/huge_memory.c | 11 ++--- mm/shmem.c | 93 +++++++++++++++++++++------------------- 3 files changed, 54 insertions(+), 61 deletions(-)
Signature · 1 line
2.39.3