From: "Pankaj Raghav (Samsung)" <kernel@pankajraghav.com>
To: brauner@kernel.org, sfr@canb.auug.org.au, akpm@linux-foundation.org
Cc: linux-next@vger.kernel.org, mcgrof@kernel.org,
willy@infradead.org, ziy@nvidia.com, da.gomez@samsung.com,
kernel@pankajraghav.com, linux-fsdevel@vger.kernel.org,
linux-mm@kvack.org, Pankaj Raghav <p.raghav@samsung.com>,
Sven Schnelle <svens@linux.ibm.com>
Subject: [PATCH] mm: don't convert the page to folio before splitting in split_huge_page()
Date: Mon, 2 Sep 2024 14:49:32 +0200 [thread overview]
Message-ID: <20240902124931.506061-2-kernel@pankajraghav.com> (raw)
From: Pankaj Raghav <p.raghav@samsung.com>
Sven reported that a commit from bs > ps series was breaking the ksm ltp
test[1].
split_huge_page() takes precisely a page that is locked, and it also
expects the folio that contains that page to be locked after that
huge page has been split. The changes introduced converted the page to
folio, and passed the head page to be split, which might not be locked,
resulting in a kernel panic.
This commit fixes it by always passing the correct page to be split from
split_huge_page() with the appropriate minimum order for splitting.
[1] https://lore.kernel.org/linux-xfs/yt9dttf3r49e.fsf@linux.ibm.com/
Reported-by: Sven Schnelle <svens@linux.ibm.com>
Fixes: fd031210c9ce ("mm: split a folio in minimum folio order chunks")
Signed-off-by: Pankaj Raghav <p.raghav@samsung.com>
---
This applies to the vfs.blocksize branch on the vfs tree.
@Christian, Stephen already sent a mail saying that there is a conflict
with these changes and mm-unstable. For now, I have based these patches
out of your tree. Let me know if you need the same patch based on
linux-next.
include/linux/huge_mm.h | 16 +++++++++++++++-
mm/huge_memory.c | 21 +++++++++++++--------
2 files changed, 28 insertions(+), 9 deletions(-)
diff --git a/include/linux/huge_mm.h b/include/linux/huge_mm.h
index 7c50aeed0522..7a570e0437c9 100644
--- a/include/linux/huge_mm.h
+++ b/include/linux/huge_mm.h
@@ -319,10 +319,24 @@ unsigned long thp_get_unmapped_area_vmflags(struct file *filp, unsigned long add
bool can_split_folio(struct folio *folio, int *pextra_pins);
int split_huge_page_to_list_to_order(struct page *page, struct list_head *list,
unsigned int new_order);
+int min_order_for_split(struct folio *folio);
int split_folio_to_list(struct folio *folio, struct list_head *list);
static inline int split_huge_page(struct page *page)
{
- return split_folio(page_folio(page));
+ struct folio *folio = page_folio(page);
+ int ret = min_order_for_split(folio);
+
+ if (ret < 0)
+ return ret;
+
+ /*
+ * split_huge_page() locks the page before splitting and
+ * expects the same page that has been split to be locked when
+ * returned. split_folio(page_folio(page)) cannot be used here
+ * because it converts the page to folio and passes the head
+ * page to be split.
+ */
+ return split_huge_page_to_list_to_order(page, NULL, ret);
}
void deferred_split_folio(struct folio *folio);
diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index c29af9451d92..9931ff1d9a9d 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -3297,12 +3297,10 @@ int split_huge_page_to_list_to_order(struct page *page, struct list_head *list,
return ret;
}
-int split_folio_to_list(struct folio *folio, struct list_head *list)
+int min_order_for_split(struct folio *folio)
{
- unsigned int min_order = 0;
-
if (folio_test_anon(folio))
- goto out;
+ return 0;
if (!folio->mapping) {
if (folio_test_pmd_mappable(folio))
@@ -3310,10 +3308,17 @@ int split_folio_to_list(struct folio *folio, struct list_head *list)
return -EBUSY;
}
- min_order = mapping_min_folio_order(folio->mapping);
-out:
- return split_huge_page_to_list_to_order(&folio->page, list,
- min_order);
+ return mapping_min_folio_order(folio->mapping);
+}
+
+int split_folio_to_list(struct folio *folio, struct list_head *list)
+{
+ int ret = min_order_for_split(folio);
+
+ if (ret < 0)
+ return ret;
+
+ return split_huge_page_to_list_to_order(&folio->page, list, ret);
}
void __folio_undo_large_rmappable(struct folio *folio)
--
2.44.1
next reply other threads:[~2024-09-02 12:50 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-09-02 12:49 Pankaj Raghav (Samsung) [this message]
2024-09-02 13:35 ` David Hildenbrand
2024-09-02 14:00 ` Matthew Wilcox
2024-09-02 14:21 ` Christian Brauner
2024-09-02 14:48 ` Pankaj Raghav (Samsung)
2024-09-02 19:08 ` Christian Brauner
2024-09-02 19:35 ` Pankaj Raghav (Samsung)
2024-09-03 7:53 ` Christian Brauner
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240902124931.506061-2-kernel@pankajraghav.com \
--to=kernel@pankajraghav.com \
--cc=akpm@linux-foundation.org \
--cc=brauner@kernel.org \
--cc=da.gomez@samsung.com \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=linux-next@vger.kernel.org \
--cc=mcgrof@kernel.org \
--cc=p.raghav@samsung.com \
--cc=sfr@canb.auug.org.au \
--cc=svens@linux.ibm.com \
--cc=willy@infradead.org \
--cc=ziy@nvidia.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox