Messages in this thread Patch in this message | | | Subject | Adding "addr" argument to __{pte,pmd,pud}_free_tlb() | From | Benjamin Herrenschmidt <> | Date | Tue, 02 Jun 2009 15:02:44 +1000 |
| |
Hi !
For some new powerpc variant support where I'm doing tricks with the mapping of PTE pages I need to know the virtual address represented by the base of a PTE page.
I could use the old technique of sticking stuff in the struct page of the PTE page but that sucks since all callsites have it already close by.
So before I do a giant patch adding the argument to all archs, here's a quick check to see there's no objection. The basic patch for the core code and powerpc arch only is below. If nobody goes onto a tantrum over the next few weeks, then I'll produce a new variant that fixes all archs.
Note: In theory I only need it for __pte_free_tlb() but it's readily available at the callsite for the others and so it's basically free so it's better to have the API be consistent for all 3 call types.
Cheers, Ben.
Index: linux-work/arch/powerpc/include/asm/pgalloc-32.h =================================================================== --- linux-work.orig/arch/powerpc/include/asm/pgalloc-32.h 2009-04-01 16:32:01.000000000 +1100 +++ linux-work/arch/powerpc/include/asm/pgalloc-32.h 2009-04-01 16:32:03.000000000 +1100 @@ -16,7 +16,7 @@ extern void pgd_free(struct mm_struct *m */ /* #define pmd_alloc_one(mm,address) ({ BUG(); ((pmd_t *)2); }) */ #define pmd_free(mm, x) do { } while (0) -#define __pmd_free_tlb(tlb,x) do { } while (0) +#define __pmd_free_tlb(tlb,x,a) do { } while (0) /* #define pgd_populate(mm, pmd, pte) BUG() */ #ifndef CONFIG_BOOKE Index: linux-work/arch/powerpc/include/asm/pgalloc-64.h =================================================================== --- linux-work.orig/arch/powerpc/include/asm/pgalloc-64.h 2009-04-01 16:32:12.000000000 +1100 +++ linux-work/arch/powerpc/include/asm/pgalloc-64.h 2009-04-01 16:32:21.000000000 +1100 @@ -118,11 +118,11 @@ static inline void pgtable_free(pgtable_ kmem_cache_free(pgtable_cache[cachenum], p); } -#define __pmd_free_tlb(tlb, pmd) \ +#define __pmd_free_tlb(tlb, pmd,addr) \ pgtable_free_tlb(tlb, pgtable_free_cache(pmd, \ PMD_CACHE_NUM, PMD_TABLE_SIZE-1)) #ifndef CONFIG_PPC_64K_PAGES -#define __pud_free_tlb(tlb, pud) \ +#define __pud_free_tlb(tlb, pud, addr) \ pgtable_free_tlb(tlb, pgtable_free_cache(pud, \ PUD_CACHE_NUM, PUD_TABLE_SIZE-1)) #endif /* CONFIG_PPC_64K_PAGES */ Index: linux-work/arch/powerpc/include/asm/pgalloc.h =================================================================== --- linux-work.orig/arch/powerpc/include/asm/pgalloc.h 2009-04-01 16:31:33.000000000 +1100 +++ linux-work/arch/powerpc/include/asm/pgalloc.h 2009-04-01 16:31:43.000000000 +1100 @@ -38,14 +38,14 @@ static inline pgtable_free_t pgtable_fre extern void pgtable_free_tlb(struct mmu_gather *tlb, pgtable_free_t pgf); #ifdef CONFIG_SMP -#define __pte_free_tlb(tlb,ptepage) \ +#define __pte_free_tlb(tlb,ptepage,address) \ do { \ pgtable_page_dtor(ptepage); \ pgtable_free_tlb(tlb, pgtable_free_cache(page_address(ptepage), \ PTE_NONCACHE_NUM, PTE_TABLE_SIZE-1)); \ } while (0) #else -#define __pte_free_tlb(tlb, pte) pte_free((tlb)->mm, (pte)) +#define __pte_free_tlb(tlb, pte, address) pte_free((tlb)->mm, (pte)) #endif Index: linux-work/include/asm-generic/pgtable-nopmd.h =================================================================== --- linux-work.orig/include/asm-generic/pgtable-nopmd.h 2009-04-01 16:32:57.000000000 +1100 +++ linux-work/include/asm-generic/pgtable-nopmd.h 2009-04-01 16:33:03.000000000 +1100 @@ -59,7 +59,7 @@ static inline pmd_t * pmd_offset(pud_t * static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd) { } -#define __pmd_free_tlb(tlb, x) do { } while (0) +#define __pmd_free_tlb(tlb, x, a) do { } while (0) #undef pmd_addr_end #define pmd_addr_end(addr, end) (end) Index: linux-work/include/asm-generic/pgtable-nopud.h =================================================================== --- linux-work.orig/include/asm-generic/pgtable-nopud.h 2009-04-01 16:32:40.000000000 +1100 +++ linux-work/include/asm-generic/pgtable-nopud.h 2009-04-01 16:32:44.000000000 +1100 @@ -52,7 +52,7 @@ static inline pud_t * pud_offset(pgd_t * */ #define pud_alloc_one(mm, address) NULL #define pud_free(mm, x) do { } while (0) -#define __pud_free_tlb(tlb, x) do { } while (0) +#define __pud_free_tlb(tlb, x, a) do { } while (0) #undef pud_addr_end #define pud_addr_end(addr, end) (end) Index: linux-work/include/asm-generic/tlb.h =================================================================== --- linux-work.orig/include/asm-generic/tlb.h 2009-04-01 16:28:50.000000000 +1100 +++ linux-work/include/asm-generic/tlb.h 2009-04-01 16:29:20.000000000 +1100 @@ -123,24 +123,24 @@ static inline void tlb_remove_page(struc __tlb_remove_tlb_entry(tlb, ptep, address); \ } while (0) -#define pte_free_tlb(tlb, ptep) \ +#define pte_free_tlb(tlb, ptep, address) \ do { \ tlb->need_flush = 1; \ - __pte_free_tlb(tlb, ptep); \ + __pte_free_tlb(tlb, ptep, address); \ } while (0) #ifndef __ARCH_HAS_4LEVEL_HACK -#define pud_free_tlb(tlb, pudp) \ +#define pud_free_tlb(tlb, pudp, address) \ do { \ tlb->need_flush = 1; \ - __pud_free_tlb(tlb, pudp); \ + __pud_free_tlb(tlb, pudp, address); \ } while (0) #endif -#define pmd_free_tlb(tlb, pmdp) \ +#define pmd_free_tlb(tlb, pmdp, address) \ do { \ tlb->need_flush = 1; \ - __pmd_free_tlb(tlb, pmdp); \ + __pmd_free_tlb(tlb, pmdp, address); \ } while (0) #define tlb_migrate_finish(mm) do {} while (0) Index: linux-work/mm/memory.c =================================================================== --- linux-work.orig/mm/memory.c 2009-04-01 16:30:05.000000000 +1100 +++ linux-work/mm/memory.c 2009-04-01 16:30:48.000000000 +1100 @@ -135,11 +135,12 @@ void pmd_clear_bad(pmd_t *pmd) * Note: this doesn't free the actual pages themselves. That * has been handled earlier when unmapping all the memory regions. */ -static void free_pte_range(struct mmu_gather *tlb, pmd_t *pmd) +static void free_pte_range(struct mmu_gather *tlb, pmd_t *pmd, + unsigned long addr) { pgtable_t token = pmd_pgtable(*pmd); pmd_clear(pmd); - pte_free_tlb(tlb, token); + pte_free_tlb(tlb, token, addr); tlb->mm->nr_ptes--; } @@ -157,7 +158,7 @@ static inline void free_pmd_range(struct next = pmd_addr_end(addr, end); if (pmd_none_or_clear_bad(pmd)) continue; - free_pte_range(tlb, pmd); + free_pte_range(tlb, pmd, addr); } while (pmd++, addr = next, addr != end); start &= PUD_MASK; @@ -173,7 +174,7 @@ static inline void free_pmd_range(struct pmd = pmd_offset(pud, start); pud_clear(pud); - pmd_free_tlb(tlb, pmd); + pmd_free_tlb(tlb, pmd, start); } static inline void free_pud_range(struct mmu_gather *tlb, pgd_t *pgd, @@ -206,7 +207,7 @@ static inline void free_pud_range(struct pud = pud_offset(pgd, start); pgd_clear(pgd); - pud_free_tlb(tlb, pud); + pud_free_tlb(tlb, pud, start); } /*
| |