Before commit 718b13861d22 ("x86: mm: free page table pages by RCU instead of semi RCU"), the page table pages will be freed by semi RCU, that is: - batch table freeing: asynchronous free by RCU - single table freeing: IPI + synchronous free This commit introduce a RCU version for single table freeing to support PT_RECLAIM. While it is not necessary to limit the RCU version only in CONFIG_PT_RECLAIM. It is reasonable to asynchronous free single table by RCU if CONFIG_MMU_GATHER_RCU_TABLE_FREE. This patch moves the definition of single table freeing in CONFIG_MMU_GATHER_RCU_TABLE_FREE, so we have both RCU version batch/single table freeing if CONFIG_MMU_GATHER_RCU_TABLE_FREE. Signed-off-by: Wei Yang Cc: Qi Zheng Cc: "David Hildenbrand (Arm)" --- mm/mmu_gather.c | 51 +++++++++++++++++++++---------------------------- 1 file changed, 22 insertions(+), 29 deletions(-) diff --git a/mm/mmu_gather.c b/mm/mmu_gather.c index fe5b6a031717..6c1cbd9c717b 100644 --- a/mm/mmu_gather.c +++ b/mm/mmu_gather.c @@ -296,6 +296,22 @@ static void tlb_remove_table_free(struct mmu_table_batch *batch) call_rcu(&batch->rcu, tlb_remove_table_rcu); } +static inline void __tlb_remove_table_one_rcu(struct rcu_head *head) +{ + struct ptdesc *ptdesc; + + ptdesc = container_of(head, struct ptdesc, pt_rcu_head); + __tlb_remove_table(ptdesc); +} + +static inline void tlb_remove_table_one(void *table) +{ + struct ptdesc *ptdesc; + + ptdesc = table; + call_rcu(&ptdesc->pt_rcu_head, __tlb_remove_table_one_rcu); +} + #else /* !CONFIG_MMU_GATHER_RCU_TABLE_FREE */ static void tlb_remove_table_free(struct mmu_table_batch *batch) @@ -303,6 +319,12 @@ static void tlb_remove_table_free(struct mmu_table_batch *batch) __tlb_remove_table_free(batch); } +static inline void tlb_remove_table_one(void *table) +{ + tlb_remove_table_sync_one(); + __tlb_remove_table(table); +} + #endif /* CONFIG_MMU_GATHER_RCU_TABLE_FREE */ /* @@ -320,35 +342,6 @@ static inline void tlb_table_invalidate(struct mmu_gather *tlb) } } -#ifdef CONFIG_PT_RECLAIM -static inline void __tlb_remove_table_one_rcu(struct rcu_head *head) -{ - struct ptdesc *ptdesc; - - ptdesc = container_of(head, struct ptdesc, pt_rcu_head); - __tlb_remove_table(ptdesc); -} - -static inline void __tlb_remove_table_one(void *table) -{ - struct ptdesc *ptdesc; - - ptdesc = table; - call_rcu(&ptdesc->pt_rcu_head, __tlb_remove_table_one_rcu); -} -#else -static inline void __tlb_remove_table_one(void *table) -{ - tlb_remove_table_sync_one(); - __tlb_remove_table(table); -} -#endif /* CONFIG_PT_RECLAIM */ - -static void tlb_remove_table_one(void *table) -{ - __tlb_remove_table_one(table); -} - static void tlb_table_flush(struct mmu_gather *tlb) { struct mmu_table_batch **batch = &tlb->batch; -- 2.34.1