I've been working with this patch on an SB1250 (configured for 32-bit due to some non-technical constraints). I have tracked down the cause of a crash that only occurs with SMP enabled, and wondered there might be a better approach than the one I took for fixing it. The crash scenario involves one CPU having an atomic mapping of type KM_USER0 in use when the other CPU happens to call r4k_flush_cachee_page(), which in turn calls r4k_on_each_cpu() for local_r4k_flush_cache_page(). The original CPU is interrupted (still with an active KM_USER0 mapping), local_r4k_flush_cache_page() is called, and in the process another KM_USER0 mapping is attempted (and fails in flames.) The diffs below (against 2.6.26.1) appear to have eliminated this problem - does this make sense, and is there a better way? Lance Index: linux26/arch/mips/mm/c-r4k.c =================================================================== RCS file: /export/cvsroot/exos/linux26/arch/mips/mm/Attic/c-r4k.c,v retrieving revision 1.1.4.1 diff -u -r1.1.4.1 c-r4k.c --- linux26/arch/mips/mm/c-r4k.c 9 Sep 2008 20:25:44 -0000 1.1.4.1 +++ linux26/arch/mips/mm/c-r4k.c 4 Nov 2008 14:46:17 -0000 @@ -436,6 +436,7 @@ struct vm_area_struct *vma; unsigned long addr; unsigned long pfn; + __u32 cpu; }; static inline void local_r4k_flush_cache_page(void *args) @@ -452,6 +453,12 @@ pmd_t *pmdp; pte_t *ptep; void *vaddr; + enum km_type kmtype; + + if (fcp_args->cpu == smp_processor_id()) + kmtype = KM_USER0; + else + kmtype = KM_FLUSH_CACHE_PAGE; /* * If ownes no valid ASID yet, cannot possibly have gotten @@ -485,7 +492,7 @@ if (map_coherent) vaddr = kmap_coherent(page, addr); else - vaddr = kmap_atomic(page, KM_USER0); + vaddr = kmap_atomic(page, kmtype); addr = (unsigned long)vaddr; } @@ -508,7 +515,7 @@ if (map_coherent) kunmap_coherent(); else - kunmap_atomic(vaddr, KM_USER0); + kunmap_atomic(vaddr, kmtype); } } @@ -520,6 +527,7 @@ args.vma = vma; args.addr = addr; args.pfn = pfn; + args.cpu = smp_processor_id(); r4k_on_each_cpu(local_r4k_flush_cache_page, &args, 1, 1); } Index: linux26/include/asm-mips/kmap_types.h =================================================================== RCS file: /export/cvsroot/exos/linux26/include/asm-mips/Attic/kmap_types.h,v retrieving revision 1.1.4.1 diff -u -r1.1.4.1 kmap_types.h --- linux26/include/asm-mips/kmap_types.h 10 Sep 2008 12:48:21 -0000 1.1.4.1 +++ linux26/include/asm-mips/kmap_types.h 4 Nov 2008 14:46:19 -0000 @@ -22,7 +22,8 @@ D(10) KM_IRQ1, D(11) KM_SOFTIRQ0, D(12) KM_SOFTIRQ1, -D(13) KM_TYPE_NR +D(13) KM_FLUSH_CACHE_PAGE, +D(14) KM_TYPE_NR }; #undef D