diff mbox series

[RFC,V3,32/43] rv64ilp32_abi: mm: Remove _folio_nr_pages

Message ID 20250325121624.523258-33-guoren@kernel.org (mailing list archive)
State New
Headers show
Series rv64ilp32_abi: Build CONFIG_64BIT kernel-self with ILP32 ABI | expand

Commit Message

Guo Ren March 25, 2025, 12:16 p.m. UTC
From: "Guo Ren (Alibaba DAMO Academy)" <guoren@kernel.org>

BITS_PER_LONG defines the layout of the struct page, and
_folio_nr_pages would conflict with page->_mapcount for RV64ILP32
ABI. Here is problem:

BUG: Bad page state in process kworker/u4:0  pfn:61eed
page: refcount:0 mapcount:5 mapping:00000000 index:0x0 pfn:0x61eed
flags: 0x0(zone=0)
raw: 00000000 00000000 ffffffff 00000000 00000000 00000000 00000004 00000000
raw: 00000000 00000000
page dumped because: nonzero mapcount
Modules linked in:
CPU: 0 UID: 0 PID: 11 Comm: kworker/u4:0 Not tainted 6.13.0-rc4
Hardware name: riscv-virtio,qemu (DT)
Workqueue: async async_run_entry_fn
Call Trace:
[<bc015096>] dump_backtrace+0x1e/0x26
[<bc002330>] show_stack+0x2a/0x38
[<bc00f38c>] dump_stack_lvl+0x4a/0x68
[<bc00f3c0>] dump_stack+0x16/0x1e
[<bc1cadd8>] bad_page+0x120/0x142
[<bc1cf2c2>] free_unref_page+0x510/0x5f8
[<bc17fb16>] __folio_put+0x6a/0xbc
[<bc1d6090>] free_large_kmalloc+0x6a/0xb8
[<bc1d9144>] kfree+0x23c/0x300
[<bcc02834>] unpack_to_rootfs+0x27c/0x2c0
[<bcc02e96>] do_populate_rootfs+0x24/0x12e
[<bc04c80c>] async_run_entry_fn+0x26/0xcc
[<bc03e116>] process_one_work+0x136/0x224
[<bc03e9e4>] worker_thread+0x234/0x30a
[<bc046334>] kthread+0xca/0xe6
[<bca47bea>] ret_from_fork+0xe/0x18
Disabling lock debugging due to kernel taint

So, remove _folio_nr_pages just like CONFIG_32BIT and use
"_flags_1 & 0xff" instead.

Signed-off-by: Guo Ren (Alibaba DAMO Academy) <guoren@kernel.org>
---
 include/linux/mm.h       | 4 ++--
 include/linux/mm_types.h | 2 +-
 mm/internal.h            | 2 +-
 3 files changed, 4 insertions(+), 4 deletions(-)
diff mbox series

Patch

diff --git a/include/linux/mm.h b/include/linux/mm.h
index 7b1068ddcbb7..454fb8ca724c 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -2058,7 +2058,7 @@  static inline long folio_nr_pages(const struct folio *folio)
 {
 	if (!folio_test_large(folio))
 		return 1;
-#ifdef CONFIG_64BIT
+#if BITS_PER_LONG == 64
 	return folio->_folio_nr_pages;
 #else
 	return 1L << (folio->_flags_1 & 0xff);
@@ -2083,7 +2083,7 @@  static inline unsigned long compound_nr(struct page *page)
 
 	if (!test_bit(PG_head, &folio->flags))
 		return 1;
-#ifdef CONFIG_64BIT
+#if BITS_PER_LONG == 64
 	return folio->_folio_nr_pages;
 #else
 	return 1L << (folio->_flags_1 & 0xff);
diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
index 6b27db7f9496..da3ba1a79ad5 100644
--- a/include/linux/mm_types.h
+++ b/include/linux/mm_types.h
@@ -370,7 +370,7 @@  struct folio {
 			atomic_t _entire_mapcount;
 			atomic_t _nr_pages_mapped;
 			atomic_t _pincount;
-#ifdef CONFIG_64BIT
+#if BITS_PER_LONG == 64
 			unsigned int _folio_nr_pages;
 #endif
 	/* private: the union with struct page is transitional */
diff --git a/mm/internal.h b/mm/internal.h
index 109ef30fee11..c9372a8552ba 100644
--- a/mm/internal.h
+++ b/mm/internal.h
@@ -682,7 +682,7 @@  static inline void folio_set_order(struct folio *folio, unsigned int order)
 		return;
 
 	folio->_flags_1 = (folio->_flags_1 & ~0xffUL) | order;
-#ifdef CONFIG_64BIT
+#if BITS_PER_LONG == 64
 	folio->_folio_nr_pages = 1U << order;
 #endif
 }