diff -urN v2.4.2-pre3/arch/alpha/mm/init.c work-v2.4.2-pre3/arch/alpha/mm/init.c --- v2.4.2-pre3/arch/alpha/mm/init.c Wed Nov 29 01:43:39 2000 +++ work-v2.4.2-pre3/arch/alpha/mm/init.c Mon Feb 12 16:35:09 2001 @@ -32,6 +32,9 @@ #include #include #include +#include + +mmu_gather_t mmu_gathers[NR_CPUS]; static unsigned long totalram_pages; diff -urN v2.4.2-pre3/arch/arm/mm/init.c work-v2.4.2-pre3/arch/arm/mm/init.c --- v2.4.2-pre3/arch/arm/mm/init.c Mon Feb 12 12:18:54 2001 +++ work-v2.4.2-pre3/arch/arm/mm/init.c Mon Feb 12 16:35:33 2001 @@ -33,6 +33,9 @@ #include #include +#include + +mmu_gather_t mmu_gathers[NR_CPUS]; #ifndef CONFIG_DISCONTIGMEM #define NR_NODES 1 diff -urN v2.4.2-pre3/arch/cris/mm/init.c work-v2.4.2-pre3/arch/cris/mm/init.c --- v2.4.2-pre3/arch/cris/mm/init.c Mon Feb 12 12:18:54 2001 +++ work-v2.4.2-pre3/arch/cris/mm/init.c Mon Feb 12 16:35:59 2001 @@ -57,6 +57,9 @@ #include #include #include +#include + +mmu_gather_t mmu_gathers[NR_CPUS]; static unsigned long totalram_pages; diff -urN v2.4.2-pre3/arch/i386/boot/install.sh work-v2.4.2-pre3/arch/i386/boot/install.sh --- v2.4.2-pre3/arch/i386/boot/install.sh Tue Jan 3 06:57:26 1995 +++ work-v2.4.2-pre3/arch/i386/boot/install.sh Mon Feb 12 16:32:48 2001 @@ -21,6 +21,7 @@ # User may have a custom install script +if [ -x ~/bin/installkernel ]; then exec ~/bin/installkernel "$@"; fi if [ -x /sbin/installkernel ]; then exec /sbin/installkernel "$@"; fi # Default install - same as make zlilo diff -urN v2.4.2-pre3/arch/i386/mm/init.c work-v2.4.2-pre3/arch/i386/mm/init.c --- v2.4.2-pre3/arch/i386/mm/init.c Tue Jan 30 14:38:49 2001 +++ work-v2.4.2-pre3/arch/i386/mm/init.c Mon Feb 12 16:32:48 2001 @@ -35,7 +35,9 @@ #include #include #include +#include +mmu_gather_t mmu_gathers[NR_CPUS]; unsigned long highstart_pfn, highend_pfn; static unsigned long totalram_pages; static unsigned long totalhigh_pages; diff -urN v2.4.2-pre3/arch/ia64/mm/init.c work-v2.4.2-pre3/arch/ia64/mm/init.c --- v2.4.2-pre3/arch/ia64/mm/init.c Thu Jan 4 15:50:17 2001 +++ work-v2.4.2-pre3/arch/ia64/mm/init.c Mon Feb 12 16:36:33 2001 @@ -23,6 +23,9 @@ #include #include #include +#include + +mmu_gather_t mmu_gathers[NR_CPUS]; /* References to section boundaries: */ extern char _stext, _etext, _edata, __init_begin, __init_end; diff -urN v2.4.2-pre3/arch/m68k/mm/init.c work-v2.4.2-pre3/arch/m68k/mm/init.c --- v2.4.2-pre3/arch/m68k/mm/init.c Mon Oct 16 15:58:51 2000 +++ work-v2.4.2-pre3/arch/m68k/mm/init.c Mon Feb 12 16:36:52 2001 @@ -31,6 +31,9 @@ #ifdef CONFIG_ATARI #include #endif +#include + +mmu_gather_t mmu_gathers[NR_CPUS]; static unsigned long totalram_pages; diff -urN v2.4.2-pre3/arch/mips/mm/init.c work-v2.4.2-pre3/arch/mips/mm/init.c --- v2.4.2-pre3/arch/mips/mm/init.c Mon Oct 16 15:58:51 2000 +++ work-v2.4.2-pre3/arch/mips/mm/init.c Mon Feb 12 16:37:33 2001 @@ -38,6 +38,9 @@ #include #endif #include +#include + +mmu_gather_t mmu_gathers[NR_CPUS]; static unsigned long totalram_pages; diff -urN v2.4.2-pre3/arch/mips64/mm/init.c work-v2.4.2-pre3/arch/mips64/mm/init.c --- v2.4.2-pre3/arch/mips64/mm/init.c Mon Oct 16 15:58:51 2000 +++ work-v2.4.2-pre3/arch/mips64/mm/init.c Mon Feb 12 16:37:18 2001 @@ -37,6 +37,9 @@ #include #endif #include +#include + +mmu_gather_t mmu_gathers[NR_CPUS]; unsigned long totalram_pages; diff -urN v2.4.2-pre3/arch/parisc/mm/init.c work-v2.4.2-pre3/arch/parisc/mm/init.c --- v2.4.2-pre3/arch/parisc/mm/init.c Tue Dec 5 15:29:39 2000 +++ work-v2.4.2-pre3/arch/parisc/mm/init.c Mon Feb 12 16:37:56 2001 @@ -19,6 +19,9 @@ #include #include +#include + +mmu_gather_t mmu_gathers[NR_CPUS]; static unsigned long totalram_pages; extern unsigned long max_pfn, mem_max; diff -urN v2.4.2-pre3/arch/ppc/mm/init.c work-v2.4.2-pre3/arch/ppc/mm/init.c --- v2.4.2-pre3/arch/ppc/mm/init.c Tue Jan 30 14:38:50 2001 +++ work-v2.4.2-pre3/arch/ppc/mm/init.c Mon Feb 12 16:38:26 2001 @@ -67,6 +67,9 @@ #if defined(CONFIG_4xx) #include "4xx_tlb.h" #endif +#include + +mmu_gather_t mmu_gathers[NR_CPUS]; #define MAX_LOW_MEM (512 << 20) diff -urN v2.4.2-pre3/arch/s390/mm/init.c work-v2.4.2-pre3/arch/s390/mm/init.c --- v2.4.2-pre3/arch/s390/mm/init.c Wed Nov 29 01:43:39 2000 +++ work-v2.4.2-pre3/arch/s390/mm/init.c Mon Feb 12 16:38:43 2001 @@ -35,6 +35,9 @@ #include #include #include +#include + +mmu_gather_t mmu_gathers[NR_CPUS]; static unsigned long totalram_pages; diff -urN v2.4.2-pre3/arch/sh/mm/init.c work-v2.4.2-pre3/arch/sh/mm/init.c --- v2.4.2-pre3/arch/sh/mm/init.c Wed Nov 29 01:43:39 2000 +++ work-v2.4.2-pre3/arch/sh/mm/init.c Mon Feb 12 16:38:59 2001 @@ -34,6 +34,9 @@ #include #include #include +#include + +mmu_gather_t mmu_gathers[NR_CPUS]; /* * Cache of MMU context last used. diff -urN v2.4.2-pre3/arch/sparc/mm/init.c work-v2.4.2-pre3/arch/sparc/mm/init.c --- v2.4.2-pre3/arch/sparc/mm/init.c Mon Dec 11 15:37:03 2000 +++ work-v2.4.2-pre3/arch/sparc/mm/init.c Mon Feb 12 16:39:31 2001 @@ -32,6 +32,9 @@ #include #include #include +#include + +mmu_gather_t mmu_gathers[NR_CPUS]; unsigned long *sparc_valid_addr_bitmap; diff -urN v2.4.2-pre3/arch/sparc64/mm/init.c work-v2.4.2-pre3/arch/sparc64/mm/init.c --- v2.4.2-pre3/arch/sparc64/mm/init.c Mon Feb 12 12:18:55 2001 +++ work-v2.4.2-pre3/arch/sparc64/mm/init.c Mon Feb 12 16:39:16 2001 @@ -30,6 +30,9 @@ #include #include #include +#include + +mmu_gather_t mmu_gathers[NR_CPUS]; extern void device_scan(void); diff -urN v2.4.2-pre3/drivers/net/hamradio/soundmodem/gentbl.c work-v2.4.2-pre3/drivers/net/hamradio/soundmodem/gentbl.c --- v2.4.2-pre3/drivers/net/hamradio/soundmodem/gentbl.c Thu Jun 25 15:25:16 1998 +++ work-v2.4.2-pre3/drivers/net/hamradio/soundmodem/gentbl.c Mon Feb 12 16:32:48 2001 @@ -26,6 +26,7 @@ */ #include +#include #include #include diff -urN v2.4.2-pre3/include/asm-alpha/tlb.h work-v2.4.2-pre3/include/asm-alpha/tlb.h --- v2.4.2-pre3/include/asm-alpha/tlb.h Wed Dec 31 19:00:00 1969 +++ work-v2.4.2-pre3/include/asm-alpha/tlb.h Mon Feb 12 16:33:44 2001 @@ -0,0 +1 @@ +#include diff -urN v2.4.2-pre3/include/asm-arm/tlb.h work-v2.4.2-pre3/include/asm-arm/tlb.h --- v2.4.2-pre3/include/asm-arm/tlb.h Wed Dec 31 19:00:00 1969 +++ work-v2.4.2-pre3/include/asm-arm/tlb.h Mon Feb 12 16:33:44 2001 @@ -0,0 +1 @@ +#include diff -urN v2.4.2-pre3/include/asm-cris/tlb.h work-v2.4.2-pre3/include/asm-cris/tlb.h --- v2.4.2-pre3/include/asm-cris/tlb.h Wed Dec 31 19:00:00 1969 +++ work-v2.4.2-pre3/include/asm-cris/tlb.h Mon Feb 12 16:33:44 2001 @@ -0,0 +1 @@ +#include diff -urN v2.4.2-pre3/include/asm-generic/tlb.h work-v2.4.2-pre3/include/asm-generic/tlb.h --- v2.4.2-pre3/include/asm-generic/tlb.h Wed Dec 31 19:00:00 1969 +++ work-v2.4.2-pre3/include/asm-generic/tlb.h Mon Feb 12 16:32:48 2001 @@ -0,0 +1,111 @@ +/* asm-generic/tlb.h + * + * Generic TLB shootdown code + * + * Copyright 2001 Red Hat, Inc. + * Based on code from mm/memory.c Copyright Linus Torvalds and others. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ +#ifndef _ASM_GENERIC__TLB_H +#define _ASM_GENERIC__TLB_H + +#ifdef CONFIG_SMP +/* aim for something that fits in the L1 cache */ +#define FREE_PTE_NR 508 + +/* mmu_gather_t is an opaque type used by the mm code for passing around any + * data needed by arch specific code for tlb_remove_page. This structure can + * be per-CPU or per-MM as the page table lock is held for the duration of TLB + * shootdown. + */ +typedef struct free_pte_ctx { + struct mm_struct *mm; + unsigned long nr; /* set to ~0UL means fast mode */ + unsigned long start_addr, end_addr; + pte_t ptes[FREE_PTE_NR]; +} mmu_gather_t; + +/* Users of the generic TLB shootdown code must declare this storage space. */ +extern mmu_gather_t mmu_gathers[NR_CPUS]; + +/* tlb_gather_mmu + * Return a pointer to an initialized mmu_gather_t. + */ +static inline mmu_gather_t *tlb_gather_mmu(struct mm_struct *mm) +{ + mmu_gather_t *tlb = &mmu_gathers[smp_processor_id()]; + + tlb->mm = mm; + /* Use fast mode if there is only one user of this mm (this process) */ + tlb->nr = (atomic_read(&(mm)->mm_users) == 1) ? ~0UL : 0UL; + return tlb; +} + +/* void tlb_remove_page(mmu_gather_t *tlb, pte_t *ptep, unsigned long addr) + * Must perform the equivalent to __free_pte(pte_get_and_clear(ptep)), while + * handling the additional races in SMP caused by other CPUs caching valid + * mappings in their TLBs. + */ +#define tlb_remove_page(ctxp, pte, addr) do {\ + /* Handle the common case fast, first. */\ + if ((ctxp)->nr == ~0UL) {\ + __free_pte(*(pte));\ + pte_clear((pte));\ + break;\ + }\ + if (!(ctxp)->nr) \ + (ctxp)->start_addr = (addr);\ + (ctxp)->ptes[(ctxp)->nr++] = ptep_get_and_clear(pte);\ + (ctxp)->end_addr = (addr) + PAGE_SIZE;\ + if ((ctxp)->nr >= FREE_PTE_NR)\ + tlb_finish_mmu((ctxp), 0, 0);\ + } while (0) + +/* tlb_finish_mmu + * Called at the end of the shootdown operation to free up any resources + * that were required. The page talbe lock is still held at this point. + */ +static inline void tlb_finish_mmu(struct free_pte_ctx *ctx, unsigned long start, unsigned long end) +{ + unsigned long i, nr; + + /* Handle the fast case first. */ + if (ctx->nr == ~0UL) { + flush_tlb_range(ctx->mm, start, end); + return; + } + nr = ctx->nr; + ctx->nr = 0; + if (nr) + flush_tlb_range(ctx->mm, ctx->start_addr, ctx->end_addr); + for (i=0; i < nr; i++) { + pte_t pte = ctx->ptes[i]; + __free_pte(pte); + } +} + +#else + +/* The uniprocessor functions are quite simple and are inline macros in an + * attempt to get gcc to generate optimal code since this code is run on each + * page in a process at exit. + */ +typedef struct mm_struct mmu_gather_t; + +#define tlb_gather_mmu(mm) (mm) +#define tlb_finish_mmu(tlb, start, end) flush_tlb_range(tlb, start, end) +#define tlb_remove_page(tlb, ptep, addr) do {\ + pte_t __pte = *(ptep);\ + pte_clear(ptep);\ + __free_pte(__pte);\ + } while (0) + +#endif + + +#endif /* _ASM_GENERIC__TLB_H */ + diff -urN v2.4.2-pre3/include/asm-i386/tlb.h work-v2.4.2-pre3/include/asm-i386/tlb.h --- v2.4.2-pre3/include/asm-i386/tlb.h Wed Dec 31 19:00:00 1969 +++ work-v2.4.2-pre3/include/asm-i386/tlb.h Mon Feb 12 16:32:48 2001 @@ -0,0 +1 @@ +#include diff -urN v2.4.2-pre3/include/asm-ia64/tlb.h work-v2.4.2-pre3/include/asm-ia64/tlb.h --- v2.4.2-pre3/include/asm-ia64/tlb.h Wed Dec 31 19:00:00 1969 +++ work-v2.4.2-pre3/include/asm-ia64/tlb.h Mon Feb 12 16:33:45 2001 @@ -0,0 +1 @@ +#include diff -urN v2.4.2-pre3/include/asm-m68k/tlb.h work-v2.4.2-pre3/include/asm-m68k/tlb.h --- v2.4.2-pre3/include/asm-m68k/tlb.h Wed Dec 31 19:00:00 1969 +++ work-v2.4.2-pre3/include/asm-m68k/tlb.h Mon Feb 12 16:33:45 2001 @@ -0,0 +1 @@ +#include diff -urN v2.4.2-pre3/include/asm-mips/tlb.h work-v2.4.2-pre3/include/asm-mips/tlb.h --- v2.4.2-pre3/include/asm-mips/tlb.h Wed Dec 31 19:00:00 1969 +++ work-v2.4.2-pre3/include/asm-mips/tlb.h Mon Feb 12 16:33:45 2001 @@ -0,0 +1 @@ +#include diff -urN v2.4.2-pre3/include/asm-mips64/tlb.h work-v2.4.2-pre3/include/asm-mips64/tlb.h --- v2.4.2-pre3/include/asm-mips64/tlb.h Wed Dec 31 19:00:00 1969 +++ work-v2.4.2-pre3/include/asm-mips64/tlb.h Mon Feb 12 16:33:45 2001 @@ -0,0 +1 @@ +#include diff -urN v2.4.2-pre3/include/asm-parisc/tlb.h work-v2.4.2-pre3/include/asm-parisc/tlb.h --- v2.4.2-pre3/include/asm-parisc/tlb.h Wed Dec 31 19:00:00 1969 +++ work-v2.4.2-pre3/include/asm-parisc/tlb.h Mon Feb 12 16:33:45 2001 @@ -0,0 +1 @@ +#include diff -urN v2.4.2-pre3/include/asm-ppc/tlb.h work-v2.4.2-pre3/include/asm-ppc/tlb.h --- v2.4.2-pre3/include/asm-ppc/tlb.h Wed Dec 31 19:00:00 1969 +++ work-v2.4.2-pre3/include/asm-ppc/tlb.h Mon Feb 12 16:33:45 2001 @@ -0,0 +1 @@ +#include diff -urN v2.4.2-pre3/include/asm-s390/tlb.h work-v2.4.2-pre3/include/asm-s390/tlb.h --- v2.4.2-pre3/include/asm-s390/tlb.h Wed Dec 31 19:00:00 1969 +++ work-v2.4.2-pre3/include/asm-s390/tlb.h Mon Feb 12 16:33:45 2001 @@ -0,0 +1 @@ +#include diff -urN v2.4.2-pre3/include/asm-sh/tlb.h work-v2.4.2-pre3/include/asm-sh/tlb.h --- v2.4.2-pre3/include/asm-sh/tlb.h Wed Dec 31 19:00:00 1969 +++ work-v2.4.2-pre3/include/asm-sh/tlb.h Mon Feb 12 16:33:45 2001 @@ -0,0 +1 @@ +#include diff -urN v2.4.2-pre3/include/asm-sparc/tlb.h work-v2.4.2-pre3/include/asm-sparc/tlb.h --- v2.4.2-pre3/include/asm-sparc/tlb.h Wed Dec 31 19:00:00 1969 +++ work-v2.4.2-pre3/include/asm-sparc/tlb.h Mon Feb 12 16:33:45 2001 @@ -0,0 +1 @@ +#include diff -urN v2.4.2-pre3/include/asm-sparc64/tlb.h work-v2.4.2-pre3/include/asm-sparc64/tlb.h --- v2.4.2-pre3/include/asm-sparc64/tlb.h Wed Dec 31 19:00:00 1969 +++ work-v2.4.2-pre3/include/asm-sparc64/tlb.h Mon Feb 12 16:33:45 2001 @@ -0,0 +1 @@ +#include diff -urN v2.4.2-pre3/include/linux/swap.h work-v2.4.2-pre3/include/linux/swap.h --- v2.4.2-pre3/include/linux/swap.h Tue Feb 6 18:02:45 2001 +++ work-v2.4.2-pre3/include/linux/swap.h Mon Feb 12 16:32:48 2001 @@ -293,6 +293,22 @@ extern void shmem_unuse(swp_entry_t entry, struct page *page); +/* Helper function for TLB shootdown that frees a present pte. + */ +static inline void __free_pte(pte_t pte) +{ + struct page *page = pte_page(pte); + if ((!VALID_PAGE(page)) || PageReserved(page)) + return; + /* + * free_page() used to be able to clear swap cache + * entries. We may now have to do it manually. + */ + if (pte_dirty(pte) && page->mapping) + set_page_dirty(page); + free_page_and_swap_cache(page); +} + #endif /* __KERNEL__*/ #endif /* _LINUX_SWAP_H */ diff -urN v2.4.2-pre3/include/linux/tlb.h work-v2.4.2-pre3/include/linux/tlb.h --- v2.4.2-pre3/include/linux/tlb.h Wed Dec 31 19:00:00 1969 +++ work-v2.4.2-pre3/include/linux/tlb.h Mon Feb 12 16:33:45 2001 @@ -0,0 +1 @@ +#include diff -urN v2.4.2-pre3/include/math-emu/tlb.h work-v2.4.2-pre3/include/math-emu/tlb.h --- v2.4.2-pre3/include/math-emu/tlb.h Wed Dec 31 19:00:00 1969 +++ work-v2.4.2-pre3/include/math-emu/tlb.h Mon Feb 12 16:33:45 2001 @@ -0,0 +1 @@ +#include diff -urN v2.4.2-pre3/include/net/tlb.h work-v2.4.2-pre3/include/net/tlb.h --- v2.4.2-pre3/include/net/tlb.h Wed Dec 31 19:00:00 1969 +++ work-v2.4.2-pre3/include/net/tlb.h Mon Feb 12 16:33:45 2001 @@ -0,0 +1 @@ +#include diff -urN v2.4.2-pre3/include/pcmcia/tlb.h work-v2.4.2-pre3/include/pcmcia/tlb.h --- v2.4.2-pre3/include/pcmcia/tlb.h Wed Dec 31 19:00:00 1969 +++ work-v2.4.2-pre3/include/pcmcia/tlb.h Mon Feb 12 16:33:45 2001 @@ -0,0 +1 @@ +#include diff -urN v2.4.2-pre3/include/scsi/tlb.h work-v2.4.2-pre3/include/scsi/tlb.h --- v2.4.2-pre3/include/scsi/tlb.h Wed Dec 31 19:00:00 1969 +++ work-v2.4.2-pre3/include/scsi/tlb.h Mon Feb 12 16:33:45 2001 @@ -0,0 +1 @@ +#include diff -urN v2.4.2-pre3/include/video/tlb.h work-v2.4.2-pre3/include/video/tlb.h --- v2.4.2-pre3/include/video/tlb.h Wed Dec 31 19:00:00 1969 +++ work-v2.4.2-pre3/include/video/tlb.h Mon Feb 12 16:33:45 2001 @@ -0,0 +1 @@ +#include diff -urN v2.4.2-pre3/mm/filemap.c work-v2.4.2-pre3/mm/filemap.c --- v2.4.2-pre3/mm/filemap.c Mon Feb 12 12:19:03 2001 +++ work-v2.4.2-pre3/mm/filemap.c Mon Feb 12 16:32:48 2001 @@ -2023,9 +2023,7 @@ if (vma->vm_flags & VM_LOCKED) return -EINVAL; - flush_cache_range(vma->vm_mm, start, end); zap_page_range(vma->vm_mm, start, end - start); - flush_tlb_range(vma->vm_mm, start, end); return 0; } diff -urN v2.4.2-pre3/mm/memory.c work-v2.4.2-pre3/mm/memory.c --- v2.4.2-pre3/mm/memory.c Mon Feb 12 12:19:03 2001 +++ work-v2.4.2-pre3/mm/memory.c Mon Feb 12 16:32:48 2001 @@ -46,7 +46,7 @@ #include #include #include - +#include unsigned long max_mapnr; unsigned long num_physpages; @@ -265,37 +265,19 @@ /* * Return indicates whether a page was freed so caller can adjust rss */ -static inline int free_pte(pte_t pte) -{ - if (pte_present(pte)) { - struct page *page = pte_page(pte); - if ((!VALID_PAGE(page)) || PageReserved(page)) - return 0; - /* - * free_page() used to be able to clear swap cache - * entries. We may now have to do it manually. - */ - if (pte_dirty(pte) && page->mapping) - set_page_dirty(page); - free_page_and_swap_cache(page); - return 1; - } - swap_free(pte_to_swp_entry(pte)); - return 0; -} - static inline void forget_pte(pte_t page) { if (!pte_none(page)) { printk("forget_pte: old mapping existed!\n"); - free_pte(page); + BUG(); } } -static inline int zap_pte_range(struct mm_struct *mm, pmd_t * pmd, unsigned long address, unsigned long size) +static inline int zap_pte_range(mmu_gather_t *tlb, pmd_t * pmd, unsigned long address, unsigned long size) { - pte_t * pte; - int freed; + unsigned long offset; + pte_t * ptep; + int freed = 0; if (pmd_none(*pmd)) return 0; @@ -304,27 +286,27 @@ pmd_clear(pmd); return 0; } - pte = pte_offset(pmd, address); + ptep = pte_offset(pmd, address); address &= ~PMD_MASK; if (address + size > PMD_SIZE) size = PMD_SIZE - address; - size >>= PAGE_SHIFT; - freed = 0; - for (;;) { - pte_t page; - if (!size) - break; - page = ptep_get_and_clear(pte); - pte++; - size--; - if (pte_none(page)) + size &= PAGE_MASK; + for (offset=0; offset < size; ptep++, offset += PAGE_SIZE) { + pte_t pte = *ptep; + if (pte_none(pte)) continue; - freed += free_pte(page); + if (pte_present(pte)) { + freed ++; + /* This will eventually call __free_pte on the pte. */ + tlb_remove_page(tlb, ptep, address + offset); + } else + swap_free(pte_to_swp_entry(pte)); } + return freed; } -static inline int zap_pmd_range(struct mm_struct *mm, pgd_t * dir, unsigned long address, unsigned long size) +static inline int zap_pmd_range(mmu_gather_t *tlb, pgd_t * dir, unsigned long address, unsigned long size) { pmd_t * pmd; unsigned long end; @@ -344,7 +326,7 @@ end = PGDIR_SIZE; freed = 0; do { - freed += zap_pte_range(mm, pmd, address, end - address); + freed += zap_pte_range(tlb, pmd, address, end - address); address = (address + PMD_SIZE) & PMD_MASK; pmd++; } while (address < end); @@ -356,8 +338,9 @@ */ void zap_page_range(struct mm_struct *mm, unsigned long address, unsigned long size) { + mmu_gather_t *tlb; pgd_t * dir; - unsigned long end = address + size; + unsigned long start = address, end = address + size; int freed = 0; dir = pgd_offset(mm, address); @@ -372,12 +355,18 @@ if (address >= end) BUG(); spin_lock(&mm->page_table_lock); + flush_cache_range(mm, address, end); + tlb = tlb_gather_mmu(mm); + do { - freed += zap_pmd_range(mm, dir, address, end - address); + freed += zap_pmd_range(tlb, dir, address, end - address); address = (address + PGDIR_SIZE) & PGDIR_MASK; dir++; } while (address && (address < end)); - spin_unlock(&mm->page_table_lock); + + /* this will flush any remaining tlb entries */ + tlb_finish_mmu(tlb, start, end); + /* * Update rss for the mm_struct (not necessarily current->mm) * Notice that rss is an unsigned long. @@ -386,6 +375,7 @@ mm->rss -= freed; else mm->rss = 0; + spin_unlock(&mm->page_table_lock); } @@ -908,9 +898,7 @@ /* mapping wholly truncated? */ if (mpnt->vm_pgoff >= pgoff) { - flush_cache_range(mm, start, end); zap_page_range(mm, start, len); - flush_tlb_range(mm, start, end); continue; } @@ -923,9 +911,7 @@ /* Ok, partially affected.. */ start += diff << PAGE_SHIFT; len = (len - diff) << PAGE_SHIFT; - flush_cache_range(mm, start, end); zap_page_range(mm, start, len); - flush_tlb_range(mm, start, end); } while ((mpnt = mpnt->vm_next_share) != NULL); } diff -urN v2.4.2-pre3/mm/mmap.c work-v2.4.2-pre3/mm/mmap.c --- v2.4.2-pre3/mm/mmap.c Mon Feb 12 12:19:03 2001 +++ work-v2.4.2-pre3/mm/mmap.c Mon Feb 12 16:32:48 2001 @@ -373,9 +373,7 @@ vma->vm_file = NULL; fput(file); /* Undo any partial mapping done by a device driver. */ - flush_cache_range(mm, vma->vm_start, vma->vm_end); zap_page_range(mm, vma->vm_start, vma->vm_end - vma->vm_start); - flush_tlb_range(mm, vma->vm_start, vma->vm_end); free_vma: kmem_cache_free(vm_area_cachep, vma); return error; @@ -750,9 +748,7 @@ remove_shared_vm_struct(mpnt); mm->map_count--; - flush_cache_range(mm, st, end); zap_page_range(mm, st, size); - flush_tlb_range(mm, st, end); /* * Fix the mapping, and free the old area if it wasn't reused. diff -urN v2.4.2-pre3/mm/mremap.c work-v2.4.2-pre3/mm/mremap.c --- v2.4.2-pre3/mm/mremap.c Fri Dec 29 17:07:24 2000 +++ work-v2.4.2-pre3/mm/mremap.c Mon Feb 12 16:32:48 2001 @@ -119,7 +119,6 @@ while ((offset += PAGE_SIZE) < len) move_one_page(mm, new_addr + offset, old_addr + offset); zap_page_range(mm, new_addr, len); - flush_tlb_range(mm, new_addr, new_addr + len); return -1; }