diff mbox

[PA-RISC] Fix SMP cache related HPMCs running libgomp testsuite

Message ID BLU0-SMTP33BC220C6C43A14F8BF18697390@phx.gbl (mailing list archive)
State Rejected
Headers show

Commit Message

John David Anglin July 31, 2011, 10:11 p.m. UTC
After a considerable amount of testing, I have found that the HPMCs  
that I have been seeing
in the GCC libgomp testsuite are caused by the implementation of  
flush_user_dcache_range.
The current implementation doesn't flush all aliases (e.g., kernel)  
and this leads to cache corruption.
As with flush_cache_mm, we need to either whack the entire cache, or  
do something similar to that
in flush_dcache_page.

The for-[1-8].C tests are the principle problem.  They turn "for  
loops" into a large number of
parallel threads.

I was hoping someone else would have solved this problem, but arm, for  
example, appears to
flush the entire cache on vipt architectures.

The problem with the attached patch is that flushing the entire data  
cache on the rp3440 is
incredibly slow (0x40000 iterations).  I have a patch to unroll the  
loops in flush_instruction_cache_local
and flush_data_cache_local, but still they are still slow.

We are probably missing opportunities to skip flushing the instruction  
cache, but still the data
cache flush will be slow.

What I think needs to be done is to determine the ptep pointer for the  
starting and ending addresses
when the context is current.  From this, we can get the page pointer.   
Then, we may be able to
call flush_dcache_page.  Currently, the only page table lookup that I  
see is in entry.S.

Maybe there is a simpler method?  For example, is there a way to force  
the kernel to use
flush_cache_page.

I'm not sure the change is needed on machines that support non  
equivalent aliases.

Dave

--
John David Anglin	dave.anglin@bell.net
diff mbox

Patch

diff --git a/arch/parisc/kernel/cache.c b/arch/parisc/kernel/cache.c
index 83335f3..532e3bf 100644
--- a/arch/parisc/kernel/cache.c
+++ b/arch/parisc/kernel/cache.c
@@ -472,10 +472,14 @@  void flush_cache_mm(struct mm_struct *mm)
 void
 flush_user_dcache_range(unsigned long start, unsigned long end)
 {
+#ifdef CONFIG_SMP
+	flush_data_cache();
+#else
 	if ((end - start) < parisc_cache_flush_threshold)
 		flush_user_dcache_range_asm(start,end);
 	else
 		flush_data_cache();
+#endif
 }
 
 void