diff mbox series

[2/3] btrfs: do not use __GFP_NOFAIL flag for attach_eb_folio_to_filemap()

Message ID d6a9c038e12f1f2dae353f1ba657ba0666f0aaaa.1720159494.git.wqu@suse.com (mailing list archive)
State New, archived
Headers show
Series btrfs: remove __GFP_NOFAIL usage for debug builds | expand

Commit Message

Qu Wenruo July 5, 2024, 6:15 a.m. UTC
The gfp_flag passed into filemap_add_folio() is utilized by two
locations:

- mem_cgroup_charge()
  I'm not confident mem cgroup is going to handle the different
  combinations of folio order and __GFP_NOFAIL that well.
  In fact I'm already hitting various soft lockup in mem cgroup related
  code during larger metadata folio tests.

- Xarray split
  I believe this is mostly fine.

Although extent buffer allocation is very critical, we can still handle
the errors, the worst case is to abort the current transaction.

So to enable more testing and hopefully to provide a smooth transaction,
for CONFIG_BTRFS_DEBUG builds do not use __GFP_NOFAIL flag.

Signed-off-by: Qu Wenruo <wqu@suse.com>
---
 fs/btrfs/extent_io.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
index d43a3a9fc650..97c3f272fcaa 100644
--- a/fs/btrfs/extent_io.c
+++ b/fs/btrfs/extent_io.c
@@ -2966,6 +2966,7 @@  static int check_eb_alignment(struct btrfs_fs_info *fs_info, u64 start)
  * and @found_eb_ret would be updated.
  * Return -EAGAIN if the filemap has an existing folio but with different size
  * than @eb.
+ * Return -ENOMEM if the memory allocation failed.
  * The caller needs to free the existing folios and retry using the same order.
  */
 static int attach_eb_folio_to_filemap(struct extent_buffer *eb, int i,
@@ -2977,6 +2978,7 @@  static int attach_eb_folio_to_filemap(struct extent_buffer *eb, int i,
 	struct address_space *mapping = fs_info->btree_inode->i_mapping;
 	const unsigned long index = eb->start >> PAGE_SHIFT;
 	struct folio *existing_folio = NULL;
+	const bool debug = IS_ENABLED(CONFIG_BTRFS_DEBUG);
 	int ret;
 
 	ASSERT(found_eb_ret);
@@ -2986,10 +2988,13 @@  static int attach_eb_folio_to_filemap(struct extent_buffer *eb, int i,
 
 retry:
 	ret = filemap_add_folio(mapping, eb->folios[i], index + i,
-				GFP_NOFS | __GFP_NOFAIL);
+				GFP_NOFS | (!debug ? __GFP_NOFAIL : 0));
 	if (!ret)
 		goto finish;
+	if (unlikely(ret == -ENOMEM))
+		return ret;
 
+	ASSERT(ret == -EEXIST);
 	existing_folio = filemap_lock_folio(mapping, index + i);
 	/* The page cache only exists for a very short time, just retry. */
 	if (IS_ERR(existing_folio)) {
@@ -3126,6 +3131,8 @@  struct extent_buffer *alloc_extent_buffer(struct btrfs_fs_info *fs_info,
 			ASSERT(existing_eb);
 			goto out;
 		}
+		if (unlikely(ret == -ENOMEM))
+			goto out;
 
 		/*
 		 * TODO: Special handling for a corner case where the order of