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
|