On Fri, 1 Feb 2002, Maciej W. Rozycki wrote: > Well, after looking at the Alpha Architecture Handbook I see "mb" and > "wmb" are pure ordering barriers -- any transactions at the CPU bus (pins) > may still be deferred or prefetched (architecturally -- can't comment on > specific chips). So after all, maybe all the macros should be purely > "sync" for MIPS ("" for MIPS I, and mb() equal to wbflush() for R3220 and > similar setups) and anything that wants to see all writes actually > committed should use wbflush(), which would be defined as "mb(); > uncached_read();" (or in a system-specific way, for R3220, etc.)? > > The i386 implementation seems stronger than it should be, but that's > probably because of the limited choice available. > > Any thoughts? Well, I've seen no thoughts so far. :-( Anyway here is a new patch, which takes my considerations about a synchronization vs a write commitment into account. This implementation only assures the absolute minimum specified in the operations. I am also tempted to add "#define iob() wbflush()" to system.h and attempt to define the macro for other architectures as well. The intended semantics is to assure all preceding transactions arrived at a system bus and none of following ones were started yet. The "system bus" here is defined: "the bus that connects the bus controller of a CPU (whether internal to the chip or not) to the rest of a system." -- + Maciej W. Rozycki, Technical University of Gdansk, Poland + +--------------------------------------------------------------+ + e-mail: macro@ds2.pg.gda.pl, PGP key available + patch-mips-2.4.17-20020111-mb-wb-1 diff -up --recursive --new-file linux-mips-2.4.17-20020111.macro/arch/mips/config.in linux-mips-2.4.17-20020111/arch/mips/config.in --- linux-mips-2.4.17-20020111.macro/arch/mips/config.in Mon Jan 7 05:27:13 2002 +++ linux-mips-2.4.17-20020111/arch/mips/config.in Sat Jan 26 02:35:35 2002 @@ -363,6 +363,12 @@ else fi fi fi +if [ "$CONFIG_CPU_R3000" = "y" -o \ + "$CONFIG_CPU_TX39XX" = "y" ]; then + define_bool CONFIG_CPU_HAS_SYNC n +else + define_bool CONFIG_CPU_HAS_SYNC y +fi endmenu mainmenu_option next_comment diff -up --recursive --new-file linux-mips-2.4.17-20020111.macro/include/asm-mips/system.h linux-mips-2.4.17-20020111/include/asm-mips/system.h --- linux-mips-2.4.17-20020111.macro/include/asm-mips/system.h Thu Dec 13 05:28:09 2001 +++ linux-mips-2.4.17-20020111/include/asm-mips/system.h Sat Feb 2 00:05:19 2002 @@ -167,32 +167,31 @@ extern void __global_restore_flags(unsig #define local_irq_disable() __cli(); #define local_irq_enable() __sti(); -/* - * These are probably defined overly paranoid ... - */ +#ifdef CONFIG_CPU_HAS_SYNC +#define __sync() __asm__ __volatile__("sync" : : : "memory") +#else +#define __sync() do { } while(0) +#endif + +#define fast_wmb() __sync() +#define fast_rmb() __sync() +#define fast_mb() __sync() + #ifdef CONFIG_CPU_HAS_WB #include <asm/wbflush.h> -#define rmb() do { } while(0) -#define wmb() wbflush() -#define mb() wbflush() - -#else /* CONFIG_CPU_HAS_WB */ - -#define mb() \ -__asm__ __volatile__( \ - "# prevent instructions being moved around\n\t" \ - ".set\tnoreorder\n\t" \ - "# 8 nops to fool the R4400 pipeline\n\t" \ - "nop;nop;nop;nop;nop;nop;nop;nop\n\t" \ - ".set\treorder" \ - : /* no output */ \ - : /* no input */ \ - : "memory") -#define rmb() mb() -#define wmb() mb() -#endif /* CONFIG_CPU_HAS_WB */ +#define wmb() fast_wmb() +#define rmb() fast_rmb() +#define mb() wbflush(); + +#else /* !CONFIG_CPU_HAS_WB */ + +#define wmb() fast_wmb() +#define rmb() fast_rmb() +#define mb() fast_mb() + +#endif /* !CONFIG_CPU_HAS_WB */ #ifdef CONFIG_SMP #define smp_mb() mb() diff -up --recursive --new-file linux-mips-2.4.17-20020111.macro/include/asm-mips/wbflush.h linux-mips-2.4.17-20020111/include/asm-mips/wbflush.h --- linux-mips-2.4.17-20020111.macro/include/asm-mips/wbflush.h Fri Sep 7 04:26:33 2001 +++ linux-mips-2.4.17-20020111/include/asm-mips/wbflush.h Sat Feb 2 00:05:21 2002 @@ -6,28 +6,49 @@ * for more details. * * Copyright (c) 1998 Harald Koerfgen + * Copyright (C) 2002 Maciej W. Rozycki */ #ifndef __ASM_MIPS_WBFLUSH_H #define __ASM_MIPS_WBFLUSH_H #include <linux/config.h> -#if defined(CONFIG_CPU_HAS_WB) -/* - * R2000 or R3000 - */ -extern void (*__wbflush) (void); +#include <asm/addrspace.h> +#include <asm/system.h> -#define wbflush() __wbflush() +#define __fast_wbflush() \ + __asm__ __volatile__( \ + ".set push\n\t" \ + ".set noreorder\n\t" \ + "lw $0,%0\n\t" \ + "nop\n\t" \ + ".set pop" \ + : /* no output */ \ + : "m" (*(int *)KSEG1) \ + : "memory") + +#define fast_wbflush() \ + do { \ + fast_mb(); \ + __fast_wbflush(); \ + } while (0) + + +#ifdef CONFIG_CPU_HAS_WB + +extern void (*__wbflush)(void); + +#define wbflush() \ + do { \ + fast_mb(); \ + __wbflush(); \ + } while (0) -#else -/* - * we don't need no stinkin' wbflush - */ +#else /* !CONFIG_CPU_HAS_WB */ -#define wbflush() do { } while(0) +#define wbflush() fast_wbflush() -#endif +#endif /* !CONFIG_CPU_HAS_WB */ extern void wbflush_setup(void);