diff options
| author | Linus Torvalds <torvalds@home.transmeta.com> | 2002-05-15 09:18:09 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@penguin.transmeta.com> | 2002-05-15 09:18:09 -0700 |
| commit | e9d00e5cb88db3f2d29aa89938e90e4011b735f2 (patch) | |
| tree | 8bc8fc903daf71fa0cf697a5400c04feeb1fd38a /include | |
| parent | 7c9d187e950db8c6fbccc9e260b2ed6779845f6d (diff) | |
This improves on the page table TLB shootdown. Almost there.
Diffstat (limited to 'include')
| -rw-r--r-- | include/asm-generic/tlb.h | 44 | ||||
| -rw-r--r-- | include/asm-i386/pgalloc.h | 4 | ||||
| -rw-r--r-- | include/linux/mm.h | 2 |
3 files changed, 16 insertions, 34 deletions
diff --git a/include/asm-generic/tlb.h b/include/asm-generic/tlb.h index bc1c3aec9c1a..0e5c08cec926 100644 --- a/include/asm-generic/tlb.h +++ b/include/asm-generic/tlb.h @@ -28,8 +28,7 @@ typedef struct free_pte_ctx { struct mm_struct *mm; unsigned long nr; /* set to ~0UL means fast mode */ unsigned long freed; - unsigned long start_addr, end_addr; - pte_t ptes[FREE_PTE_NR]; + struct page * pages[FREE_PTE_NR]; } mmu_gather_t; /* Users of the generic TLB shootdown code must declare this storage space. */ @@ -55,20 +54,15 @@ static inline mmu_gather_t *tlb_gather_mmu(struct mm_struct *mm) static inline void tlb_flush_mmu(mmu_gather_t *tlb, unsigned long start, unsigned long end) { - unsigned long i, nr; + unsigned long nr; - /* Handle the fast case first. */ - if (tlb->nr == ~0UL) { - flush_tlb_mm(tlb->mm); - return; - } + flush_tlb_mm(tlb->mm); nr = tlb->nr; - tlb->nr = 0; - if (nr) - flush_tlb_mm(tlb->mm); - for (i=0; i < nr; i++) { - pte_t pte = tlb->ptes[i]; - __free_pte(pte); + if (nr != ~0UL) { + unsigned long i; + tlb->nr = 0; + for (i=0; i < nr; i++) + free_page_and_swap_cache(tlb->pages[i]); } } @@ -85,7 +79,6 @@ static inline void tlb_finish_mmu(mmu_gather_t *tlb, unsigned long start, unsign if (rss < freed) freed = rss; mm->rss = rss - freed; - tlb_flush_mmu(tlb, start, end); } @@ -95,29 +88,16 @@ static inline void tlb_finish_mmu(mmu_gather_t *tlb, unsigned long start, unsign * handling the additional races in SMP caused by other CPUs caching valid * mappings in their TLBs. */ -static inline void tlb_remove_page(mmu_gather_t *tlb, pte_t *pte, unsigned long addr) +static inline void tlb_remove_page(mmu_gather_t *tlb, struct page *page) { - struct page *page; - unsigned long pfn = pte_pfn(*pte); - - if (pfn_valid(pfn)) { - page = pfn_to_page(pfn); - if (!PageReserved(page)) - tlb->freed++; - } - /* Handle the common case fast, first. */\ if (tlb->nr == ~0UL) { - __free_pte(*pte); - pte_clear(pte); + free_page_and_swap_cache(page); return; } - if (!tlb->nr) - tlb->start_addr = addr; - tlb->ptes[tlb->nr++] = ptep_get_and_clear(pte); - tlb->end_addr = addr + PAGE_SIZE; + tlb->pages[tlb->nr++] = page; if (tlb->nr >= FREE_PTE_NR) - tlb_finish_mmu(tlb, 0, 0); + tlb_flush_mmu(tlb, 0, 0); } #endif /* _ASM_GENERIC__TLB_H */ diff --git a/include/asm-i386/pgalloc.h b/include/asm-i386/pgalloc.h index b078cdd4adaa..10e7021c33a6 100644 --- a/include/asm-i386/pgalloc.h +++ b/include/asm-i386/pgalloc.h @@ -35,6 +35,9 @@ static inline void pte_free(struct page *pte) __free_page(pte); } + +#define pte_free_tlb(tlb,pte) tlb_remove_page((tlb),(pte)) + /* * allocating and freeing a pmd is trivial: the 1-entry pmd is * inside the pgd, so has no extra memory associated with it. @@ -43,6 +46,7 @@ static inline void pte_free(struct page *pte) #define pmd_alloc_one(mm, addr) ({ BUG(); ((pmd_t *)2); }) #define pmd_free(x) do { } while (0) +#define pmd_free_tlb(tlb,x) do { } while (0) #define pgd_populate(mm, pmd, pte) BUG() #define check_pgt_cache() do { } while (0) diff --git a/include/linux/mm.h b/include/linux/mm.h index 9d92b69a8c36..2f0b56f0183b 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -311,8 +311,6 @@ extern mem_map_t * mem_map; extern void show_free_areas(void); extern void show_free_areas_node(pg_data_t *pgdat); -extern void clear_page_tables(struct mm_struct *, unsigned long, int); - extern int fail_writepage(struct page *); struct page * shmem_nopage(struct vm_area_struct * vma, unsigned long address, int unused); struct file *shmem_file_setup(char * name, loff_t size); |
