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

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

 



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


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

--
John David Anglin	dave.anglin@xxxxxxxx



[Index of Archives]     [Linux SoC]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux