From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3ED3F46EC79 for ; Tue, 8 Sep 2026 21:16:42 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788902206; cv=none; b=VRQlVshUCP1Q5dXhzX1y8rgipoWhGjU9YdSOn/HZTlVrhjIezR06z+ShOHld+fkgg0Z2G7XTEoJ6nxiqQqjxxZE0waG73tD1QkS+4R7oirDptaDMzqUtNXYPm1Y0aALMbYTyf8qmMjjGZPgMSMOlP2SuISnaa3HXr1wtlcUr+Yc= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788902206; c=relaxed/simple; bh=s7W0btjc0AZoKbKoMDcJVOX8zx5SSoG5BNNYmBUrkbQ=; h=Date:To:From:Subject:Message-Id; b=lkYGFImoZLFYnd3AeR8+57z5gcSdvDkH6hL2RRuG7sodvMXLRiusWHPkQbM3DDE88Defz/HvT3gLMSrIM2QFv6zWYmGKmeRS08Owphhwd2AVM00aQK7vBcYti4196+khYFRTvgAHRnblypHB9qS1ef4HmAnJEl+HZLM6+OUrEiw= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux-foundation.org header.i=@linux-foundation.org header.b=yJS0W6QZ; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux-foundation.org header.i=@linux-foundation.org header.b="yJS0W6QZ" Received: by smtp.kernel.org (Postfix) with ESMTPSA id D3A6F1F00A3A; Tue, 8 Sep 2026 21:16:41 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux-foundation.org; s=korg; t=1788902201; bh=trYZqYUSTa/sjxieqKUqPO1Zar/y6oaHMwqvZM4wohs=; h=Date:To:From:Subject; b=yJS0W6QZVb8K4omU/75M5Yw3YrsObP7iGzYbj1f2SMQHZT79EvwTWIM3VpPxEX3ew bXNBfxyNcjAFC/m35aJHDYaQXc8lYcP5xJlTBACmLZtRMLlyX/siVKV/DvjcBF1dQZ Mz/CQSYGk/vHwOYNo7EwQswZAQ8T/ytLm9TmB340= Date: Tue, 08 Sep 2026 14:16:41 -0700 To: mm-commits@vger.kernel.org,ljs@kernel.org,akpm@linux-foundation.org From: Andrew Morton Subject: + mm-enable-mmu_gather_rcu_table_free-for-m68k-motorola.patch added to mm-new branch Message-Id: <20260908211641.D3A6F1F00A3A@smtp.kernel.org> Precedence: bulk X-Mailing-List: mm-commits@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: The patch titled Subject: mm: enable MMU_GATHER_RCU_TABLE_FREE for m68k-motorola has been added to the -mm mm-new branch. Its filename is mm-enable-mmu_gather_rcu_table_free-for-m68k-motorola.patch This patch will shortly appear at https://git.kernel.org/pub/scm/linux/kernel/git/akpm/25-new.git/tree/patches/mm-enable-mmu_gather_rcu_table_free-for-m68k-motorola.patch This patch will later appear in the mm-new branch at git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm Note, mm-new is a provisional staging ground for work-in-progress patches, and acceptance into mm-new is a notification for others take notice and to finish up reviews. Please do not hesitate to respond to review feedback and post updated versions to replace or incrementally fixup patches in mm-new. The mm-new branch of mm.git is not included in linux-next If a few days of testing in mm-new is successful, the patch will me moved into mm.git's mm-unstable branch, which is included in linux-next Before you just go and hit "reply", please: a) Consider who else should be cc'ed b) Prefer to cc a suitable mailing list as well c) Ideally: find the original patch on the mailing list and do a reply-to-all to that, adding suitable additional cc's *** Remember to use Documentation/process/submit-checklist.rst when testing your code *** The -mm tree is included into linux-next via various branches at git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm and is updated there most days ------------------------------------------------------ From: "Lorenzo Stoakes (ARM)" Subject: mm: enable MMU_GATHER_RCU_TABLE_FREE for m68k-motorola Date: Tue, 08 Sep 2026 13:32:18 +0100 sun3 and coldfire are already supported, however motorola requires a little more care. Here, custom table removal logic is required, so CONFIG_HAVE_ARCH_TLB_REMOVE_TABLE is enabled for m68k-motorola. Firstly as part of this change, the page table level must be communicated to the underlying __tlb_remove_table() implementation. Take advantage of the fact that page tables are aligned by more than enough to permit setting TABLE_PTE or TABLE_PMD in the low bits of the pointer, and store this there. Then update __pte_free_tlb() and __pmd_free_tlb() to pass this through, then have __tlb_remove_table() decode this and pass it to free_pointer_table(). The page table freeing is performed via call_rcu(), so free_pointer_table() now will be invoked from softirq context, and as such may be re-entrant. Introduce an irq save/restore spinlock to handle this, and hold it over the time a given ptable entry is being referenced in both get_pointer_table() and free_pointer_table(). In order to make things a little easier in this respect, separate out the logic for adding a new ptable entry into add_pointer_table() and only hold the lock during ptable entry insertion in this case. Note that original list_add_tail(new, dp) added new prior to dp, which is ptable_list[type].next, i.e. after ptable_list[type]. The equivalent therefore is list_add(new, &ptable_list[type]), which adds new after ptable_list[type], only without needing to make reference to dp. Note that, as m68k-motorola specifies CONFIG_HAVE_ARCH_TLB_REMOVE_TABLE, it does not enable CONFIG_PT_RECLAIM. This isn't meaningfully impactful. With this applied, all of m68k implements CONFIG_MMU_GATHER_RCU_TABLE_FREE. This forms part of an overall effort to switch every architecture to this mode. Link: https://lore.kernel.org/20260908-rcu-pagetable-freeing-v2-9-1f60b64e878e@kernel.org Signed-off-by: Lorenzo Stoakes (ARM) Cc: Albert Ou Cc: Alexander Gordeev Cc: Alexandre Ghiti Cc: Andreas Larsson Cc: "Aneesh Kumar K.V" Cc: Anton Ivanov Cc: Arnd Bergmann Cc: Baolin Wang Cc: Barry Song Cc: "Borislav Petkov (AMD)" Cc: Catalin Marinas Cc: Christian Borntraeger Cc: Christian Zankel Cc: Dave Hansen Cc: David Hildenbrand Cc: David S. Miller Cc: Dev Jain Cc: Dinh Nguyen Cc: Geert Uytterhoeven Cc: Guo Ren Cc: Heiko Carstens Cc: Helge Deller Cc: "H. Peter Anvin" Cc: Huacai Chen Cc: Hugh Dickins Cc: Ingo Molnar Cc: James Bottomley Cc: Jason Gunthorpe Cc: Johannes Berg Cc: John Hubbard Cc: John Paul Adrian Glaubitz Cc: Jonas Bonn Cc: Kiryl Shutsemau Cc: Lance Yang Cc: Liam R. Howlett Cc: Madhavan Srinivasan Cc: Magnus Lindholm Cc: Marc Rutland Cc: Matt Turner Cc: Max Filippov Cc: Michael Ellerman Cc: Michal Hocko Cc: Michal Simek Cc: Mike Rapoport Cc: Nicholas Piggin Cc: Palmer Dabbelt Cc: Peter Xu Cc: Peter Zijlstra Cc: Richard Henderson Cc: Richard Weinberger Cc: Rich Felker Cc: Russell King Cc: Ryan Roberts Cc: Stafford Horne Cc: Stefan Kristiansson Cc: Suren Baghdasaryan Cc: Sven Schnelle Cc: Thomas Bogendoerfer Cc: Vasily Gorbik Cc: Vineet Gupta Cc: Vlastimil Babka Cc: WANG Xuerui Cc: Will Deacon Cc: Yoshinori Sato Cc: Zi Yan Signed-off-by: Andrew Morton --- arch/m68k/Kconfig | 3 arch/m68k/include/asm/motorola_pgalloc.h | 9 - arch/m68k/mm/motorola.c | 121 +++++++++++++-------- 3 files changed, 86 insertions(+), 47 deletions(-) --- a/arch/m68k/include/asm/motorola_pgalloc.h~mm-enable-mmu_gather_rcu_table_free-for-m68k-motorola +++ a/arch/m68k/include/asm/motorola_pgalloc.h @@ -17,6 +17,7 @@ enum m68k_table_types { extern void init_pointer_table(void *table, int type); extern void *get_pointer_table(struct mm_struct *mm, int type); extern int free_pointer_table(void *table, int type); +extern void __tlb_remove_table(void *table); /* * Allocate and free page tables. The xxx_kernel() versions are @@ -47,7 +48,7 @@ static inline void pte_free(struct mm_st static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t pgtable, unsigned long address) { - free_pointer_table(pgtable, TABLE_PTE); + tlb_remove_table(tlb, (void *)((unsigned long)pgtable | TABLE_PTE)); } @@ -61,10 +62,10 @@ static inline int pmd_free(struct mm_str return free_pointer_table(pmd, TABLE_PMD); } -static inline int __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd, - unsigned long address) +static inline void __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd, + unsigned long address) { - return free_pointer_table(pmd, TABLE_PMD); + tlb_remove_table(tlb, (void *)((unsigned long)pmd | TABLE_PMD)); } --- a/arch/m68k/Kconfig~mm-enable-mmu_gather_rcu_table_free-for-m68k-motorola +++ a/arch/m68k/Kconfig @@ -29,6 +29,7 @@ config M68K select HAVE_ARCH_LIBGCC_H select HAVE_ARCH_SECCOMP select HAVE_ARCH_SECCOMP_FILTER + select HAVE_ARCH_TLB_REMOVE_TABLE if MMU_MOTOROLA select HAVE_ASM_MODVERSIONS select HAVE_DEBUG_BUGVERBOSE select HAVE_EFFICIENT_UNALIGNED_ACCESS if !CPU_HAS_NO_UNALIGNED @@ -36,7 +37,7 @@ config M68K select HAVE_MOD_ARCH_SPECIFIC select HAVE_UID16 select MMU_GATHER_NO_RANGE if MMU - select MMU_GATHER_RCU_TABLE_FREE if MMU && (SUN3 || COLDFIRE) + select MMU_GATHER_RCU_TABLE_FREE if MMU select MODULES_USE_ELF_REL select MODULES_USE_ELF_RELA select NO_DMA if !MMU && !COLDFIRE --- a/arch/m68k/mm/motorola.c~mm-enable-mmu_gather_rcu_table_free-for-m68k-motorola +++ a/arch/m68k/mm/motorola.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -103,6 +104,8 @@ static struct list_head ptable_list[3] = LIST_HEAD_INIT(ptable_list[2]), }; +static DEFINE_SPINLOCK(ptable_lock); + #define PD_PTABLE(ptdesc) ((ptable_desc *)&(virt_to_ptdesc((void *)(ptdesc))->pt_list)) #define PD_PTDESC(ptable) (list_entry(ptable, struct ptdesc, pt_list)) #define PD_MARKBITS(dp) (*(unsigned int *)&PD_PTDESC(dp)->pt_index) @@ -139,52 +142,66 @@ void __init init_pointer_table(void *tab return; } +/* + * For a pointer table for a user process address space, a + * table is taken from a ptdesc allocated for the purpose. Each + * ptdesc can hold 8 pointer tables. The ptdesc is remapped in + * virtual address space to be noncacheable. + */ +static void *add_pointer_table(struct mm_struct *mm, int type) +{ + struct ptdesc *ptdesc; + ptable_desc *new; + void *pt_addr; + + ptdesc = pagetable_alloc(GFP_KERNEL | __GFP_ZERO, 0); + if (!ptdesc) + return NULL; + + pt_addr = ptdesc_address(ptdesc); + + switch (type) { + case TABLE_PTE: + /* + * m68k doesn't have SPLIT_PTE_PTLOCKS for not having + * SMP. + */ + pagetable_pte_ctor(mm, ptdesc); + break; + case TABLE_PMD: + pagetable_pmd_ctor(mm, ptdesc); + break; + case TABLE_PGD: + pagetable_pgd_ctor(ptdesc); + break; + } + + mmu_page_ctor(pt_addr); + + new = PD_PTABLE(pt_addr); + + PD_MARKBITS(new) = ptable_mask(type) - 1; + scoped_guard(spinlock_irqsave, &ptable_lock) + list_add(new, &ptable_list[type]); + + return (pmd_t *)pt_addr; +} + void *get_pointer_table(struct mm_struct *mm, int type) { - ptable_desc *dp = ptable_list[type].next; - unsigned int mask = list_empty(&ptable_list[type]) ? 0 : PD_MARKBITS(dp); unsigned int tmp, off; + unsigned long mask; + unsigned long flags; + ptable_desc *dp; + void *ret; - /* - * For a pointer table for a user process address space, a - * table is taken from a ptdesc allocated for the purpose. Each - * ptdesc can hold 8 pointer tables. The ptdesc is remapped in - * virtual address space to be noncacheable. - */ - if (mask == 0) { - struct ptdesc *ptdesc; - ptable_desc *new; - void *pt_addr; - - ptdesc = pagetable_alloc(GFP_KERNEL | __GFP_ZERO, 0); - if (!ptdesc) - return NULL; - - pt_addr = ptdesc_address(ptdesc); - - switch (type) { - case TABLE_PTE: - /* - * m68k doesn't have SPLIT_PTE_PTLOCKS for not having - * SMP. - */ - pagetable_pte_ctor(mm, ptdesc); - break; - case TABLE_PMD: - pagetable_pmd_ctor(mm, ptdesc); - break; - case TABLE_PGD: - pagetable_pgd_ctor(ptdesc); - break; - } - - mmu_page_ctor(pt_addr); - - new = PD_PTABLE(pt_addr); - PD_MARKBITS(new) = ptable_mask(type) - 1; - list_add_tail(new, dp); + spin_lock_irqsave(&ptable_lock, flags); + dp = ptable_list[type].next; + mask = list_empty(&ptable_list[type]) ? 0 : PD_MARKBITS(dp); - return (pmd_t *)pt_addr; + if (mask == 0) { + spin_unlock_irqrestore(&ptable_lock, flags); + return add_pointer_table(mm, type); } for (tmp = 1, off = 0; (mask & tmp) == 0; tmp <<= 1, off += ptable_size(type)) @@ -194,7 +211,10 @@ void *get_pointer_table(struct mm_struct /* move to end of list */ list_move_tail(dp, &ptable_list[type]); } - return ptdesc_address(PD_PTDESC(dp)) + off; + + ret = ptdesc_address(PD_PTDESC(dp)) + off; + spin_unlock_irqrestore(&ptable_lock, flags); + return ret; } int free_pointer_table(void *table, int type) @@ -203,6 +223,9 @@ int free_pointer_table(void *table, int unsigned long ptable = (unsigned long)table; unsigned long pt_addr = ptable & PAGE_MASK; unsigned int mask = 1U << ((ptable - pt_addr)/ptable_size(type)); + unsigned long flags; + + spin_lock_irqsave(&ptable_lock, flags); dp = PD_PTABLE(pt_addr); if (PD_MARKBITS (dp) & mask) @@ -213,6 +236,8 @@ int free_pointer_table(void *table, int if (PD_MARKBITS(dp) == ptable_mask(type)) { /* all tables in ptdesc are free, free ptdesc */ list_del(dp); + spin_unlock_irqrestore(&ptable_lock, flags); + mmu_page_dtor((void *)pt_addr); pagetable_dtor_free(virt_to_ptdesc((void *)pt_addr)); return 1; @@ -223,9 +248,21 @@ int free_pointer_table(void *table, int */ list_move(dp, &ptable_list[type]); } + + spin_unlock_irqrestore(&ptable_lock, flags); return 0; } +void __tlb_remove_table(void *table) +{ + /* The bottom 2 bits are used to encode page table type. */ + const unsigned long encoded = (unsigned long)table; + void *addr = (void *)(encoded & ~3UL); + const int type = encoded & 3; + + free_pointer_table(addr, type); +} + /* size of memory already mapped in head.S */ extern __initdata unsigned long m68k_init_mapped_size; _ Patches currently in -mm which might be from ljs@kernel.org are mm-vma-correctly-unaccount-on-mmap_prepare-failure.patch mm-vmpressure-remove-window-size-todo.patch tools-testing-selftests-mm-add-missing-gitignore-entries.patch mm-move-drivers-char-memc-to-mm-char-memc.patch mm-implement-file_is_dev_zero-to-uniquely-identify-dev-zero.patch mm-vma-only-permit-map_private-dev-zero-to-be-mapped-anonymous.patch mm-vma-make-map_private-mapped-dev-zero-mappings-truly-anonymous.patch tools-testing-vma-add-test-to-assert-map_private-dev-zero-is-anon.patch tools-testing-selftests-mm-add-map_private-dev-zero-merge-tests.patch mm-madvise-swap-in-cowd-map_private-file-mappings-on-madv_willneed.patch mm-huge_memory-zap-deposited-page-tables-after-an-rcu-grace-period.patch mm-enable-mmu_gather_rcu_table_free-for-most-2-level-architectures.patch mm-enable-mmu_gather_rcu_table_free-for-mmu-riscv.patch mm-enable-mmu_gather_rcu_table_free-for-mmu-arm.patch mm-enable-mmu_gather_rcu_table_free-for-arc-microblaze-xtensa.patch mm-enable-mmu_gather_rcu_table_free-for-sparc64.patch mm-enable-mmu_gather_rcu_table_free-for-m68k-coldfire.patch mm-enable-mmu_gather_rcu_table_free-for-sh-x2.patch mm-enable-mmu_gather_rcu_table_free-for-m68k-motorola.patch mm-enable-mmu_gather_rcu_table_free-for-sparc32.patch mm-make-userland-page-table-freeing-rcu-safe.patch mm-change-the-contract-for-free_pgtables-update-docs.patch