From: "Guo Ren (Alibaba DAMO Academy)" <guoren@xxxxxxxxxx> 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@xxxxxxxxxx> --- include/linux/mm.h | 4 ++-- include/linux/mm_types.h | 2 +- mm/internal.h | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) 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 } -- 2.40.1