Message ID | f8d84fb8-eb9-6649-7137-715c6010468c@google.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | mm: free retracted page table by RCU | expand |
On Sun, 28 May 2023, Hugh Dickins wrote: > Add sparc-specific pte_free_defer(), to call pte_free() via call_rcu(). > pte_free_defer() will be called inside khugepaged's retract_page_tables() > loop, where allocating extra memory cannot be relied upon. This precedes > the generic version to avoid build breakage from incompatible pgtable_t. sparc32 supports pagetables sharing a page, but does not support THP; sparc64 supports THP, but does not support pagetables sharing a page. So the sparc-specific pte_free_defer() is as simple as the generic one, except for converting between pte_t *pgtable_t and struct page *. The patch should be fine as posted (except its title is misleading). > > Signed-off-by: Hugh Dickins <hughd@google.com> > --- > arch/sparc/include/asm/pgalloc_64.h | 4 ++++ > arch/sparc/mm/init_64.c | 16 ++++++++++++++++ > 2 files changed, 20 insertions(+) > > diff --git a/arch/sparc/include/asm/pgalloc_64.h b/arch/sparc/include/asm/pgalloc_64.h > index 7b5561d17ab1..caa7632be4c2 100644 > --- a/arch/sparc/include/asm/pgalloc_64.h > +++ b/arch/sparc/include/asm/pgalloc_64.h > @@ -65,6 +65,10 @@ pgtable_t pte_alloc_one(struct mm_struct *mm); > void pte_free_kernel(struct mm_struct *mm, pte_t *pte); > void pte_free(struct mm_struct *mm, pgtable_t ptepage); > > +/* arch use pte_free_defer() implementation in arch/sparc/mm/init_64.c */ > +#define pte_free_defer pte_free_defer > +void pte_free_defer(struct mm_struct *mm, pgtable_t pgtable); > + > #define pmd_populate_kernel(MM, PMD, PTE) pmd_set(MM, PMD, PTE) > #define pmd_populate(MM, PMD, PTE) pmd_set(MM, PMD, PTE) > > diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c > index 04f9db0c3111..b7c6aa085ef6 100644 > --- a/arch/sparc/mm/init_64.c > +++ b/arch/sparc/mm/init_64.c > @@ -2930,6 +2930,22 @@ void pgtable_free(void *table, bool is_page) > } > > #ifdef CONFIG_TRANSPARENT_HUGEPAGE > +static void pte_free_now(struct rcu_head *head) > +{ > + struct page *page; > + > + page = container_of(head, struct page, rcu_head); > + __pte_free((pgtable_t)page_to_virt(page)); > +} > + > +void pte_free_defer(struct mm_struct *mm, pgtable_t pgtable) > +{ > + struct page *page; > + > + page = virt_to_page(pgtable); > + call_rcu(&page->rcu_head, pte_free_now); > +} > + > void update_mmu_cache_pmd(struct vm_area_struct *vma, unsigned long addr, > pmd_t *pmd) > { > -- > 2.35.3 > >
diff --git a/arch/sparc/include/asm/pgalloc_64.h b/arch/sparc/include/asm/pgalloc_64.h index 7b5561d17ab1..caa7632be4c2 100644 --- a/arch/sparc/include/asm/pgalloc_64.h +++ b/arch/sparc/include/asm/pgalloc_64.h @@ -65,6 +65,10 @@ pgtable_t pte_alloc_one(struct mm_struct *mm); void pte_free_kernel(struct mm_struct *mm, pte_t *pte); void pte_free(struct mm_struct *mm, pgtable_t ptepage); +/* arch use pte_free_defer() implementation in arch/sparc/mm/init_64.c */ +#define pte_free_defer pte_free_defer +void pte_free_defer(struct mm_struct *mm, pgtable_t pgtable); + #define pmd_populate_kernel(MM, PMD, PTE) pmd_set(MM, PMD, PTE) #define pmd_populate(MM, PMD, PTE) pmd_set(MM, PMD, PTE) diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c index 04f9db0c3111..b7c6aa085ef6 100644 --- a/arch/sparc/mm/init_64.c +++ b/arch/sparc/mm/init_64.c @@ -2930,6 +2930,22 @@ void pgtable_free(void *table, bool is_page) } #ifdef CONFIG_TRANSPARENT_HUGEPAGE +static void pte_free_now(struct rcu_head *head) +{ + struct page *page; + + page = container_of(head, struct page, rcu_head); + __pte_free((pgtable_t)page_to_virt(page)); +} + +void pte_free_defer(struct mm_struct *mm, pgtable_t pgtable) +{ + struct page *page; + + page = virt_to_page(pgtable); + call_rcu(&page->rcu_head, pte_free_now); +} + void update_mmu_cache_pmd(struct vm_area_struct *vma, unsigned long addr, pmd_t *pmd) {
Add sparc-specific pte_free_defer(), to call pte_free() via call_rcu(). pte_free_defer() will be called inside khugepaged's retract_page_tables() loop, where allocating extra memory cannot be relied upon. This precedes the generic version to avoid build breakage from incompatible pgtable_t. Signed-off-by: Hugh Dickins <hughd@google.com> --- arch/sparc/include/asm/pgalloc_64.h | 4 ++++ arch/sparc/mm/init_64.c | 16 ++++++++++++++++ 2 files changed, 20 insertions(+)