We're going to be adding a few new barrier primitives, and in order to avoid endless duplication make more agressive use of asm-generic/barrier.h. Change the asm-generic/barrier.h such that it allows partial barrier definitions and fills out the rest with defaults. There are a few architectures (h8300, m32r, m68k) that could probably do away with their barrier.h file entirely but are kept for now due to their unconventional nop() implementation. Cc: Tony Luck <tony.luck@xxxxxxxxx> Cc: Oleg Nesterov <oleg@xxxxxxxxxx> Cc: Benjamin Herrenschmidt <benh@xxxxxxxxxxxxxxxxxxx> Cc: Frederic Weisbecker <fweisbec@xxxxxxxxx> Cc: Mathieu Desnoyers <mathieu.desnoyers@xxxxxxxxxx> Cc: Michael Ellerman <michael@xxxxxxxxxxxxxx> Cc: Michael Neuling <mikey@xxxxxxxxxxx> Cc: Russell King <linux@xxxxxxxxxxxxxxxx> Cc: Geert Uytterhoeven <geert@xxxxxxxxxxxxxx> Cc: Heiko Carstens <heiko.carstens@xxxxxxxxxx> Cc: Linus Torvalds <torvalds@xxxxxxxxxxxxxxxxxxxx> Cc: Martin Schwidefsky <schwidefsky@xxxxxxxxxx> Cc: Victor Kaplansky <VICTORK@xxxxxxxxxx> Suggested-by: Geert Uytterhoeven <geert@xxxxxxxxxxxxxx> Reviewed-by: "Paul E. McKenney" <paulmck@xxxxxxxxxxxxxxxxxx> Signed-off-by: Peter Zijlstra <peterz@xxxxxxxxxxxxx> --- arch/alpha/include/asm/barrier.h | 25 ++-------- arch/arc/include/asm/Kbuild | 1 arch/arc/include/asm/atomic.h | 5 ++ arch/arc/include/asm/barrier.h | 42 ----------------- arch/avr32/include/asm/barrier.h | 17 ++----- arch/blackfin/include/asm/barrier.h | 18 ------- arch/cris/include/asm/Kbuild | 1 arch/cris/include/asm/barrier.h | 25 ---------- arch/frv/include/asm/barrier.h | 8 --- arch/h8300/include/asm/barrier.h | 21 -------- arch/hexagon/include/asm/Kbuild | 1 arch/hexagon/include/asm/barrier.h | 41 ----------------- arch/m32r/include/asm/barrier.h | 80 ---------------------------------- arch/m68k/include/asm/barrier.h | 14 ----- arch/microblaze/include/asm/Kbuild | 1 arch/microblaze/include/asm/barrier.h | 27 ----------- arch/mn10300/include/asm/Kbuild | 1 arch/mn10300/include/asm/barrier.h | 37 --------------- arch/parisc/include/asm/Kbuild | 1 arch/parisc/include/asm/barrier.h | 35 -------------- arch/score/include/asm/Kbuild | 1 arch/score/include/asm/barrier.h | 16 ------ arch/sh/include/asm/barrier.h | 21 +------- arch/sparc/include/asm/barrier_32.h | 11 ---- arch/tile/include/asm/barrier.h | 68 ---------------------------- arch/unicore32/include/asm/barrier.h | 11 ---- arch/xtensa/include/asm/barrier.h | 9 --- include/asm-generic/barrier.h | 44 ++++++++++++------ 28 files changed, 64 insertions(+), 518 deletions(-) Index: linux-2.6/arch/alpha/include/asm/barrier.h =================================================================== --- linux-2.6.orig/arch/alpha/include/asm/barrier.h 2013-11-07 17:03:11.626900787 +0100 +++ linux-2.6/arch/alpha/include/asm/barrier.h 2013-11-07 17:03:11.607900434 +0100 @@ -3,33 +3,18 @@ #include <asm/compiler.h> -#define mb() \ -__asm__ __volatile__("mb": : :"memory") +#define mb() __asm__ __volatile__("mb": : :"memory") +#define rmb() __asm__ __volatile__("mb": : :"memory") +#define wmb() __asm__ __volatile__("wmb": : :"memory") -#define rmb() \ -__asm__ __volatile__("mb": : :"memory") - -#define wmb() \ -__asm__ __volatile__("wmb": : :"memory") - -#define read_barrier_depends() \ -__asm__ __volatile__("mb": : :"memory") +#define read_barrier_depends() __asm__ __volatile__("mb": : :"memory") #ifdef CONFIG_SMP #define __ASM_SMP_MB "\tmb\n" -#define smp_mb() mb() -#define smp_rmb() rmb() -#define smp_wmb() wmb() -#define smp_read_barrier_depends() read_barrier_depends() #else #define __ASM_SMP_MB -#define smp_mb() barrier() -#define smp_rmb() barrier() -#define smp_wmb() barrier() -#define smp_read_barrier_depends() do { } while (0) #endif -#define set_mb(var, value) \ -do { var = value; mb(); } while (0) +#include <asm-generic/barrier.h> #endif /* __BARRIER_H */ Index: linux-2.6/arch/arc/include/asm/Kbuild =================================================================== --- linux-2.6.orig/arch/arc/include/asm/Kbuild 2013-11-07 17:03:11.626900787 +0100 +++ linux-2.6/arch/arc/include/asm/Kbuild 2013-11-07 17:03:11.607900434 +0100 @@ -47,3 +47,4 @@ generic-y += vga.h generic-y += xor.h generic-y += preempt.h +generic-y += barrier.h Index: linux-2.6/arch/arc/include/asm/atomic.h =================================================================== --- linux-2.6.orig/arch/arc/include/asm/atomic.h 2013-11-07 17:03:11.626900787 +0100 +++ linux-2.6/arch/arc/include/asm/atomic.h 2013-11-07 17:03:11.607900434 +0100 @@ -190,6 +190,11 @@ #endif /* !CONFIG_ARC_HAS_LLSC */ +#define smp_mb__before_atomic_dec() barrier() +#define smp_mb__after_atomic_dec() barrier() +#define smp_mb__before_atomic_inc() barrier() +#define smp_mb__after_atomic_inc() barrier() + /** * __atomic_add_unless - add unless the number is a given value * @v: pointer of type atomic_t Index: linux-2.6/arch/arc/include/asm/barrier.h =================================================================== --- linux-2.6.orig/arch/arc/include/asm/barrier.h 2013-11-07 17:03:11.626900787 +0100 +++ /dev/null 1970-01-01 00:00:00.000000000 +0000 @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifndef __ASM_BARRIER_H -#define __ASM_BARRIER_H - -#ifndef __ASSEMBLY__ - -/* TODO-vineetg: Need to see what this does, don't we need sync anywhere */ -#define mb() __asm__ __volatile__ ("" : : : "memory") -#define rmb() mb() -#define wmb() mb() -#define set_mb(var, value) do { var = value; mb(); } while (0) -#define set_wmb(var, value) do { var = value; wmb(); } while (0) -#define read_barrier_depends() mb() - -/* TODO-vineetg verify the correctness of macros here */ -#ifdef CONFIG_SMP -#define smp_mb() mb() -#define smp_rmb() rmb() -#define smp_wmb() wmb() -#else -#define smp_mb() barrier() -#define smp_rmb() barrier() -#define smp_wmb() barrier() -#endif - -#define smp_mb__before_atomic_dec() barrier() -#define smp_mb__after_atomic_dec() barrier() -#define smp_mb__before_atomic_inc() barrier() -#define smp_mb__after_atomic_inc() barrier() - -#define smp_read_barrier_depends() do { } while (0) - -#endif - -#endif Index: linux-2.6/arch/avr32/include/asm/barrier.h =================================================================== --- linux-2.6.orig/arch/avr32/include/asm/barrier.h 2013-11-07 17:03:11.626900787 +0100 +++ linux-2.6/arch/avr32/include/asm/barrier.h 2013-11-07 17:03:11.618900638 +0100 @@ -8,22 +8,15 @@ #ifndef __ASM_AVR32_BARRIER_H #define __ASM_AVR32_BARRIER_H -#define nop() asm volatile("nop") - -#define mb() asm volatile("" : : : "memory") -#define rmb() mb() -#define wmb() asm volatile("sync 0" : : : "memory") -#define read_barrier_depends() do { } while(0) -#define set_mb(var, value) do { var = value; mb(); } while(0) +/* + * Weirdest thing ever.. no full barrier, but it has a write barrier! + */ +#define wmb() asm volatile("sync 0" : : : "memory") #ifdef CONFIG_SMP # error "The AVR32 port does not support SMP" -#else -# define smp_mb() barrier() -# define smp_rmb() barrier() -# define smp_wmb() barrier() -# define smp_read_barrier_depends() do { } while(0) #endif +#include <asm-generic/barrier.h> #endif /* __ASM_AVR32_BARRIER_H */ Index: linux-2.6/arch/blackfin/include/asm/barrier.h =================================================================== --- linux-2.6.orig/arch/blackfin/include/asm/barrier.h 2013-11-07 17:03:11.626900787 +0100 +++ linux-2.6/arch/blackfin/include/asm/barrier.h 2013-11-07 17:03:11.619900657 +0100 @@ -23,26 +23,10 @@ # define rmb() do { barrier(); smp_check_barrier(); } while (0) # define wmb() do { barrier(); smp_mark_barrier(); } while (0) # define read_barrier_depends() do { barrier(); smp_check_barrier(); } while (0) -#else -# define mb() barrier() -# define rmb() barrier() -# define wmb() barrier() -# define read_barrier_depends() do { } while (0) #endif -#else /* !CONFIG_SMP */ - -#define mb() barrier() -#define rmb() barrier() -#define wmb() barrier() -#define read_barrier_depends() do { } while (0) - #endif /* !CONFIG_SMP */ -#define smp_mb() mb() -#define smp_rmb() rmb() -#define smp_wmb() wmb() -#define set_mb(var, value) do { var = value; mb(); } while (0) -#define smp_read_barrier_depends() read_barrier_depends() +#include <asm-generic/barrier.h> #endif /* _BLACKFIN_BARRIER_H */ Index: linux-2.6/arch/cris/include/asm/Kbuild =================================================================== --- linux-2.6.orig/arch/cris/include/asm/Kbuild 2013-11-07 17:03:11.626900787 +0100 +++ linux-2.6/arch/cris/include/asm/Kbuild 2013-11-07 17:03:11.619900657 +0100 @@ -12,3 +12,4 @@ generic-y += vga.h generic-y += xor.h generic-y += preempt.h +generic-y += barrier.h Index: linux-2.6/arch/cris/include/asm/barrier.h =================================================================== --- linux-2.6.orig/arch/cris/include/asm/barrier.h 2013-11-07 17:03:11.626900787 +0100 +++ /dev/null 1970-01-01 00:00:00.000000000 +0000 @@ -1,25 +0,0 @@ -#ifndef __ASM_CRIS_BARRIER_H -#define __ASM_CRIS_BARRIER_H - -#define nop() __asm__ __volatile__ ("nop"); - -#define barrier() __asm__ __volatile__("": : :"memory") -#define mb() barrier() -#define rmb() mb() -#define wmb() mb() -#define read_barrier_depends() do { } while(0) -#define set_mb(var, value) do { var = value; mb(); } while (0) - -#ifdef CONFIG_SMP -#define smp_mb() mb() -#define smp_rmb() rmb() -#define smp_wmb() wmb() -#define smp_read_barrier_depends() read_barrier_depends() -#else -#define smp_mb() barrier() -#define smp_rmb() barrier() -#define smp_wmb() barrier() -#define smp_read_barrier_depends() do { } while(0) -#endif - -#endif /* __ASM_CRIS_BARRIER_H */ Index: linux-2.6/arch/frv/include/asm/barrier.h =================================================================== --- linux-2.6.orig/arch/frv/include/asm/barrier.h 2013-11-07 17:03:11.626900787 +0100 +++ linux-2.6/arch/frv/include/asm/barrier.h 2013-11-07 17:03:11.619900657 +0100 @@ -17,13 +17,7 @@ #define mb() asm volatile ("membar" : : :"memory") #define rmb() asm volatile ("membar" : : :"memory") #define wmb() asm volatile ("membar" : : :"memory") -#define read_barrier_depends() do { } while (0) -#define smp_mb() barrier() -#define smp_rmb() barrier() -#define smp_wmb() barrier() -#define smp_read_barrier_depends() do {} while(0) -#define set_mb(var, value) \ - do { var = (value); barrier(); } while (0) +#include <asm-generic/barrier.h> #endif /* _ASM_BARRIER_H */ Index: linux-2.6/arch/h8300/include/asm/barrier.h =================================================================== --- linux-2.6.orig/arch/h8300/include/asm/barrier.h 2013-11-07 17:03:11.626900787 +0100 +++ linux-2.6/arch/h8300/include/asm/barrier.h 2013-11-07 17:03:11.619900657 +0100 @@ -3,27 +3,8 @@ #define nop() asm volatile ("nop"::) -/* - * Force strict CPU ordering. - * Not really required on H8... - */ -#define mb() asm volatile ("" : : :"memory") -#define rmb() asm volatile ("" : : :"memory") -#define wmb() asm volatile ("" : : :"memory") #define set_mb(var, value) do { xchg(&var, value); } while (0) -#define read_barrier_depends() do { } while (0) - -#ifdef CONFIG_SMP -#define smp_mb() mb() -#define smp_rmb() rmb() -#define smp_wmb() wmb() -#define smp_read_barrier_depends() read_barrier_depends() -#else -#define smp_mb() barrier() -#define smp_rmb() barrier() -#define smp_wmb() barrier() -#define smp_read_barrier_depends() do { } while(0) -#endif +#include <asm-generic/barrier.h> #endif /* _H8300_BARRIER_H */ Index: linux-2.6/arch/hexagon/include/asm/Kbuild =================================================================== --- linux-2.6.orig/arch/hexagon/include/asm/Kbuild 2013-11-07 17:03:11.626900787 +0100 +++ linux-2.6/arch/hexagon/include/asm/Kbuild 2013-11-07 17:03:11.619900657 +0100 @@ -54,3 +54,4 @@ generic-y += unaligned.h generic-y += xor.h generic-y += preempt.h +generic-y += barrier.h Index: linux-2.6/arch/hexagon/include/asm/barrier.h =================================================================== --- linux-2.6.orig/arch/hexagon/include/asm/barrier.h 2013-11-07 17:03:11.626900787 +0100 +++ /dev/null 1970-01-01 00:00:00.000000000 +0000 @@ -1,41 +0,0 @@ -/* - * Memory barrier definitions for the Hexagon architecture - * - * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#ifndef _ASM_BARRIER_H -#define _ASM_BARRIER_H - -#define rmb() barrier() -#define read_barrier_depends() barrier() -#define wmb() barrier() -#define mb() barrier() -#define smp_rmb() barrier() -#define smp_read_barrier_depends() barrier() -#define smp_wmb() barrier() -#define smp_mb() barrier() -#define smp_mb__before_atomic_dec() barrier() -#define smp_mb__after_atomic_dec() barrier() -#define smp_mb__before_atomic_inc() barrier() -#define smp_mb__after_atomic_inc() barrier() - -/* Set a value and use a memory barrier. Used by the scheduler somewhere. */ -#define set_mb(var, value) \ - do { var = value; mb(); } while (0) - -#endif /* _ASM_BARRIER_H */ Index: linux-2.6/arch/m32r/include/asm/barrier.h =================================================================== --- linux-2.6.orig/arch/m32r/include/asm/barrier.h 2013-11-07 17:03:11.626900787 +0100 +++ linux-2.6/arch/m32r/include/asm/barrier.h 2013-11-07 17:03:11.620900676 +0100 @@ -11,84 +11,6 @@ #define nop() __asm__ __volatile__ ("nop" : : ) -/* - * Memory barrier. - * - * mb() prevents loads and stores being reordered across this point. - * rmb() prevents loads being reordered across this point. - * wmb() prevents stores being reordered across this point. - */ -#define mb() barrier() -#define rmb() mb() -#define wmb() mb() - -/** - * read_barrier_depends - Flush all pending reads that subsequents reads - * depend on. - * - * No data-dependent reads from memory-like regions are ever reordered - * over this barrier. All reads preceding this primitive are guaranteed - * to access memory (but not necessarily other CPUs' caches) before any - * reads following this primitive that depend on the data return by - * any of the preceding reads. This primitive is much lighter weight than - * rmb() on most CPUs, and is never heavier weight than is - * rmb(). - * - * These ordering constraints are respected by both the local CPU - * and the compiler. - * - * Ordering is not guaranteed by anything other than these primitives, - * not even by data dependencies. See the documentation for - * memory_barrier() for examples and URLs to more information. - * - * For example, the following code would force ordering (the initial - * value of "a" is zero, "b" is one, and "p" is "&a"): - * - * <programlisting> - * CPU 0 CPU 1 - * - * b = 2; - * memory_barrier(); - * p = &b; q = p; - * read_barrier_depends(); - * d = *q; - * </programlisting> - * - * - * because the read of "*q" depends on the read of "p" and these - * two reads are separated by a read_barrier_depends(). However, - * the following code, with the same initial values for "a" and "b": - * - * <programlisting> - * CPU 0 CPU 1 - * - * a = 2; - * memory_barrier(); - * b = 3; y = b; - * read_barrier_depends(); - * x = a; - * </programlisting> - * - * does not enforce ordering, since there is no data dependency between - * the read of "a" and the read of "b". Therefore, on some CPUs, such - * as Alpha, "y" could be set to 3 and "x" to 0. Use rmb() - * in cases like this where there are no data dependencies. - **/ - -#define read_barrier_depends() do { } while (0) - -#ifdef CONFIG_SMP -#define smp_mb() mb() -#define smp_rmb() rmb() -#define smp_wmb() wmb() -#define smp_read_barrier_depends() read_barrier_depends() -#define set_mb(var, value) do { (void) xchg(&var, value); } while (0) -#else -#define smp_mb() barrier() -#define smp_rmb() barrier() -#define smp_wmb() barrier() -#define smp_read_barrier_depends() do { } while (0) -#define set_mb(var, value) do { var = value; barrier(); } while (0) -#endif +#include <asm-generic/barrier.h> #endif /* _ASM_M32R_BARRIER_H */ Index: linux-2.6/arch/m68k/include/asm/barrier.h =================================================================== --- linux-2.6.orig/arch/m68k/include/asm/barrier.h 2013-11-07 17:03:11.626900787 +0100 +++ linux-2.6/arch/m68k/include/asm/barrier.h 2013-11-07 17:03:11.620900676 +0100 @@ -1,20 +1,8 @@ #ifndef _M68K_BARRIER_H #define _M68K_BARRIER_H -/* - * Force strict CPU ordering. - * Not really required on m68k... - */ #define nop() do { asm volatile ("nop"); barrier(); } while (0) -#define mb() barrier() -#define rmb() barrier() -#define wmb() barrier() -#define read_barrier_depends() ((void)0) -#define set_mb(var, value) ({ (var) = (value); wmb(); }) -#define smp_mb() barrier() -#define smp_rmb() barrier() -#define smp_wmb() barrier() -#define smp_read_barrier_depends() ((void)0) +#include <asm-generic/barrier.h> #endif /* _M68K_BARRIER_H */ Index: linux-2.6/arch/microblaze/include/asm/Kbuild =================================================================== --- linux-2.6.orig/arch/microblaze/include/asm/Kbuild 2013-11-07 17:03:11.626900787 +0100 +++ linux-2.6/arch/microblaze/include/asm/Kbuild 2013-11-07 17:03:11.620900676 +0100 @@ -4,3 +4,4 @@ generic-y += trace_clock.h generic-y += syscalls.h generic-y += preempt.h +generic-y += barrier.h Index: linux-2.6/arch/microblaze/include/asm/barrier.h =================================================================== --- linux-2.6.orig/arch/microblaze/include/asm/barrier.h 2013-11-07 17:03:11.626900787 +0100 +++ /dev/null 1970-01-01 00:00:00.000000000 +0000 @@ -1,27 +0,0 @@ -/* - * Copyright (C) 2006 Atmark Techno, Inc. - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - */ - -#ifndef _ASM_MICROBLAZE_BARRIER_H -#define _ASM_MICROBLAZE_BARRIER_H - -#define nop() asm volatile ("nop") - -#define smp_read_barrier_depends() do {} while (0) -#define read_barrier_depends() do {} while (0) - -#define mb() barrier() -#define rmb() mb() -#define wmb() mb() -#define set_mb(var, value) do { var = value; mb(); } while (0) -#define set_wmb(var, value) do { var = value; wmb(); } while (0) - -#define smp_mb() mb() -#define smp_rmb() rmb() -#define smp_wmb() wmb() - -#endif /* _ASM_MICROBLAZE_BARRIER_H */ Index: linux-2.6/arch/mn10300/include/asm/Kbuild =================================================================== --- linux-2.6.orig/arch/mn10300/include/asm/Kbuild 2013-11-07 17:03:11.626900787 +0100 +++ linux-2.6/arch/mn10300/include/asm/Kbuild 2013-11-07 17:03:11.620900676 +0100 @@ -3,3 +3,4 @@ generic-y += exec.h generic-y += trace_clock.h generic-y += preempt.h +generic-y += barrier.h Index: linux-2.6/arch/mn10300/include/asm/barrier.h =================================================================== --- linux-2.6.orig/arch/mn10300/include/asm/barrier.h 2013-11-07 17:03:11.626900787 +0100 +++ /dev/null 1970-01-01 00:00:00.000000000 +0000 @@ -1,37 +0,0 @@ -/* MN10300 memory barrier definitions - * - * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. - * Written by David Howells (dhowells@xxxxxxxxxx) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public Licence - * as published by the Free Software Foundation; either version - * 2 of the Licence, or (at your option) any later version. - */ -#ifndef _ASM_BARRIER_H -#define _ASM_BARRIER_H - -#define nop() asm volatile ("nop") - -#define mb() asm volatile ("": : :"memory") -#define rmb() mb() -#define wmb() asm volatile ("": : :"memory") - -#ifdef CONFIG_SMP -#define smp_mb() mb() -#define smp_rmb() rmb() -#define smp_wmb() wmb() -#define set_mb(var, value) do { xchg(&var, value); } while (0) -#else /* CONFIG_SMP */ -#define smp_mb() barrier() -#define smp_rmb() barrier() -#define smp_wmb() barrier() -#define set_mb(var, value) do { var = value; mb(); } while (0) -#endif /* CONFIG_SMP */ - -#define set_wmb(var, value) do { var = value; wmb(); } while (0) - -#define read_barrier_depends() do {} while (0) -#define smp_read_barrier_depends() do {} while (0) - -#endif /* _ASM_BARRIER_H */ Index: linux-2.6/arch/parisc/include/asm/Kbuild =================================================================== --- linux-2.6.orig/arch/parisc/include/asm/Kbuild 2013-11-07 17:03:11.626900787 +0100 +++ linux-2.6/arch/parisc/include/asm/Kbuild 2013-11-07 17:03:11.622900712 +0100 @@ -5,3 +5,4 @@ poll.h xor.h clkdev.h exec.h generic-y += trace_clock.h generic-y += preempt.h +generic-y += barrier.h Index: linux-2.6/arch/parisc/include/asm/barrier.h =================================================================== --- linux-2.6.orig/arch/parisc/include/asm/barrier.h 2013-11-07 17:03:11.626900787 +0100 +++ /dev/null 1970-01-01 00:00:00.000000000 +0000 @@ -1,35 +0,0 @@ -#ifndef __PARISC_BARRIER_H -#define __PARISC_BARRIER_H - -/* -** This is simply the barrier() macro from linux/kernel.h but when serial.c -** uses tqueue.h uses smp_mb() defined using barrier(), linux/kernel.h -** hasn't yet been included yet so it fails, thus repeating the macro here. -** -** PA-RISC architecture allows for weakly ordered memory accesses although -** none of the processors use it. There is a strong ordered bit that is -** set in the O-bit of the page directory entry. Operating systems that -** can not tolerate out of order accesses should set this bit when mapping -** pages. The O-bit of the PSW should also be set to 1 (I don't believe any -** of the processor implemented the PSW O-bit). The PCX-W ERS states that -** the TLB O-bit is not implemented so the page directory does not need to -** have the O-bit set when mapping pages (section 3.1). This section also -** states that the PSW Y, Z, G, and O bits are not implemented. -** So it looks like nothing needs to be done for parisc-linux (yet). -** (thanks to chada for the above comment -ggg) -** -** The __asm__ op below simple prevents gcc/ld from reordering -** instructions across the mb() "call". -*/ -#define mb() __asm__ __volatile__("":::"memory") /* barrier() */ -#define rmb() mb() -#define wmb() mb() -#define smp_mb() mb() -#define smp_rmb() mb() -#define smp_wmb() mb() -#define smp_read_barrier_depends() do { } while(0) -#define read_barrier_depends() do { } while(0) - -#define set_mb(var, value) do { var = value; mb(); } while (0) - -#endif /* __PARISC_BARRIER_H */ Index: linux-2.6/arch/score/include/asm/Kbuild =================================================================== --- linux-2.6.orig/arch/score/include/asm/Kbuild 2013-11-07 17:03:11.626900787 +0100 +++ linux-2.6/arch/score/include/asm/Kbuild 2013-11-07 17:03:11.622900712 +0100 @@ -5,3 +5,4 @@ generic-y += trace_clock.h generic-y += xor.h generic-y += preempt.h +generic-y += barrier.h Index: linux-2.6/arch/score/include/asm/barrier.h =================================================================== --- linux-2.6.orig/arch/score/include/asm/barrier.h 2013-11-07 17:03:11.626900787 +0100 +++ /dev/null 1970-01-01 00:00:00.000000000 +0000 @@ -1,16 +0,0 @@ -#ifndef _ASM_SCORE_BARRIER_H -#define _ASM_SCORE_BARRIER_H - -#define mb() barrier() -#define rmb() barrier() -#define wmb() barrier() -#define smp_mb() barrier() -#define smp_rmb() barrier() -#define smp_wmb() barrier() - -#define read_barrier_depends() do {} while (0) -#define smp_read_barrier_depends() do {} while (0) - -#define set_mb(var, value) do {var = value; wmb(); } while (0) - -#endif /* _ASM_SCORE_BARRIER_H */ Index: linux-2.6/arch/sh/include/asm/barrier.h =================================================================== --- linux-2.6.orig/arch/sh/include/asm/barrier.h 2013-11-07 17:03:11.626900787 +0100 +++ linux-2.6/arch/sh/include/asm/barrier.h 2013-11-07 17:03:11.622900712 +0100 @@ -26,29 +26,14 @@ #if defined(CONFIG_CPU_SH4A) || defined(CONFIG_CPU_SH5) #define mb() __asm__ __volatile__ ("synco": : :"memory") #define rmb() mb() -#define wmb() __asm__ __volatile__ ("synco": : :"memory") +#define wmb() mb() #define ctrl_barrier() __icbi(PAGE_OFFSET) -#define read_barrier_depends() do { } while(0) #else -#define mb() __asm__ __volatile__ ("": : :"memory") -#define rmb() mb() -#define wmb() __asm__ __volatile__ ("": : :"memory") #define ctrl_barrier() __asm__ __volatile__ ("nop;nop;nop;nop;nop;nop;nop;nop") -#define read_barrier_depends() do { } while(0) -#endif - -#ifdef CONFIG_SMP -#define smp_mb() mb() -#define smp_rmb() rmb() -#define smp_wmb() wmb() -#define smp_read_barrier_depends() read_barrier_depends() -#else -#define smp_mb() barrier() -#define smp_rmb() barrier() -#define smp_wmb() barrier() -#define smp_read_barrier_depends() do { } while(0) #endif #define set_mb(var, value) do { (void)xchg(&var, value); } while (0) +#include <asm-generic/barrier.h> + #endif /* __ASM_SH_BARRIER_H */ Index: linux-2.6/arch/sparc/include/asm/barrier_32.h =================================================================== --- linux-2.6.orig/arch/sparc/include/asm/barrier_32.h 2013-11-07 17:03:11.626900787 +0100 +++ linux-2.6/arch/sparc/include/asm/barrier_32.h 2013-11-07 17:04:15.256080745 +0100 @@ -1,15 +1,7 @@ #ifndef __SPARC_BARRIER_H #define __SPARC_BARRIER_H -/* XXX Change this if we ever use a PSO mode kernel. */ -#define mb() __asm__ __volatile__ ("" : : : "memory") -#define rmb() mb() -#define wmb() mb() -#define read_barrier_depends() do { } while(0) -#define set_mb(__var, __value) do { __var = __value; mb(); } while(0) -#define smp_mb() __asm__ __volatile__("":::"memory") -#define smp_rmb() __asm__ __volatile__("":::"memory") -#define smp_wmb() __asm__ __volatile__("":::"memory") -#define smp_read_barrier_depends() do { } while(0) +#include <asm/processor.h> /* for nop() */ +#include <asm-generic/barrier.h> #endif /* !(__SPARC_BARRIER_H) */ Index: linux-2.6/arch/tile/include/asm/barrier.h =================================================================== --- linux-2.6.orig/arch/tile/include/asm/barrier.h 2013-11-07 17:03:11.626900787 +0100 +++ linux-2.6/arch/tile/include/asm/barrier.h 2013-11-07 17:03:11.623900731 +0100 @@ -22,59 +22,6 @@ #include <arch/spr_def.h> #include <asm/timex.h> -/* - * read_barrier_depends - Flush all pending reads that subsequents reads - * depend on. - * - * No data-dependent reads from memory-like regions are ever reordered - * over this barrier. All reads preceding this primitive are guaranteed - * to access memory (but not necessarily other CPUs' caches) before any - * reads following this primitive that depend on the data return by - * any of the preceding reads. This primitive is much lighter weight than - * rmb() on most CPUs, and is never heavier weight than is - * rmb(). - * - * These ordering constraints are respected by both the local CPU - * and the compiler. - * - * Ordering is not guaranteed by anything other than these primitives, - * not even by data dependencies. See the documentation for - * memory_barrier() for examples and URLs to more information. - * - * For example, the following code would force ordering (the initial - * value of "a" is zero, "b" is one, and "p" is "&a"): - * - * <programlisting> - * CPU 0 CPU 1 - * - * b = 2; - * memory_barrier(); - * p = &b; q = p; - * read_barrier_depends(); - * d = *q; - * </programlisting> - * - * because the read of "*q" depends on the read of "p" and these - * two reads are separated by a read_barrier_depends(). However, - * the following code, with the same initial values for "a" and "b": - * - * <programlisting> - * CPU 0 CPU 1 - * - * a = 2; - * memory_barrier(); - * b = 3; y = b; - * read_barrier_depends(); - * x = a; - * </programlisting> - * - * does not enforce ordering, since there is no data dependency between - * the read of "a" and the read of "b". Therefore, on some CPUs, such - * as Alpha, "y" could be set to 3 and "x" to 0. Use rmb() - * in cases like this where there are no data dependencies. - */ -#define read_barrier_depends() do { } while (0) - #define __sync() __insn_mf() #include <hv/syscall_public.h> @@ -125,20 +72,7 @@ #define mb() fast_mb() #define iob() fast_iob() -#ifdef CONFIG_SMP -#define smp_mb() mb() -#define smp_rmb() rmb() -#define smp_wmb() wmb() -#define smp_read_barrier_depends() read_barrier_depends() -#else -#define smp_mb() barrier() -#define smp_rmb() barrier() -#define smp_wmb() barrier() -#define smp_read_barrier_depends() do { } while (0) -#endif - -#define set_mb(var, value) \ - do { var = value; mb(); } while (0) +#include <asm-generic/barrier.h> #endif /* !__ASSEMBLY__ */ #endif /* _ASM_TILE_BARRIER_H */ Index: linux-2.6/arch/unicore32/include/asm/barrier.h =================================================================== --- linux-2.6.orig/arch/unicore32/include/asm/barrier.h 2013-11-07 17:03:11.626900787 +0100 +++ linux-2.6/arch/unicore32/include/asm/barrier.h 2013-11-07 17:03:11.623900731 +0100 @@ -14,15 +14,6 @@ #define dsb() __asm__ __volatile__ ("" : : : "memory") #define dmb() __asm__ __volatile__ ("" : : : "memory") -#define mb() barrier() -#define rmb() barrier() -#define wmb() barrier() -#define smp_mb() barrier() -#define smp_rmb() barrier() -#define smp_wmb() barrier() -#define read_barrier_depends() do { } while (0) -#define smp_read_barrier_depends() do { } while (0) - -#define set_mb(var, value) do { var = value; smp_mb(); } while (0) +#include <asm-generic/barrier.h> #endif /* __UNICORE_BARRIER_H__ */ Index: linux-2.6/arch/xtensa/include/asm/barrier.h =================================================================== --- linux-2.6.orig/arch/xtensa/include/asm/barrier.h 2013-11-07 17:03:11.626900787 +0100 +++ linux-2.6/arch/xtensa/include/asm/barrier.h 2013-11-07 17:03:11.623900731 +0100 @@ -9,21 +9,14 @@ #ifndef _XTENSA_SYSTEM_H #define _XTENSA_SYSTEM_H -#define smp_read_barrier_depends() do { } while(0) -#define read_barrier_depends() do { } while(0) - #define mb() ({ __asm__ __volatile__("memw" : : : "memory"); }) #define rmb() barrier() #define wmb() mb() #ifdef CONFIG_SMP #error smp_* not defined -#else -#define smp_mb() barrier() -#define smp_rmb() barrier() -#define smp_wmb() barrier() #endif -#define set_mb(var, value) do { var = value; mb(); } while (0) +#include <asm-generic/barrier.h> #endif /* _XTENSA_SYSTEM_H */ Index: linux-2.6/include/asm-generic/barrier.h =================================================================== --- linux-2.6.orig/include/asm-generic/barrier.h 2013-11-07 17:03:11.626900787 +0100 +++ linux-2.6/include/asm-generic/barrier.h 2013-11-07 17:03:11.623900731 +0100 @@ -1,4 +1,5 @@ -/* Generic barrier definitions, based on MN10300 definitions. +/* + * Generic barrier definitions, originally based on MN10300 definitions. * * It should be possible to use these on really simple architectures, * but it serves more as a starting point for new ports. @@ -16,35 +17,50 @@ #ifndef __ASSEMBLY__ -#define nop() asm volatile ("nop") +#include <linux/compiler.h> + +#ifndef nop +#define nop() asm volatile ("nop") +#endif /* - * Force strict CPU ordering. - * And yes, this is required on UP too when we're talking - * to devices. + * Force strict CPU ordering. And yes, this is required on UP too when we're + * talking to devices. * - * This implementation only contains a compiler barrier. + * Fall back to compiler barriers if nothing better is provided. */ -#define mb() asm volatile ("": : :"memory") +#ifndef mb +#define mb() barrier() +#endif + +#ifndef rmb #define rmb() mb() -#define wmb() asm volatile ("": : :"memory") +#endif + +#ifndef wmb +#define wmb() mb() +#endif + +#ifndef read_barrier_depends +#define read_barrier_depends() do { } while (0) +#endif #ifdef CONFIG_SMP #define smp_mb() mb() #define smp_rmb() rmb() #define smp_wmb() wmb() +#define smp_read_barrier_depends() read_barrier_depends() #else #define smp_mb() barrier() #define smp_rmb() barrier() #define smp_wmb() barrier() +#define smp_read_barrier_depends() do { } while (0) #endif -#define set_mb(var, value) do { var = value; mb(); } while (0) -#define set_wmb(var, value) do { var = value; wmb(); } while (0) - -#define read_barrier_depends() do {} while (0) -#define smp_read_barrier_depends() do {} while (0) +#ifndef set_mb +#define set_mb(var, value) do { (var) = (value); mb(); } while (0) +#endif #endif /* !__ASSEMBLY__ */ #endif /* __ASM_GENERIC_BARRIER_H */ -- To unsubscribe from this list: send the line "unsubscribe linux-arch" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html