[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20240226094936.2677493-5-kernel@pankajraghav.com>
Date: Mon, 26 Feb 2024 10:49:27 +0100
From: "Pankaj Raghav (Samsung)" <kernel@...kajraghav.com>
To: linux-xfs@...r.kernel.org,
linux-fsdevel@...r.kernel.org
Cc: linux-kernel@...r.kernel.org,
david@...morbit.com,
chandan.babu@...cle.com,
akpm@...ux-foundation.org,
mcgrof@...nel.org,
ziy@...dia.com,
hare@...e.de,
djwong@...nel.org,
gost.dev@...sung.com,
linux-mm@...ck.org,
willy@...radead.org,
Pankaj Raghav <p.raghav@...sung.com>
Subject: [PATCH 04/13] filemap: use mapping_min_order while allocating folios
From: Pankaj Raghav <p.raghav@...sung.com>
filemap_create_folio() and do_read_cache_folio() were always allocating
folio of order 0. __filemap_get_folio was trying to allocate higher
order folios when fgp_flags had higher order hint set but it will default
to order 0 folio if higher order memory allocation fails.
As we bring the notion of mapping_min_order, make sure these functions
allocate at least folio of mapping_min_order as we need to guarantee it
in the page cache.
Add some additional VM_BUG_ON() in page_cache_delete[batch] and
__filemap_add_folio to catch errors where we delete or add folios that
has order less than min_order.
Signed-off-by: Pankaj Raghav <p.raghav@...sung.com>
Signed-off-by: Luis Chamberlain <mcgrof@...nel.org>
Reviewed-by: Hannes Reinecke <hare@...e.de>
Acked-by: Darrick J. Wong <djwong@...nel.org>
---
mm/filemap.c | 24 ++++++++++++++++++++----
1 file changed, 20 insertions(+), 4 deletions(-)
diff --git a/mm/filemap.c b/mm/filemap.c
index bdf4f65f597c..4b144479c4cb 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -135,6 +135,8 @@ static void page_cache_delete(struct address_space *mapping,
xas_set_order(&xas, folio->index, folio_order(folio));
nr = folio_nr_pages(folio);
+ VM_BUG_ON_FOLIO(folio_order(folio) < mapping_min_folio_order(mapping),
+ folio);
VM_BUG_ON_FOLIO(!folio_test_locked(folio), folio);
xas_store(&xas, shadow);
@@ -305,6 +307,8 @@ static void page_cache_delete_batch(struct address_space *mapping,
WARN_ON_ONCE(!folio_test_locked(folio));
+ VM_BUG_ON_FOLIO(folio_order(folio) < mapping_min_folio_order(mapping),
+ folio);
folio->mapping = NULL;
/* Leave folio->index set: truncation lookup relies on it */
@@ -896,6 +900,8 @@ noinline int __filemap_add_folio(struct address_space *mapping,
}
}
+ VM_BUG_ON_FOLIO(folio_order(folio) < mapping_min_folio_order(mapping),
+ folio);
xas_store(&xas, folio);
if (xas_error(&xas))
goto unlock;
@@ -1847,6 +1853,9 @@ struct folio *__filemap_get_folio(struct address_space *mapping, pgoff_t index,
fgf_t fgp_flags, gfp_t gfp)
{
struct folio *folio;
+ unsigned int min_order = mapping_min_folio_order(mapping);
+
+ index = mapping_align_start_index(mapping, index);
repeat:
folio = filemap_get_entry(mapping, index);
@@ -1886,7 +1895,7 @@ struct folio *__filemap_get_folio(struct address_space *mapping, pgoff_t index,
folio_wait_stable(folio);
no_page:
if (!folio && (fgp_flags & FGP_CREAT)) {
- unsigned order = FGF_GET_ORDER(fgp_flags);
+ unsigned int order = max(min_order, FGF_GET_ORDER(fgp_flags));
int err;
if ((fgp_flags & FGP_WRITE) && mapping_can_writeback(mapping))
@@ -1912,8 +1921,13 @@ struct folio *__filemap_get_folio(struct address_space *mapping, pgoff_t index,
gfp_t alloc_gfp = gfp;
err = -ENOMEM;
+ if (order < min_order)
+ order = min_order;
if (order > 0)
alloc_gfp |= __GFP_NORETRY | __GFP_NOWARN;
+
+ VM_BUG_ON(index & ((1UL << order) - 1));
+
folio = filemap_alloc_folio(alloc_gfp, order);
if (!folio)
continue;
@@ -1927,7 +1941,7 @@ struct folio *__filemap_get_folio(struct address_space *mapping, pgoff_t index,
break;
folio_put(folio);
folio = NULL;
- } while (order-- > 0);
+ } while (order-- > min_order);
if (err == -EEXIST)
goto repeat;
@@ -2422,7 +2436,8 @@ static int filemap_create_folio(struct file *file,
struct folio *folio;
int error;
- folio = filemap_alloc_folio(mapping_gfp_mask(mapping), 0);
+ folio = filemap_alloc_folio(mapping_gfp_mask(mapping),
+ mapping_min_folio_order(mapping));
if (!folio)
return -ENOMEM;
@@ -3666,7 +3681,8 @@ static struct folio *do_read_cache_folio(struct address_space *mapping,
repeat:
folio = filemap_get_folio(mapping, index);
if (IS_ERR(folio)) {
- folio = filemap_alloc_folio(gfp, 0);
+ folio = filemap_alloc_folio(gfp,
+ mapping_min_folio_order(mapping));
if (!folio)
return ERR_PTR(-ENOMEM);
err = filemap_add_folio(mapping, folio, index, gfp);
--
2.43.0
Powered by blists - more mailing lists