[PATCH 1/2] btrfs: additional gfp api for allocating compressed folios

JP Kobryn (Meta) posted 2 patches 2 weeks, 3 days ago
There is a newer version of this series
[PATCH 1/2] btrfs: additional gfp api for allocating compressed folios
Posted by JP Kobryn (Meta) 2 weeks, 3 days ago
btrfs_alloc_compr_folio() assumes all callers want GFP_NOFS. This is fine
for most cases, however there are some call sites that would benefit from
different flags. One such case is preventing direct reclaim from occurring
during readahead allocations. With unbounded reclaim during this time,
noticeable latency will occur under high memory pressure.

Provide an additional API that accepts one additional gfp_t parameter,
giving callers flexibility over the characteristics of their allocation.

Signed-off-by: JP Kobryn (Meta) <jp.kobryn@linux.dev>
---
 fs/btrfs/compression.c | 9 +++++++--
 fs/btrfs/compression.h | 1 +
 2 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c
index 192f133d9eb5..ae9cb5b7676c 100644
--- a/fs/btrfs/compression.c
+++ b/fs/btrfs/compression.c
@@ -180,7 +180,7 @@ static unsigned long btrfs_compr_pool_scan(struct shrinker *sh, struct shrink_co
 /*
  * Common wrappers for page allocation from compression wrappers
  */
-struct folio *btrfs_alloc_compr_folio(struct btrfs_fs_info *fs_info)
+struct folio *btrfs_alloc_compr_folio_gfp(struct btrfs_fs_info *fs_info, gfp_t gfp)
 {
 	struct folio *folio = NULL;
 
@@ -200,7 +200,12 @@ struct folio *btrfs_alloc_compr_folio(struct btrfs_fs_info *fs_info)
 		return folio;
 
 alloc:
-	return folio_alloc(GFP_NOFS, fs_info->block_min_order);
+	return folio_alloc(gfp, fs_info->block_min_order);
+}
+
+struct folio *btrfs_alloc_compr_folio(struct btrfs_fs_info *fs_info)
+{
+	return btrfs_alloc_compr_folio_gfp(fs_info, GFP_NOFS);
 }
 
 void btrfs_free_compr_folio(struct folio *folio)
diff --git a/fs/btrfs/compression.h b/fs/btrfs/compression.h
index 973530e9ce6c..6131c128dd21 100644
--- a/fs/btrfs/compression.h
+++ b/fs/btrfs/compression.h
@@ -99,6 +99,7 @@ void btrfs_submit_compressed_read(struct btrfs_bio *bbio);
 int btrfs_compress_str2level(unsigned int type, const char *str, int *level_ret);
 
 struct folio *btrfs_alloc_compr_folio(struct btrfs_fs_info *fs_info);
+struct folio *btrfs_alloc_compr_folio_gfp(struct btrfs_fs_info *fs_info, gfp_t gfp);
 void btrfs_free_compr_folio(struct folio *folio);
 
 struct workspace_manager {
-- 
2.52.0
Re: [PATCH 1/2] btrfs: additional gfp api for allocating compressed folios
Posted by David Sterba 2 weeks, 2 days ago
On Fri, Mar 20, 2026 at 12:34:44AM -0700, JP Kobryn (Meta) wrote:
> btrfs_alloc_compr_folio() assumes all callers want GFP_NOFS. This is fine
> for most cases, however there are some call sites that would benefit from
> different flags. One such case is preventing direct reclaim from occurring
> during readahead allocations. With unbounded reclaim during this time,
> noticeable latency will occur under high memory pressure.
> 
> Provide an additional API that accepts one additional gfp_t parameter,
> giving callers flexibility over the characteristics of their allocation.

If you still need to set the gfp flags in v2, please drop this patch and
extend btrfs_alloc_compr_folio(), the API is internal and we don't need
it fine grained.
Re: [PATCH 1/2] btrfs: additional gfp api for allocating compressed folios
Posted by Mark Harmstone 2 weeks, 2 days ago
Reviewed-by: Mark Harmstone <mark@harmstone.com>

On 20/03/2026 7.34 am, JP Kobryn (Meta) wrote:
> btrfs_alloc_compr_folio() assumes all callers want GFP_NOFS. This is fine
> for most cases, however there are some call sites that would benefit from
> different flags. One such case is preventing direct reclaim from occurring
> during readahead allocations. With unbounded reclaim during this time,
> noticeable latency will occur under high memory pressure.
> 
> Provide an additional API that accepts one additional gfp_t parameter,
> giving callers flexibility over the characteristics of their allocation.
> 
> Signed-off-by: JP Kobryn (Meta) <jp.kobryn@linux.dev>
> ---
>   fs/btrfs/compression.c | 9 +++++++--
>   fs/btrfs/compression.h | 1 +
>   2 files changed, 8 insertions(+), 2 deletions(-)
> 
> diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c
> index 192f133d9eb5..ae9cb5b7676c 100644
> --- a/fs/btrfs/compression.c
> +++ b/fs/btrfs/compression.c
> @@ -180,7 +180,7 @@ static unsigned long btrfs_compr_pool_scan(struct shrinker *sh, struct shrink_co
>   /*
>    * Common wrappers for page allocation from compression wrappers
>    */
> -struct folio *btrfs_alloc_compr_folio(struct btrfs_fs_info *fs_info)
> +struct folio *btrfs_alloc_compr_folio_gfp(struct btrfs_fs_info *fs_info, gfp_t gfp)
>   {
>   	struct folio *folio = NULL;
>   
> @@ -200,7 +200,12 @@ struct folio *btrfs_alloc_compr_folio(struct btrfs_fs_info *fs_info)
>   		return folio;
>   
>   alloc:
> -	return folio_alloc(GFP_NOFS, fs_info->block_min_order);
> +	return folio_alloc(gfp, fs_info->block_min_order);
> +}
> +
> +struct folio *btrfs_alloc_compr_folio(struct btrfs_fs_info *fs_info)
> +{
> +	return btrfs_alloc_compr_folio_gfp(fs_info, GFP_NOFS);
>   }
>   
>   void btrfs_free_compr_folio(struct folio *folio)
> diff --git a/fs/btrfs/compression.h b/fs/btrfs/compression.h
> index 973530e9ce6c..6131c128dd21 100644
> --- a/fs/btrfs/compression.h
> +++ b/fs/btrfs/compression.h
> @@ -99,6 +99,7 @@ void btrfs_submit_compressed_read(struct btrfs_bio *bbio);
>   int btrfs_compress_str2level(unsigned int type, const char *str, int *level_ret);
>   
>   struct folio *btrfs_alloc_compr_folio(struct btrfs_fs_info *fs_info);
> +struct folio *btrfs_alloc_compr_folio_gfp(struct btrfs_fs_info *fs_info, gfp_t gfp);
>   void btrfs_free_compr_folio(struct folio *folio);
>   
>   struct workspace_manager {