* [PATCH] revised tlb shootdown patch vs 2.4.2-pre3 (fwd)
@ 2001-02-12 21:54 Ben LaHaise
0 siblings, 0 replies; only message in thread
From: Ben LaHaise @ 2001-02-12 21:54 UTC (permalink / raw)
To: linux-mm
[-- Attachment #1: Type: TEXT/PLAIN, Size: 1000 bytes --]
I'm silly =)
---------- Forwarded message ----------
Date: Mon, 12 Feb 2001 16:52:27 -0500 (EST)
From: Ben LaHaise <bcrl@redhat.com>
To: torvalds@transmeta.com
Cc: davem@redhat.com, alan@redhat.com, linux-mm@redhat.com
Subject: [PATCH] revised tlb shootdown patch vs 2.4.2-pre3
Hello all,
Attached is the revised tlb shootdown patch that implements the tlb_*
interface suggested in asm-generic/tlb.h. All architechures are updated
to use the generic code, although they may opt to do something else. It
also has the mm_users optimisation that will fall back to unbuffered page
freeing if only one thread is in use, plus it compiles to the old code
without CONFIG_SMP. Comments? I've santity tested all of the non-SMP,
SMP-slow and SMP-fast paths with no problems.
Also, there are two small other fragments: correct a compile time warning
in the soundmodem code, and add a check for ~/bin/installkernel in
arch/i386/boot/install.sh. I'ld appreciate it if those were included.
Thanks!
-ben
[-- Attachment #2: Type: TEXT/PLAIN, Size: 22678 bytes --]
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 <asm/dma.h>
#include <asm/mmu_context.h>
#include <asm/console.h>
+#include <asm/tlb.h>
+
+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 <asm/mach/arch.h>
#include <asm/mach/map.h>
+#include <asm/tlb.h>
+
+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 <asm/pgtable.h>
#include <asm/dma.h>
#include <asm/svinto.h>
+#include <asm/tlb.h>
+
+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 <asm/fixmap.h>
#include <asm/e820.h>
#include <asm/apic.h>
+#include <asm/tlb.h>
+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 <asm/pgalloc.h>
#include <asm/sal.h>
#include <asm/system.h>
+#include <asm/tlb.h>
+
+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 <asm/atari_stram.h>
#endif
+#include <asm/tlb.h>
+
+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 <asm/sgialib.h>
#endif
#include <asm/mmu_context.h>
+#include <asm/tlb.h>
+
+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 <asm/sgialib.h>
#endif
#include <asm/mmu_context.h>
+#include <asm/tlb.h>
+
+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 <linux/unistd.h>
#include <asm/pgalloc.h>
+#include <asm/tlb.h>
+
+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 <asm/tlb.h>
+
+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 <asm/pgalloc.h>
#include <asm/dma.h>
#include <asm/lowcore.h>
+#include <asm/tlb.h>
+
+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 <asm/pgalloc.h>
#include <asm/mmu_context.h>
#include <asm/io.h>
+#include <asm/tlb.h>
+
+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 <asm/page.h>
#include <asm/pgtable.h>
#include <asm/vaddrs.h>
+#include <asm/tlb.h>
+
+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 <asm/vaddrs.h>
#include <asm/dma.h>
#include <asm/starfire.h>
+#include <asm/tlb.h>
+
+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 <stdio.h>
+#include <stdlib.h>
#include <math.h>
#include <string.h>
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 <asm-generic/tlb.h>
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 <asm-generic/tlb.h>
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 <asm-generic/tlb.h>
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 <asm-generic/tlb.h>
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 <asm-generic/tlb.h>
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 <asm-generic/tlb.h>
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 <asm-generic/tlb.h>
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 <asm-generic/tlb.h>
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 <asm-generic/tlb.h>
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 <asm-generic/tlb.h>
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 <asm-generic/tlb.h>
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 <asm-generic/tlb.h>
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 <asm-generic/tlb.h>
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 <asm-generic/tlb.h>
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 <asm-generic/tlb.h>
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 <asm-generic/tlb.h>
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 <asm-generic/tlb.h>
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 <asm-generic/tlb.h>
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 <asm-generic/tlb.h>
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 <asm-generic/tlb.h>
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 <asm/pgalloc.h>
#include <linux/highmem.h>
#include <linux/pagemap.h>
-
+#include <asm/tlb.h>
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;
}
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2001-02-12 21:54 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2001-02-12 21:54 [PATCH] revised tlb shootdown patch vs 2.4.2-pre3 (fwd) Ben LaHaise
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox