Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=db813fe5a77d03b29e872da47463d2efbddc3fc2
Commit:     db813fe5a77d03b29e872da47463d2efbddc3fc2
Parent:     e58d95abb7b3232333ab35a09f7f5b0cd6a19cdb
Author:     Ralf Baechle <[EMAIL PROTECTED]>
AuthorDate: Thu Sep 27 18:26:43 2007 +0100
Committer:  Ralf Baechle <[EMAIL PROTECTED]>
CommitDate: Thu Oct 11 23:46:12 2007 +0100

    [MIPS] Avoid indexed cacheops.
    
    On MP configurations it's highly dubious what this code will actually
    affect since blasting away cachelines may or may not do the right
    thing wrt. cache coherency.
    
    Signed-off-by: Ralf Baechle <[EMAIL PROTECTED]>
---
 arch/mips/mm/c-r4k.c |   74 +++++++++++++++++++-------------------------------
 1 files changed, 28 insertions(+), 46 deletions(-)

diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c
index 738b898..cf48371 100644
--- a/arch/mips/mm/c-r4k.c
+++ b/arch/mips/mm/c-r4k.c
@@ -8,6 +8,7 @@
  * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
  */
 #include <linux/init.h>
+#include <linux/highmem.h>
 #include <linux/kernel.h>
 #include <linux/linkage.h>
 #include <linux/sched.h>
@@ -318,23 +319,6 @@ static void __init r4k_blast_scache_setup(void)
                r4k_blast_scache = blast_scache128;
 }
 
-/*
- * This is former mm's flush_cache_all() which really should be
- * flush_cache_vunmap these days ...
- */
-static inline void local_r4k_flush_cache_all(void * args)
-{
-       r4k_blast_dcache();
-}
-
-static void r4k_flush_cache_all(void)
-{
-       if (!cpu_has_dc_aliases)
-               return;
-
-       r4k_on_each_cpu(local_r4k_flush_cache_all, NULL, 1, 1);
-}
-
 static inline void local_r4k___flush_cache_all(void * args)
 {
 #if defined(CONFIG_CPU_LOONGSON2)
@@ -423,13 +407,14 @@ static inline void local_r4k_flush_cache_page(void *args)
        struct flush_cache_page_args *fcp_args = args;
        struct vm_area_struct *vma = fcp_args->vma;
        unsigned long addr = fcp_args->addr;
-       unsigned long paddr = fcp_args->pfn << PAGE_SHIFT;
+       struct page *page = pfn_to_page(fcp_args->pfn);
        int exec = vma->vm_flags & VM_EXEC;
        struct mm_struct *mm = vma->vm_mm;
        pgd_t *pgdp;
        pud_t *pudp;
        pmd_t *pmdp;
        pte_t *ptep;
+       void *vaddr;
 
        /*
         * If ownes no valid ASID yet, cannot possibly have gotten
@@ -451,43 +436,40 @@ static inline void local_r4k_flush_cache_page(void *args)
        if (!(pte_val(*ptep) & _PAGE_PRESENT))
                return;
 
-       /*
-        * Doing flushes for another ASID than the current one is
-        * too difficult since stupid R4k caches do a TLB translation
-        * for every cache flush operation.  So we do indexed flushes
-        * in that case, which doesn't overly flush the cache too much.
-        */
-       if ((mm == current->active_mm) && (pte_val(*ptep) & _PAGE_VALID)) {
-               if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc)) {
-                       r4k_blast_dcache_page(addr);
-                       if (exec && !cpu_icache_snoops_remote_store)
-                               r4k_blast_scache_page(addr);
-               }
-               if (exec)
-                       r4k_blast_icache_page(addr);
-
-               return;
+       if ((mm == current->active_mm) && (pte_val(*ptep) & _PAGE_VALID))
+               vaddr = NULL;
+       else {
+               /*
+                * Use kmap_coherent or kmap_atomic to do flushes for
+                * another ASID than the current one.
+                */
+               if (cpu_has_dc_aliases)
+                       vaddr = kmap_coherent(page, addr);
+               else
+                       vaddr = kmap_atomic(page, KM_USER0);
+               addr = (unsigned long)vaddr;
        }
 
-       /*
-        * Do indexed flush, too much work to get the (possible) TLB refills
-        * to work correctly.
-        */
        if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc)) {
-               r4k_blast_dcache_page_indexed(cpu_has_pindexed_dcache ?
-                                             paddr : addr);
-               if (exec && !cpu_icache_snoops_remote_store) {
-                       r4k_blast_scache_page_indexed(paddr);
-               }
+               r4k_blast_dcache_page(addr);
+               if (exec && !cpu_icache_snoops_remote_store)
+                       r4k_blast_scache_page(addr);
        }
        if (exec) {
-               if (cpu_has_vtag_icache && mm == current->active_mm) {
+               if (vaddr && cpu_has_vtag_icache && mm == current->active_mm) {
                        int cpu = smp_processor_id();
 
                        if (cpu_context(cpu, mm) != 0)
                                drop_mmu_context(mm, cpu);
                } else
-                       r4k_blast_icache_page_indexed(addr);
+                       r4k_blast_icache_page(addr);
+       }
+
+       if (vaddr) {
+               if (cpu_has_dc_aliases)
+                       kunmap_coherent();
+               else
+                       kunmap_atomic(vaddr, KM_USER0);
        }
 }
 
@@ -1279,7 +1261,7 @@ void __init r4k_cache_init(void)
                                        PAGE_SIZE - 1);
        else
                shm_align_mask = PAGE_SIZE-1;
-       flush_cache_all         = r4k_flush_cache_all;
+       flush_cache_all         = cache_noop;
        __flush_cache_all       = r4k___flush_cache_all;
        flush_cache_mm          = r4k_flush_cache_mm;
        flush_cache_page        = r4k_flush_cache_page;
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to