]> err.no Git - linux-2.6/commitdiff
[PATCH] mm: flush_tlb_range outside ptlock
authorHugh Dickins <hugh@veritas.com>
Sun, 30 Oct 2005 01:16:28 +0000 (18:16 -0700)
committerLinus Torvalds <torvalds@g5.osdl.org>
Sun, 30 Oct 2005 04:40:40 +0000 (21:40 -0700)
There was one small but very significant change in the previous patch:
mprotect's flush_tlb_range fell outside the page_table_lock: as it is in 2.4,
but that doesn't prove it safe in 2.6.

On some architectures flush_tlb_range comes to the same as flush_tlb_mm, which
has always been called from outside page_table_lock in dup_mmap, and is so
proved safe.  Others required a deeper audit: I could find no reliance on
page_table_lock in any; but in ia64 and parisc found some code which looks a
bit as if it might want preemption disabled.  That won't do any actual harm,
so pending a decision from the maintainers, disable preemption there.

Remove comments on page_table_lock from flush_tlb_mm, flush_tlb_range and
flush_tlb_page entries in cachetlb.txt: they were rather misleading (what
generic code does is different from what usually happens), the rules are now
changing, and it's not yet clear where we'll end up (will the generic
tlb_flush_mmu happen always under lock?  never under lock?  or sometimes under
and sometimes not?).

Signed-off-by: Hugh Dickins <hugh@veritas.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Documentation/cachetlb.txt
arch/ia64/mm/tlb.c
include/asm-parisc/tlbflush.h

index e132fb1163b0785dee1a072569f4aaa467e899dd..7eb715e07eda0eaf39f391fe8e4caf3c1734fdd9 100644 (file)
@@ -49,9 +49,6 @@ changes occur:
        page table operations such as what happens during
        fork, and exec.
 
-       Platform developers note that generic code will always
-       invoke this interface without mm->page_table_lock held.
-
 3) void flush_tlb_range(struct vm_area_struct *vma,
                        unsigned long start, unsigned long end)
 
@@ -72,9 +69,6 @@ changes occur:
        call flush_tlb_page (see below) for each entry which may be
        modified.
 
-       Platform developers note that generic code will always
-       invoke this interface with mm->page_table_lock held.
-
 4) void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr)
 
        This time we need to remove the PAGE_SIZE sized translation
@@ -93,9 +87,6 @@ changes occur:
 
        This is used primarily during fault processing.
 
-       Platform developers note that generic code will always
-       invoke this interface with mm->page_table_lock held.
-
 5) void flush_tlb_pgtables(struct mm_struct *mm,
                           unsigned long start, unsigned long end)
 
index c93e0f2b5feab9b94c2ccad9507291b554abd2de..c79a9b96d02b3759eb2adffb8ac807a4ac55e18d 100644 (file)
@@ -158,10 +158,12 @@ flush_tlb_range (struct vm_area_struct *vma, unsigned long start, unsigned long
 # ifdef CONFIG_SMP
        platform_global_tlb_purge(mm, start, end, nbits);
 # else
+       preempt_disable();
        do {
                ia64_ptcl(start, (nbits<<2));
                start += (1UL << nbits);
        } while (start < end);
+       preempt_enable();
 # endif
 
        ia64_srlz_i();                  /* srlz.i implies srlz.d */
index 84af4ab1fe51bd41d5d40644b78d3c46edc07401..e97aa8d1eff5f99bf84596d64602e252c356ff71 100644 (file)
@@ -88,7 +88,7 @@ static inline void flush_tlb_range(struct vm_area_struct *vma,
        if (npages >= 512)  /* 2MB of space: arbitrary, should be tuned */
                flush_tlb_all();
        else {
-
+               preempt_disable();
                mtsp(vma->vm_mm->context,1);
                purge_tlb_start();
                if (split_tlb) {
@@ -102,6 +102,7 @@ static inline void flush_tlb_range(struct vm_area_struct *vma,
                                pdtlb(start);
                                start += PAGE_SIZE;
                        }
+               preempt_enable();
                }
                purge_tlb_end();
        }