On 2019-05-23 12:43 a.m., Grant Grundler wrote: >> On a UP kernel, mb() is currently just a compiler >> memory barrier. On a SMP kernel, mb() generates a "sync" instruction. We also >> use "ldcw" as a barrier in spinlocks. > Yeah, I'm not sure how strong the mb() needs to be and maybe I'm > giving the wrong advice: use dma_wmb() for the case I've described > above. Then use dma_rmb() before reading data structures updated by > the device. See examples in the existing code: > https://elixir.bootlin.com/linux/v4.20/ident/dma_wmb > Looking at arm and arm64, I think sync should be used for mb(), rmb() and wmb(). Possibly, ldcw can be used for dma_rmb() and dma_wmb() although sync should be okay. Sync is heavier than ldcw. The __smp barriers could use ldcw. Arm64 doesn't distinguish between UP and SMP. 32-bit arm has this config option, CONFIG_ARM_DMA_MEM_BUFFERABLE, that enables stronger barriers when defined. I think we should use the same barriers on UP and SMP on parisc to ensure we properly synchronize I/O operations. Dave -- John David Anglin dave.anglin@xxxxxxxx