Re: [PATCH 2.6.24][MIPS]Work in progress: fix HIGHMEM-enabled dcache flushing on 32-bit processor

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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


[Index of Archives]     [Linux MIPS Home]     [LKML Archive]     [Linux ARM Kernel]     [Linux ARM]     [Linux]     [Git]     [Yosemite News]     [Linux SCSI]     [Linux Hams]

  Powered by Linux