summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@home.transmeta.com>2002-05-15 09:18:09 -0700
committerLinus Torvalds <torvalds@penguin.transmeta.com>2002-05-15 09:18:09 -0700
commite9d00e5cb88db3f2d29aa89938e90e4011b735f2 (patch)
tree8bc8fc903daf71fa0cf697a5400c04feeb1fd38a /include
parent7c9d187e950db8c6fbccc9e260b2ed6779845f6d (diff)
This improves on the page table TLB shootdown. Almost there.
Diffstat (limited to 'include')
-rw-r--r--include/asm-generic/tlb.h44
-rw-r--r--include/asm-i386/pgalloc.h4
-rw-r--r--include/linux/mm.h2
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);