Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

tools/perf: Add required memory barriers

To match patch bf378d341e48 ("perf: Fix perf ring buffer memory
ordering") change userspace to also adhere to the ordering outlined.

Signed-off-by: Peter Zijlstra <peterz@infradead.org>
Cc: Michael Neuling <mikey@neuling.org>
Cc: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
Cc: james.hogan@imgtec.com
Cc: Vince Weaver <vince@deater.net>
Cc: Victor Kaplansky <VICTORK@il.ibm.com>
Cc: Oleg Nesterov <oleg@redhat.com>
Cc: Anton Blanchard <anton@samba.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
Cc: Michael Ellerman <michael@ellerman.id.au>
Link: http://lkml.kernel.org/r/20131030104246.GH16117@laptop.programming.kicks-ass.net
Signed-off-by: Ingo Molnar <mingo@kernel.org>

authored by

Peter Zijlstra and committed by
Ingo Molnar
a94d342b 0a196848

+49 -16
+47 -12
tools/perf/perf.h
··· 4 4 #include <asm/unistd.h> 5 5 6 6 #if defined(__i386__) 7 + #define mb() asm volatile("lock; addl $0,0(%%esp)" ::: "memory") 8 + #define wmb() asm volatile("lock; addl $0,0(%%esp)" ::: "memory") 7 9 #define rmb() asm volatile("lock; addl $0,0(%%esp)" ::: "memory") 8 10 #define cpu_relax() asm volatile("rep; nop" ::: "memory"); 9 11 #define CPUINFO_PROC "model name" ··· 15 13 #endif 16 14 17 15 #if defined(__x86_64__) 16 + #define mb() asm volatile("mfence" ::: "memory") 17 + #define wmb() asm volatile("sfence" ::: "memory") 18 18 #define rmb() asm volatile("lfence" ::: "memory") 19 19 #define cpu_relax() asm volatile("rep; nop" ::: "memory"); 20 20 #define CPUINFO_PROC "model name" ··· 27 23 28 24 #ifdef __powerpc__ 29 25 #include "../../arch/powerpc/include/uapi/asm/unistd.h" 26 + #define mb() asm volatile ("sync" ::: "memory") 27 + #define wmb() asm volatile ("sync" ::: "memory") 30 28 #define rmb() asm volatile ("sync" ::: "memory") 31 - #define cpu_relax() asm volatile ("" ::: "memory"); 32 29 #define CPUINFO_PROC "cpu" 33 30 #endif 34 31 35 32 #ifdef __s390__ 33 + #define mb() asm volatile("bcr 15,0" ::: "memory") 34 + #define wmb() asm volatile("bcr 15,0" ::: "memory") 36 35 #define rmb() asm volatile("bcr 15,0" ::: "memory") 37 - #define cpu_relax() asm volatile("" ::: "memory"); 38 36 #endif 39 37 40 38 #ifdef __sh__ 41 39 #if defined(__SH4A__) || defined(__SH5__) 40 + # define mb() asm volatile("synco" ::: "memory") 41 + # define wmb() asm volatile("synco" ::: "memory") 42 42 # define rmb() asm volatile("synco" ::: "memory") 43 43 #else 44 + # define mb() asm volatile("" ::: "memory") 45 + # define wmb() asm volatile("" ::: "memory") 44 46 # define rmb() asm volatile("" ::: "memory") 45 47 #endif 46 - #define cpu_relax() asm volatile("" ::: "memory") 47 48 #define CPUINFO_PROC "cpu type" 48 49 #endif 49 50 50 51 #ifdef __hppa__ 52 + #define mb() asm volatile("" ::: "memory") 53 + #define wmb() asm volatile("" ::: "memory") 51 54 #define rmb() asm volatile("" ::: "memory") 52 - #define cpu_relax() asm volatile("" ::: "memory"); 53 55 #define CPUINFO_PROC "cpu" 54 56 #endif 55 57 56 58 #ifdef __sparc__ 59 + #ifdef __LP64__ 60 + #define mb() asm volatile("ba,pt %%xcc, 1f\n" \ 61 + "membar #StoreLoad\n" \ 62 + "1:\n":::"memory") 63 + #else 64 + #define mb() asm volatile("":::"memory") 65 + #endif 66 + #define wmb() asm volatile("":::"memory") 57 67 #define rmb() asm volatile("":::"memory") 58 - #define cpu_relax() asm volatile("":::"memory") 59 68 #define CPUINFO_PROC "cpu" 60 69 #endif 61 70 62 71 #ifdef __alpha__ 72 + #define mb() asm volatile("mb" ::: "memory") 73 + #define wmb() asm volatile("wmb" ::: "memory") 63 74 #define rmb() asm volatile("mb" ::: "memory") 64 - #define cpu_relax() asm volatile("" ::: "memory") 65 75 #define CPUINFO_PROC "cpu model" 66 76 #endif 67 77 68 78 #ifdef __ia64__ 79 + #define mb() asm volatile ("mf" ::: "memory") 80 + #define wmb() asm volatile ("mf" ::: "memory") 69 81 #define rmb() asm volatile ("mf" ::: "memory") 70 82 #define cpu_relax() asm volatile ("hint @pause" ::: "memory") 71 83 #define CPUINFO_PROC "model name" ··· 92 72 * Use the __kuser_memory_barrier helper in the CPU helper page. See 93 73 * arch/arm/kernel/entry-armv.S in the kernel source for details. 94 74 */ 75 + #define mb() ((void(*)(void))0xffff0fa0)() 76 + #define wmb() ((void(*)(void))0xffff0fa0)() 95 77 #define rmb() ((void(*)(void))0xffff0fa0)() 96 - #define cpu_relax() asm volatile("":::"memory") 97 78 #define CPUINFO_PROC "Processor" 98 79 #endif 99 80 100 81 #ifdef __aarch64__ 101 - #define rmb() asm volatile("dmb ld" ::: "memory") 82 + #define mb() asm volatile("dmb ish" ::: "memory") 83 + #define wmb() asm volatile("dmb ishld" ::: "memory") 84 + #define rmb() asm volatile("dmb ishst" ::: "memory") 102 85 #define cpu_relax() asm volatile("yield" ::: "memory") 103 86 #endif 104 87 105 88 #ifdef __mips__ 106 - #define rmb() asm volatile( \ 89 + #define mb() asm volatile( \ 107 90 ".set mips2\n\t" \ 108 91 "sync\n\t" \ 109 92 ".set mips0" \ 110 93 : /* no output */ \ 111 94 : /* no input */ \ 112 95 : "memory") 113 - #define cpu_relax() asm volatile("" ::: "memory") 96 + #define wmb() mb() 97 + #define rmb() mb() 114 98 #define CPUINFO_PROC "cpu model" 115 99 #endif 116 100 117 101 #ifdef __arc__ 102 + #define mb() asm volatile("" ::: "memory") 103 + #define wmb() asm volatile("" ::: "memory") 118 104 #define rmb() asm volatile("" ::: "memory") 119 - #define cpu_relax() rmb() 120 105 #define CPUINFO_PROC "Processor" 121 106 #endif 122 107 123 108 #ifdef __metag__ 109 + #define mb() asm volatile("" ::: "memory") 110 + #define wmb() asm volatile("" ::: "memory") 124 111 #define rmb() asm volatile("" ::: "memory") 125 - #define cpu_relax() asm volatile("" ::: "memory") 126 112 #define CPUINFO_PROC "CPU" 127 113 #endif 114 + 115 + #define barrier() asm volatile ("" ::: "memory") 116 + 117 + #ifndef cpu_relax 118 + #define cpu_relax() barrier() 119 + #endif 120 + 121 + #define ACCESS_ONCE(x) (*(volatile typeof(x) *)&(x)) 122 + 128 123 129 124 #include <time.h> 130 125 #include <unistd.h>
-2
tools/perf/tests/rdpmc.c
··· 9 9 10 10 #if defined(__x86_64__) || defined(__i386__) 11 11 12 - #define barrier() asm volatile("" ::: "memory") 13 - 14 12 static u64 rdpmc(unsigned int counter) 15 13 { 16 14 unsigned int low, high;
+2 -2
tools/perf/util/evlist.h
··· 177 177 static inline unsigned int perf_mmap__read_head(struct perf_mmap *mm) 178 178 { 179 179 struct perf_event_mmap_page *pc = mm->base; 180 - int head = pc->data_head; 180 + int head = ACCESS_ONCE(pc->data_head); 181 181 rmb(); 182 182 return head; 183 183 } ··· 190 190 /* 191 191 * ensure all reads are done before we write the tail out. 192 192 */ 193 - /* mb(); */ 193 + mb(); 194 194 pc->data_tail = tail; 195 195 } 196 196