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

Configure Feed

Select the types of activity you want to include in your feed.

parisc: Define mb() and add memory barriers to assembler unlock sequences

For years I thought all parisc machines executed loads and stores in
order. However, Jeff Law recently indicated on gcc-patches that this is
not correct. There are various degrees of out-of-order execution all the
way back to the PA7xxx processor series (hit-under-miss). The PA8xxx
series has full out-of-order execution for both integer operations, and
loads and stores.

This is described in the following article:
http://web.archive.org/web/20040214092531/http://www.cpus.hp.com/technical_references/advperf.shtml

For this reason, we need to define mb() and to insert a memory barrier
before the store unlocking spinlocks. This ensures that all memory
accesses are complete prior to unlocking. The ldcw instruction performs
the same function on entry.

Signed-off-by: John David Anglin <dave.anglin@bell.net>
Cc: stable@vger.kernel.org # 4.0+
Signed-off-by: Helge Deller <deller@gmx.de>

authored by

John David Anglin and committed by
Helge Deller
fedb8da9 66509a27

+39
+32
arch/parisc/include/asm/barrier.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + #ifndef __ASM_BARRIER_H 3 + #define __ASM_BARRIER_H 4 + 5 + #ifndef __ASSEMBLY__ 6 + 7 + /* The synchronize caches instruction executes as a nop on systems in 8 + which all memory references are performed in order. */ 9 + #define synchronize_caches() __asm__ __volatile__ ("sync" : : : "memory") 10 + 11 + #if defined(CONFIG_SMP) 12 + #define mb() do { synchronize_caches(); } while (0) 13 + #define rmb() mb() 14 + #define wmb() mb() 15 + #define dma_rmb() mb() 16 + #define dma_wmb() mb() 17 + #else 18 + #define mb() barrier() 19 + #define rmb() barrier() 20 + #define wmb() barrier() 21 + #define dma_rmb() barrier() 22 + #define dma_wmb() barrier() 23 + #endif 24 + 25 + #define __smp_mb() mb() 26 + #define __smp_rmb() mb() 27 + #define __smp_wmb() mb() 28 + 29 + #include <asm-generic/barrier.h> 30 + 31 + #endif /* !__ASSEMBLY__ */ 32 + #endif /* __ASM_BARRIER_H */
+2
arch/parisc/kernel/entry.S
··· 482 482 .macro tlb_unlock0 spc,tmp 483 483 #ifdef CONFIG_SMP 484 484 or,COND(=) %r0,\spc,%r0 485 + sync 486 + or,COND(=) %r0,\spc,%r0 485 487 stw \spc,0(\tmp) 486 488 #endif 487 489 .endm
+1
arch/parisc/kernel/pacache.S
··· 353 353 .macro tlb_unlock la,flags,tmp 354 354 #ifdef CONFIG_SMP 355 355 ldi 1,\tmp 356 + sync 356 357 stw \tmp,0(\la) 357 358 mtsm \flags 358 359 #endif
+4
arch/parisc/kernel/syscall.S
··· 633 633 sub,<> %r28, %r25, %r0 634 634 2: stw,ma %r24, 0(%r26) 635 635 /* Free lock */ 636 + sync 636 637 stw,ma %r20, 0(%sr2,%r20) 637 638 #if ENABLE_LWS_DEBUG 638 639 /* Clear thread register indicator */ ··· 648 647 3: 649 648 /* Error occurred on load or store */ 650 649 /* Free lock */ 650 + sync 651 651 stw %r20, 0(%sr2,%r20) 652 652 #if ENABLE_LWS_DEBUG 653 653 stw %r0, 4(%sr2,%r20) ··· 850 848 851 849 cas2_end: 852 850 /* Free lock */ 851 + sync 853 852 stw,ma %r20, 0(%sr2,%r20) 854 853 /* Enable interrupts */ 855 854 ssm PSW_SM_I, %r0 ··· 861 858 22: 862 859 /* Error occurred on load or store */ 863 860 /* Free lock */ 861 + sync 864 862 stw %r20, 0(%sr2,%r20) 865 863 ssm PSW_SM_I, %r0 866 864 ldo 1(%r0),%r28