Subject: __flush_cache_all() miscellany

From: "Justin Carlson" <[email-masked]>
Date: 29 May 2002 09:50:52 -0700

Looking at the cache routines, I've noticed that there's been a
relatively recent introduction of a __flush_cache_all() routine. 
Looking at oss.sgi.com's cvs logs, I see this comment:

>Introduce __flush_cache_all() which flushes the cache no matter if
>this operation is necessary from the mm point of view or not.

Some questions:

Which caches does this apply to?  It looks like the current
implementations assume L1 only.

Would anyone have a problem with renaming this function?  To me, at
least, it's rather confusing to have all of:

flush_cache_all()
_flush_cache_all()
__flush_cache_all()
___flush_cache_all()

defined, especially when the latter two mean something significantly
different from the former two.  I'd prefer calling the new one
{_}force_flush_l1_caches() or somesuch.

In a related note, one of the few places this routine is called is the
kgdb stub routines (in arch/mips/kernel/gdb-stub.c):

void set_async_breakpoint(unsigned int epc)
{
	int cpu = smp_processor_id();

	async_bp[cpu].addr = epc;
	async_bp[cpu].val  = *(unsigned *)epc;
	*(unsigned *)epc = BP;
	__flush_cache_all();
}

Shouldn't that be a flush_icache_range() call anyways?

Thanks,
  Justin

---

From: "Justin Carlson" <[email-masked]>
Date: 29 May 2002 12:26:29 -0700

Here's a patch against cvs that does the rename.  Unless anyone has
objections, Ralf, could  you apply this?

While doing this, I've noticed that the whole mips tree is horribly
inconsistent in terms of the cache flushing syscalls (sys_cacheflush and
sys_sysmips->CACHE_FLUSH).  

Here's what the different ports appear to flush given one of these
syscall:

andes:  l1 and l2
lexra:  l1 icache
mips32: l1 icache/dcache
r3k:    l1 icache
r4k:    l1 icache/dcache
r5432:  l1 icache/dcache
r5900:  l1 icache/dcache
rm7k:   l1 icache/dcache
sb1:    l1 icache/dcache
sr7100: l1 and l2
tx39:   l1 icache
tx49:   li icache/dcache

Some of these are blatantly wrong with respect to the cacheflush
syscall; it defines flags for flushing the icache, dcache, or both.  In
the latter two cases, the lexra, r3k, and tx39 are not doing what was
requested.  I doubt this matters for any significant userspace app, but
it would be nice to at least be consistent.

As for the sysmips system call, I've  not been able to dig up the
semantics.  (Actually, I don't really see why we have both ways of
flushing the cache at all...some historical cruft?).  Anyone have a
helpful pointer to docs on the subject?

Thanks,
  Justin

? rename___flush_cache_all.patch
Index: arch/mips/kernel/gdb-stub.c
===================================================================
RCS file: /cvsroot/linux-mips/linux/arch/mips/kernel/gdb-stub.c,v
retrieving revision 1.7
diff -u -r1.7 gdb-stub.c
--- arch/mips/kernel/gdb-stub.c	9 May 2002 17:22:34 -0000	1.7
+++ arch/mips/kernel/gdb-stub.c	29 May 2002 19:00:41 -0000
@@ -578,7 +578,7 @@
 	async_bp.addr = epc;
 	async_bp.val  = *(unsigned *)epc;
 	*(unsigned *)epc = BP;
-	__flush_cache_all();
+	force_flush_cache_all();
 }

@@ -805,7 +805,7 @@
 			 * NB: We flush both caches, just to be sure...
 			 */
 
-			__flush_cache_all();
+			force_flush_cache_all();
 			return;
 			/* NOTREACHED */
 			break;
@@ -834,7 +834,7 @@
 			 * use breakpoints and continue, instead.
 			 */
 			single_step(regs);
-			__flush_cache_all();
+			force_flush_cache_all();
 			return;
 			/* NOTREACHED */
 
Index: arch/mips/kernel/sysmips.c
===================================================================
RCS file: /cvsroot/linux-mips/linux/arch/mips/kernel/sysmips.c,v
retrieving revision 1.10
diff -u -r1.10 sysmips.c
--- arch/mips/kernel/sysmips.c	26 Nov 2001 19:18:13 -0000	1.10
+++ arch/mips/kernel/sysmips.c	29 May 2002 19:00:41 -0000
@@ -84,7 +84,7 @@
 		goto out;
 
 	case FLUSH_CACHE:
-		__flush_cache_all();
+		force_flush_cache_all();
 		retval = 0;
 		goto out;
 
Index: arch/mips/mm/c-andes.c
===================================================================
RCS file: /cvsroot/linux-mips/linux/arch/mips/mm/c-andes.c,v
retrieving revision 1.4
diff -u -r1.4 c-andes.c
--- arch/mips/mm/c-andes.c	19 Feb 2002 17:43:02 -0000	1.4
+++ arch/mips/mm/c-andes.c	29 May 2002 19:00:41 -0000
@@ -70,7 +70,7 @@
 	}
 }
 
-static void andes___flush_cache_all(void)
+static void andes_force_flush_cache_all(void)
 {
 	andes_flush_cache_l1();
 	andes_flush_cache_l2();
@@ -105,7 +105,7 @@
 	_copy_page = andes_copy_page;
 
 	_flush_cache_all = andes_flush_cache_all;
-	___flush_cache_all = andes___flush_cache_all;
+	_force_flush_cache_all = andes_force_flush_cache_all;
 	_flush_cache_mm = andes_flush_cache_mm;
 	_flush_cache_page = andes_flush_cache_page;
 	_flush_page_to_ram = andes_flush_page_to_ram;
Index: arch/mips/mm/c-lexra.c
===================================================================
RCS file: /cvsroot/linux-mips/linux/arch/mips/mm/c-lexra.c,v
retrieving revision 1.1
diff -u -r1.1 c-lexra.c
--- arch/mips/mm/c-lexra.c	9 May 2002 17:22:35 -0000	1.1
+++ arch/mips/mm/c-lexra.c	29 May 2002 19:00:42 -0000
@@ -282,7 +282,7 @@
 	dcache_size = 1024 * 2;
 
 	_flush_cache_all = lx_flush_cache_all;
-	___flush_cache_all = lx_flush_cache_all; 
+	_force_flush_cache_all = lx_flush_cache_all; 
 	_flush_cache_mm = lx_flush_cache_mm;
 	_flush_cache_range = lx_flush_cache_range;
 	_flush_cache_page = lx_flush_cache_page;
Index: arch/mips/mm/c-mips32.c
===================================================================
RCS file: /cvsroot/linux-mips/linux/arch/mips/mm/c-mips32.c,v
retrieving revision 1.4
diff -u -r1.4 c-mips32.c
--- arch/mips/mm/c-mips32.c	28 Jan 2002 23:15:25 -0000	1.4
+++ arch/mips/mm/c-mips32.c	29 May 2002 19:00:42 -0000
@@ -590,7 +590,7 @@
 	_clear_page = (void *)mips32_clear_page_dc;
 	_copy_page = (void *)mips32_copy_page_dc;
 	_flush_cache_all = mips32_flush_cache_all_pc;
-	___flush_cache_all = mips32_flush_cache_all_pc;
+	_force_flush_cache_all = mips32_flush_cache_all_pc;
 	_flush_cache_mm = mips32_flush_cache_mm_pc;
 	_flush_cache_range = mips32_flush_cache_range_pc;
 	_flush_cache_page = mips32_flush_cache_page_pc;
@@ -606,7 +606,7 @@
 static void __init setup_scache_funcs(void)
 {
         _flush_cache_all = mips32_flush_cache_all_sc;
-        ___flush_cache_all = mips32_flush_cache_all_sc;
+        _force_flush_cache_all = mips32_flush_cache_all_sc;
 	_flush_cache_mm = mips32_flush_cache_mm_sc;
 	_flush_cache_range = mips32_flush_cache_range_sc;
 	_flush_cache_page = mips32_flush_cache_page_sc;
@@ -666,5 +666,5 @@
 	_flush_cache_sigtramp = mips32_flush_cache_sigtramp;
 	_flush_icache_range = mips32_flush_icache_range;	/* Ouch */
 
-	__flush_cache_all();
+	force_flush_cache_all();
 }
Index: arch/mips/mm/c-r3k.c
===================================================================
RCS file: /cvsroot/linux-mips/linux/arch/mips/mm/c-r3k.c,v
retrieving revision 1.6
diff -u -r1.6 c-r3k.c
--- arch/mips/mm/c-r3k.c	19 Feb 2002 17:37:17 -0000	1.6
+++ arch/mips/mm/c-r3k.c	29 May 2002 19:00:42 -0000
@@ -240,7 +240,7 @@
 {
 }
  
-static inline void r3k___flush_cache_all(void)
+static inline void r3k_force_flush_cache_all(void)
 {
 	r3k_flush_icache_range(KSEG0, KSEG0 + icache_size);
 }
@@ -328,7 +328,7 @@
 	r3k_probe_cache();
 
 	_flush_cache_all = r3k_flush_cache_all;
-	___flush_cache_all = r3k___flush_cache_all;
+	_force_flush_cache_all = r3k_force_flush_cache_all;
 	_flush_cache_mm = r3k_flush_cache_mm;
 	_flush_cache_range = r3k_flush_cache_range;
 	_flush_cache_page = r3k_flush_cache_page;
Index: arch/mips/mm/c-r4k.c
===================================================================
RCS file: /cvsroot/linux-mips/linux/arch/mips/mm/c-r4k.c,v
retrieving revision 1.9
diff -u -r1.9 c-r4k.c
--- arch/mips/mm/c-r4k.c	28 May 2002 21:03:31 -0000	1.9
+++ arch/mips/mm/c-r4k.c	29 May 2002 19:00:42 -0000
@@ -1362,7 +1362,7 @@
 		_flush_cache_page = r4k_flush_cache_page_d32i32;
 		break;
 	}
-	___flush_cache_all = _flush_cache_all;
+	_force_flush_cache_all = _flush_cache_all;
 
 	_flush_icache_page = r4k_flush_icache_page_p;
 #ifdef CONFIG_NONCOHERENT_IO
@@ -1448,7 +1448,7 @@
 		_copy_page = r4k_copy_page_s128;
 		break;
 	}
-	___flush_cache_all = _flush_cache_all;
+	_force_flush_cache_all = _flush_cache_all;
 	_flush_icache_page = r4k_flush_icache_page_s;
 #ifdef CONFIG_NONCOHERENT_IO
 	_dma_cache_wback_inv = r4k_dma_cache_wback_inv_sc;
@@ -1504,5 +1504,5 @@
 		_flush_cache_sigtramp = r4600v20k_flush_cache_sigtramp;
 	}
 
-	__flush_cache_all();
+	force_flush_cache_all();
 }
Index: arch/mips/mm/c-r5432.c
===================================================================
RCS file: /cvsroot/linux-mips/linux/arch/mips/mm/c-r5432.c,v
retrieving revision 1.6
diff -u -r1.6 c-r5432.c
--- arch/mips/mm/c-r5432.c	30 Nov 2001 18:34:09 -0000	1.6
+++ arch/mips/mm/c-r5432.c	29 May 2002 19:00:42 -0000
@@ -463,7 +463,7 @@
 	_clear_page = r5432_clear_page_d32;
 	_copy_page = r5432_copy_page_d32;
 	_flush_cache_all = r5432_flush_cache_all_d32i32;
-	___flush_cache_all = r5432_flush_cache_all_d32i32;
+	_force_flush_cache_all = r5432_flush_cache_all_d32i32;
 	_flush_page_to_ram = r5432_flush_page_to_ram_d32;
 	_flush_cache_mm = r5432_flush_cache_mm_d32i32;
 	_flush_cache_range = r5432_flush_cache_range_d32i32;
@@ -476,5 +476,5 @@
 	_flush_cache_sigtramp = r5432_flush_cache_sigtramp;
 	_flush_icache_range = r5432_flush_icache_range;	/* Ouch */
 
-	__flush_cache_all();
+	force_flush_cache_all();
 }
Index: arch/mips/mm/c-r5900.c
===================================================================
RCS file: /cvsroot/linux-mips/linux/arch/mips/mm/c-r5900.c,v
retrieving revision 1.2
diff -u -r1.2 c-r5900.c
--- arch/mips/mm/c-r5900.c	27 Nov 2001 17:53:47 -0000	1.2
+++ arch/mips/mm/c-r5900.c	29 May 2002 19:00:42 -0000
@@ -307,7 +307,7 @@
 	_flush_cache_range = r5900_flush_cache_range_d64i64;
 	_flush_cache_page = r5900_flush_cache_page_d64i64;
 
-	___flush_cache_all = _flush_cache_all;
+	_force_flush_cache_all = _flush_cache_all;
 	_flush_icache_range = r5900_flush_icache_range_i64;
 	_flush_icache_page = r5900_flush_icache_page_i64; /* FIXME */
 
Index: arch/mips/mm/c-rm7k.c
===================================================================
RCS file: /cvsroot/linux-mips/linux/arch/mips/mm/c-rm7k.c,v
retrieving revision 1.5
diff -u -r1.5 c-rm7k.c
--- arch/mips/mm/c-rm7k.c	21 Apr 2002 20:01:13 -0000	1.5
+++ arch/mips/mm/c-rm7k.c	29 May 2002 19:00:42 -0000
@@ -66,7 +66,7 @@
 		  "i" (Page_Invalidate_T));
 }
 
-static void __flush_cache_all_d32i32(void)
+static void force_flush_cache_all_d32i32(void)
 {
 	blast_dcache32();
 	blast_icache32();
@@ -105,7 +105,7 @@
 	/*
 	 * FIXME: This is overdoing things and harms performance.
 	 */
-	__flush_cache_all_d32i32();
+	force_flush_cache_all_d32i32();
 }
 
 static void rm7k_flush_icache_page(struct vm_area_struct *vma,
@@ -116,7 +116,7 @@
 	 * temporary mapping and use hit_invalidate operation to flush out
 	 * the line from the cache.
 	 */
-	__flush_cache_all_d32i32();
+	force_flush_cache_all_d32i32();
 }

@@ -331,7 +331,7 @@
 	_copy_page = rm7k_copy_page;
 
 	_flush_cache_all = rm7k_flush_cache_all_d32i32;
-	___flush_cache_all = __flush_cache_all_d32i32;
+	_force_flush_cache_all = force_flush_cache_all_d32i32;
 	_flush_cache_mm = rm7k_flush_cache_mm_d32i32;
 	_flush_cache_range = rm7k_flush_cache_range_d32i32;
 	_flush_cache_page = rm7k_flush_cache_page_d32i32;
@@ -344,5 +344,5 @@
 	_dma_cache_wback = rm7k_dma_cache_wback;
 	_dma_cache_inv = rm7k_dma_cache_inv;
 
-	__flush_cache_all_d32i32();
+	force_flush_cache_all_d32i32();
 }
Index: arch/mips/mm/c-sb1.c
===================================================================
RCS file: /cvsroot/linux-mips/linux/arch/mips/mm/c-sb1.c,v
retrieving revision 1.14
diff -u -r1.14 c-sb1.c
--- arch/mips/mm/c-sb1.c	21 Apr 2002 20:01:13 -0000	1.14
+++ arch/mips/mm/c-sb1.c	29 May 2002 19:00:42 -0000
@@ -74,7 +74,7 @@
 {
 }
 
-static void local_sb1___flush_cache_all(void)
+static void local_sb1_force_flush_cache_all(void)
 {
 	/*
 	 * Haven't worried too much about speed here; given that we're flushing
@@ -126,17 +126,17 @@
 }
 
 #ifdef CONFIG_SMP
-extern void sb1___flush_cache_all_ipi(void *ignored);
-asm("sb1___flush_cache_all_ipi = local_sb1___flush_cache_all");
+extern void sb1_force_flush_cache_all_ipi(void *ignored);
+asm("sb1_force_flush_cache_all_ipi = local_sb1_force_flush_cache_all");
 
-static void sb1___flush_cache_all(void)
+static void sb1_force_flush_cache_all(void)
 {
-	smp_call_function(sb1___flush_cache_all_ipi, 0, 1, 1);
-	local_sb1___flush_cache_all();
+	smp_call_function(sb1_force_flush_cache_all_ipi, 0, 1, 1);
+	local_sb1_force_flush_cache_all();
 }
 #else
-extern void sb1___flush_cache_all(void);
-asm("sb1___flush_cache_all = local_sb1___flush_cache_all");
+extern void sb1_force_flush_cache_all(void);
+asm("sb1_force_flush_cache_all = local_sb1_force_flush_cache_all");
 #endif

@@ -257,7 +257,7 @@
 	 * conservatively flush the entire caches on all processors
 	 * (ouch).
 	 */
-	sb1___flush_cache_all();
+	sb1_force_flush_cache_all();
 }
 
 static inline void protected_flush_icache_line(unsigned long addr)
@@ -506,7 +506,7 @@
 	_copy_page = sb1_copy_page;
 
 	_flush_cache_all = sb1_flush_cache_all;
-	___flush_cache_all = sb1___flush_cache_all;
+	_force_flush_cache_all = sb1_force_flush_cache_all;
 	_flush_cache_mm = (void (*)(struct mm_struct *))sb1_nop;
 	_flush_cache_range = (void *) sb1_nop;
 	_flush_page_to_ram = sb1_flush_page_to_ram;
Index: arch/mips/mm/c-sr7100.c
===================================================================
RCS file: /cvsroot/linux-mips/linux/arch/mips/mm/c-sr7100.c,v
retrieving revision 1.1
diff -u -r1.1 c-sr7100.c
--- arch/mips/mm/c-sr7100.c	19 Jan 2002 21:17:35 -0000	1.1
+++ arch/mips/mm/c-sr7100.c	29 May 2002 19:00:42 -0000
@@ -419,7 +419,7 @@
 static void __init setup_scache_funcs(void)
 {
         _flush_cache_all = sr7100_flush_cache_all_pc;
-        ___flush_cache_all = sr7100_nuke_caches;
+        _force_flush_cache_all = sr7100_nuke_caches;
 	_flush_cache_mm = sr7100_flush_cache_mm_pc;
 	_flush_cache_range = sr7100_flush_cache_range_pc;
 	_flush_cache_page = sr7100_flush_cache_page_pc;
Index: arch/mips/mm/c-tx39.c
===================================================================
RCS file: /cvsroot/linux-mips/linux/arch/mips/mm/c-tx39.c,v
retrieving revision 1.5
diff -u -r1.5 c-tx39.c
--- arch/mips/mm/c-tx39.c	30 Nov 2001 18:34:09 -0000	1.5
+++ arch/mips/mm/c-tx39.c	29 May 2002 19:00:43 -0000
@@ -286,7 +286,7 @@
 	case CPU_TX3912:
 		/* TX39/H core (writethru direct-map cache) */
 		_flush_cache_all	= tx39h_flush_icache_all;
-		___flush_cache_all	= tx39h_flush_icache_all;
+		_force_flush_cache_all	= tx39h_flush_icache_all;
 		_flush_cache_mm		= (void *) tx39h_flush_icache_all;
 		_flush_cache_range	= (void *) tx39h_flush_icache_all;
 		_flush_cache_page	= (void *) tx39h_flush_icache_all;
@@ -308,7 +308,7 @@
 		/* board-dependent init code may set WBON */
 
 		_flush_cache_all = tx39_flush_cache_all;
-		___flush_cache_all = tx39_flush_cache_all;
+		_force_flush_cache_all = tx39_flush_cache_all;
 		_flush_cache_mm = tx39_flush_cache_mm;
 		_flush_cache_range = tx39_flush_cache_range;
 		_flush_cache_page = tx39_flush_cache_page;
Index: arch/mips/mm/c-tx49.c
===================================================================
RCS file: /cvsroot/linux-mips/linux/arch/mips/mm/c-tx49.c,v
retrieving revision 1.3
diff -u -r1.3 c-tx49.c
--- arch/mips/mm/c-tx49.c	30 Nov 2001 18:34:09 -0000	1.3
+++ arch/mips/mm/c-tx49.c	29 May 2002 19:00:43 -0000
@@ -423,7 +423,7 @@
 		_flush_cache_page = r49_flush_cache_page_d32i32;
 		break;
 	}
-	___flush_cache_all = _flush_cache_all;
+	_force_flush_cache_all = _flush_cache_all;
 
 	_flush_icache_page = r4k_flush_icache_page;
 
@@ -434,5 +434,5 @@
 	_flush_cache_sigtramp = r4k_flush_cache_sigtramp;
 	_flush_icache_range = r4k_flush_icache_range;	/* Ouch */
 
-	__flush_cache_all();
+	force_flush_cache_all();
 }
Index: arch/mips/mm/init.c
===================================================================
RCS file: /cvsroot/linux-mips/linux/arch/mips/mm/init.c,v
retrieving revision 1.6
diff -u -r1.6 init.c
--- arch/mips/mm/init.c	18 Mar 2002 22:48:17 -0000	1.6
+++ arch/mips/mm/init.c	29 May 2002 19:00:43 -0000
@@ -49,7 +49,7 @@
 asmlinkage int sys_cacheflush(void *addr, int bytes, int cache)
 {
 	/* This should flush more selectivly ...  */
-	__flush_cache_all();
+	force_flush_cache_all();
 
 	return 0;
 }
Index: arch/mips/mm/loadmmu.c
===================================================================
RCS file: /cvsroot/linux-mips/linux/arch/mips/mm/loadmmu.c,v
retrieving revision 1.13
diff -u -r1.13 loadmmu.c
--- arch/mips/mm/loadmmu.c	9 May 2002 17:22:35 -0000	1.13
+++ arch/mips/mm/loadmmu.c	29 May 2002 19:00:43 -0000
@@ -24,7 +24,7 @@
 
 /* Cache operations. */
 void (*_flush_cache_all)(void);
-void (*___flush_cache_all)(void);
+void (*_force_flush_cache_all)(void);
 void (*_flush_cache_mm)(struct mm_struct *mm);
 void (*_flush_cache_range)(struct mm_struct *mm, unsigned long start,
 			  unsigned long end);
Index: arch/mips64/mm/c-sb1.c
===================================================================
RCS file: /cvsroot/linux-mips/linux/arch/mips64/mm/c-sb1.c,v
retrieving revision 1.6
diff -u -r1.6 c-sb1.c
--- arch/mips64/mm/c-sb1.c	24 Apr 2002 17:30:19 -0000	1.6
+++ arch/mips64/mm/c-sb1.c	29 May 2002 19:00:43 -0000
@@ -111,24 +111,24 @@
 		  "r" (KSEG0), "i" (Index_Invalidate_I));
 }
 
-static void local_sb1___flush_cache_all(void)
+static void local_sb1_force_flush_cache_all(void)
 {
 	local_sb1___flush_dcache_all();
 	local_sb1___flush_icache_all();
 }
 
 #ifdef CONFIG_SMP
-extern void sb1___flush_cache_all_ipi(void *ignored);
-asm("sb1___flush_cache_all_ipi = local_sb1___flush_cache_all");
+extern void sb1_force_flush_cache_all_ipi(void *ignored);
+asm("sb1_force_flush_cache_all_ipi = local_sb1_force_flush_cache_all");
 
-static void sb1___flush_cache_all(void)
+static void sb1_force_flush_cache_all(void)
 {
-	smp_call_function(sb1___flush_cache_all_ipi, 0, 1, 1);
-	local_sb1___flush_cache_all();
+	smp_call_function(sb1_force_flush_cache_all_ipi, 0, 1, 1);
+	local_sb1_force_flush_cache_all();
 }
 #else
-extern void sb1___flush_cache_all(void);
-asm("sb1___flush_cache_all = local_sb1___flush_cache_all");
+extern void sb1_force_flush_cache_all(void);
+asm("sb1_force_flush_cache_all = local_sb1_force_flush_cache_all");
 #endif

@@ -256,7 +256,7 @@
 	 *
 	 * Bumping the ASID may well be cheaper, need to experiment ...
 	 */
-	sb1___flush_cache_all();
+	sb1_force_flush_cache_all();
 }
 
 static inline void protected_flush_icache_line(unsigned long addr)
@@ -505,7 +505,7 @@
 	_copy_page = sb1_copy_page;
 
 	_flush_cache_all = sb1_flush_cache_all;
-	___flush_cache_all = sb1___flush_cache_all;
+	_force_flush_cache_all = sb1_force_flush_cache_all;
 	_flush_cache_mm = (void (*)(struct mm_struct *))sb1_nop;
 	_flush_cache_range = (void *) sb1_nop;
 	_flush_page_to_ram = sb1_flush_page_to_ram;
Index: arch/mips64/mm/loadmmu.c
===================================================================
RCS file: /cvsroot/linux-mips/linux/arch/mips64/mm/loadmmu.c,v
retrieving revision 1.6
diff -u -r1.6 loadmmu.c
--- arch/mips64/mm/loadmmu.c	19 Feb 2002 17:43:02 -0000	1.6
+++ arch/mips64/mm/loadmmu.c	29 May 2002 19:00:43 -0000
@@ -25,7 +25,7 @@
 
 /* Cache operations. */
 void (*_flush_cache_all)(void);
-void (*___flush_cache_all)(void);
+void (*_force_flush_cache_all)(void);
 void (*_flush_cache_mm)(struct mm_struct *mm);
 void (*_flush_cache_range)(struct mm_struct *mm, unsigned long start,
                            unsigned long end);
Index: include/asm-mips/pgtable.h
===================================================================
RCS file: /cvsroot/linux-mips/linux/include/asm-mips/pgtable.h,v
retrieving revision 1.17
diff -u -r1.17 pgtable.h
--- include/asm-mips/pgtable.h	21 Apr 2002 20:34:31 -0000	1.17
+++ include/asm-mips/pgtable.h	29 May 2002 19:00:44 -0000
@@ -33,7 +33,7 @@
  *  - flush_icache_all() flush the entire instruction cache
  */
 extern void (*_flush_cache_all)(void);
-extern void (*___flush_cache_all)(void);
+extern void (*_force_flush_cache_all)(void);
 extern void (*_flush_cache_mm)(struct mm_struct *mm);
 extern void (*_flush_cache_range)(struct mm_struct *mm, unsigned long start,
 	unsigned long end);
@@ -49,7 +49,7 @@
 #define flush_dcache_page(page)			do { } while (0)
 
 #define flush_cache_all()		_flush_cache_all()
-#define __flush_cache_all()		___flush_cache_all()
+#define force_flush_cache_all()		_force_flush_cache_all()
 #define flush_cache_mm(mm)		_flush_cache_mm(mm)
 #define flush_cache_range(mm,start,end)	_flush_cache_range(mm,start,end)
 #define flush_cache_page(vma,page)	_flush_cache_page(vma, page)
Index: include/asm-mips64/pgtable.h
===================================================================
RCS file: /cvsroot/linux-mips/linux/include/asm-mips64/pgtable.h,v
retrieving revision 1.14
diff -u -r1.14 pgtable.h
--- include/asm-mips64/pgtable.h	28 May 2002 20:25:38 -0000	1.14
+++ include/asm-mips64/pgtable.h	29 May 2002 19:00:44 -0000
@@ -28,7 +28,7 @@
  *  - flush_page_to_ram(page) write back kernel page to ram
  */
 extern void (*_flush_cache_all)(void);
-extern void (*___flush_cache_all)(void);
+extern void (*_force_flush_cache_all)(void);
 extern void (*_flush_cache_mm)(struct mm_struct *mm);
 extern void (*_flush_cache_range)(struct mm_struct *mm, unsigned long start,
 	unsigned long end);
@@ -47,7 +47,7 @@

 #define flush_cache_all()		_flush_cache_all()
-#define __flush_cache_all()		___flush_cache_all()
+#define force_flush_cache_all()		_force_flush_cache_all()
 #define flush_dcache_page(page)		do { } while (0)
 
 #ifdef CONFIG_CPU_R10000

---

From: "Maciej W. Rozycki" <[email-masked]>
Date: Wed, 29 May 2002 21:50:10 +0200 (MET DST)

> objections, Ralf, could  you apply this?

 That looks fine to me.  I'd keep the leading double underscore, though --
it acts as a warning sign the function is internal and low-level and thus
it should not be used without an appropriate justification.

> sys_sysmips->CACHE_FLUSH).  

 Ugh, it's not the only place of inconsistency...

> it would be nice to at least be consistent.

 Well, at least r3k uses WT for dcache, so it really doesn't matter unless
what you want to achieve is to hit performance.  I suspect this is also
the case for the others that ignore dcache flushes.  The L1 vs L2 issue
should be investigated where applicable. 

 This reminds me to check ld.so (and libdl) for missing sys_cacheflush()
invocations as well...

> helpful pointer to docs on the subject?

 It's compatibility crap, like the whole sysmips() stuff, I am afraid. 
Use sys_cacheflush() normally. 

  Maciej

-- 
+  Maciej W. Rozycki, Technical University of Gdansk, Poland   +
+--------------------------------------------------------------+
+        e-mail: [email-masked], PGP key available        +

---

From: "Justin Carlson" <[email-masked]>
Date: 29 May 2002 13:20:46 -0700

> it should not be used without an appropriate justification.

Yes, you're right, it's not a standard function to have.  But I'm
already wondering if this is not the right thing to do.  See below.

> should be investigated where applicable. 

Are the general semantics of the thing just broken, then?  We already
ignore the arguments to sys_cacheflush; would redefining the syscall to
mean "flush the caches in such a way that I won't get stale instructions
from this address range" actually break any current programs? 
(Evidently not, if several ports are already doing it that way)...

More to the point, does __flush_cache_all() serve any useful purpose at
all, or can it just be replaced with appropriate invocations of
flush_icache_range()?   Other than internal use for the individual port
cache routines, it's *only* used in the syscalls and the gdb stub. 

I'd like to hear the rationale for __flush_cache_all() from the original
author; it appears to have shown up in CVS a little more than a year
ago, but I don't know who sent the patch to Ralf.  Ralf, do you
remember?

Thanks,
  Justin

---

From: "Kevin D. Kissell" <[email-masked]>
Date: Wed, 29 May 2002 23:03:20 +0200

> helpful pointer to docs on the subject?

I agree that things need to be straightened out a bit here,
or at least better documented, but things may not be as bad 
as you think, depending on the actual use of the system calls.  
Specifically, if what one is worried about is ensuring that a 
modification to memory gets picked up by the instruction 
stream, as in setting/clearing a breakpoint or executing a JIT,
one does not need to flush the dcache *if* the dcache
is write-through in the first place - as it is for most if
not all of the processors you list above as flushing the
icache only.  (As a parenthetical note, future MIPS
processors won't need a system call to deal with 
instruction stream modifications, but we need to deal
with the here-and-now).

While trampolines, breakpointing and JITing are the main 
uses of user-mode cache manipulation (drivers are a whole 
'nother story), we really should have distinct capabilities for 
I-stream modification and for explicit synchronizations of 
the data storage hierarchy, for non-coherent multiprocessors
and user-manipulated DMA buffers.  As to whether
those capabilities should be distinguished by system
call (sysmips vs. cacheflush) or by parameter to the
same system call, I don't have enough data to form
an opinion at this point.

            Kevin K.

---

From: "Maciej W. Rozycki" <[email-masked]>
Date: Wed, 29 May 2002 23:00:21 +0200 (MET DST)

> (Evidently not, if several ports are already doing it that way)...

 You mean removing the DCACHE operation?  The overlying _flush_cache() 
library function is specified by the MIPS ABI supplement, so we shouldn't
really redefine it.  Also a reasonable use for it may exist -- a userland
program touching hardware directly (say X11) may want to use cached
accesses for performance reasons (e.g. because cache can do prefetches on
reads).

 I guess the intent for the ICACHE operation is to assure ICACHE vs DCACHE
coherency and the intent for the DCACHE operation is to assure DCACHE vs
RAM coherency.  If the operations do not work in this way for a given
backend, then there is a bug in it. 

> cache routines, it's *only* used in the syscalls and the gdb stub. 

 It does serve a useful purpose.  Or at least it should.  This reminds me
of adding flushing of WB caches at a system shutdown.  The function should
remain at least for this purpose. 

 If there are places you are absolutely sure flush_icache_range() would
suffice, feel free to replace the call.  There are not many
__flush_cache_all() invocations.

> ago, but I don't know who sent the patch to Ralf.  Ralf, do you

 I converted a few flush_cache_all() invocations to __flush_cache_all() 
where appropriate late last year, but the function is a bit older.  I
think you might dig the linux-kernel list archives for a discussion on the
semantics of flush_cache_all() (it's a nop for many MIPS CPUs) and
friends.  The short description in Documentation/cachetlb.txt is a bit
insufficient, I'm afraid. 

  Maciej

---

From: Ralf Baechle <[email-masked]>
Date: Wed, 29 May 2002 14:07:59 -0700

> implementations assume L1 only.

The operation got introduced for the R10000 where we only need to flush
the caches during initialization or the (unlikely on Origin) case of

> least, it's rather confusing to have all of:

No.  You may have noticed that I already introduced a bunch of local_*()
functions for the TLB stuff for the same reason - the old functions had
poor names.  The common Linux conventions to use extra underscores for a
more basic version of a function (like get_user vs __get_user etc.) is
frequently not expressive enough.

> ___flush_cache_all()

Odd number of underscores means it's a pointer ;)

> {_}force_flush_l1_caches() or somesuch.

Ok.

> Shouldn't that be a flush_icache_range() call anyways?

Yes.

  Ralf

---

From: Ralf Baechle <[email-masked]>
Date: Wed, 29 May 2002 14:09:59 -0700

> sys_sysmips->CACHE_FLUSH).  

These are compacrapability syscalls inherited from Risc/OS and IRIX.  Even
gcc generated trampoline code expects to have these available.

  Ralf

---

From: Ralf Baechle <[email-masked]>
Date: Wed, 29 May 2002 14:28:55 -0700

> an opinion at this point.

It should clearly be cacheflush(2); sysmips(2) is too coarse, too ugly
interface.  Another thing we'll still have to implement is the
cachectl(2) syscall; for certain systems and applications fine control
of the caching mode use for a memory mapping may result in major performance
improvments.

  Ralf

---

From: Ralf Baechle <[email-masked]>
Date: Wed, 29 May 2002 14:33:05 -0700

> insufficient, I'm afraid. 

I don't like that function very much; it's sort of a shotgun approach
to flushing caches in a part of the kernel that's not too performance
relevant.  The whole interface sucks, should be replaced by something
more finegrained.

  Ralf

---

From: "Maciej W. Rozycki" <[email-masked]>
Date: Wed, 29 May 2002 23:46:58 +0200 (MET DST)

> relevant.  The whole interface sucks, should be replaced by something

 Well, I suspect the API might be somewhat influenced by SPARC's oddities. 
;-)

---

From: Ralf Baechle <[email-masked]>
Date: Wed, 29 May 2002 15:46:24 -0700

>  Well, I suspect the API might be somewhat influenced by SPARC's oddities. 

Historically that's certainly true.

As a general complaint about the style of interfaces of the cache stuff -
they're too low level.  Frequently we just don't know enough about the
situation to optimize the flush operation.

  Ralf

---

From: "Justin Carlson" <[email-masked]>
Date: 29 May 2002 15:59:05 -0700

> accesses for performance reasons (e.g. because cache can do prefetches on

This is true;  I hadn't thought about the cases of userland touching
hardware directly.  Of course, I think these cases should be hunted down
and eliminated (go framebuffer device!), but alas, if that ever really
happens, it's not going to be soon.

> backend, then there is a bug in it. 

We may theoretically need these capabilities, but, given that several of
the ports already get this wrong and no loud screaming has been heard, I
wonder about the real need.

Assuming we do need these capabilities in the syscall (and, really, it's
pretty easy to make them right), I'm actually more wondering about the
need for the __flush_cache_all() in the first place.  The gdb stubs can
use the defined interface without a problem (and, indeed, more
efficiently.  What they're doing now is overkill).  That leaves the
syscalls, which, if implemented properly, should also use the normal
interface.

I'm still looking for a reason for the existence of __flush_cache_all().

> insufficient, I'm afraid. 

Woefully insufficient.  :)  I'm going to have a stab at editing that
file when I feel like I have a complete understanding.  Don't hold your
breath.  :)

-Justin

---

From: Jun Sun <[email-masked]>
Date: Wed, 29 May 2002 16:24:37 -0700

> I'm still looking for a reason for the existence of __flush_cache_all().

It is needed by kgdb where gdb client may modify several instructions before a 
'c' command is issued.  In that case, you cannot use flush_icache_range 
because you don't know the range.  It is probably not safe either as the data 
cache may not be written back yet

Does flush_icache_range() mandates write-back of dcache in the same range?  If 
it does, you might be able to get away with flush_icache_range(ICACHE_BEGIN, 
ICACHE_END).

Like someone else has pointed out, __flush_cache_all() is introduced to ensure 
i-cache/d-cache consistency.  I remember it was shortly introduced after we 
had the first cache-coherent system where flush_cache_all() is a null function.

Jun

---

From: Florian Laws <[email-masked]>
Date: Thu, 30 May 2002 14:31:20 +0200

> the caches during initialization or the (unlikely on Origin) case of

Which case?

Thanks,

Florian