diff options
author | Stephan Günther <moepi@moepi.net> | 2018-12-16 13:08:21 +0100 |
---|---|---|
committer | Martin K. Petersen <martin.petersen@oracle.com> | 2018-12-19 21:31:41 -0500 |
commit | 23c3828aa2f84edec7020c7397a22931e7a879e1 (patch) | |
tree | 9717ed7876dce8933c4955ecc8114f3b5e557303 /drivers/scsi/mpt3sas/mpt3sas_base.c | |
parent | 17b18eaa6f59044a5172db7d07149e31ede0f920 (diff) | |
download | lwn-23c3828aa2f84edec7020c7397a22931e7a879e1.tar.gz lwn-23c3828aa2f84edec7020c7397a22931e7a879e1.zip |
scsi: mpt3sas: fix memory ordering on 64bit writes
With commit 09c2f95ad404 ("scsi: mpt3sas: Swap I/O memory read value back
to cpu endianness"), 64bit writes in _base_writeq() were rewritten to use
__raw_writeq() instad of writeq().
This introduced a bug apparent on powerpc64 systems such as the Raptor
Talos II that causes the HBA to drop from the PCIe bus under heavy load and
being reinitialized after a couple of seconds.
It can easily be triggered on affacted systems by using something like
fio --name=random-write --iodepth=4 --rw=randwrite --bs=4k --direct=0 \
--size=128M --numjobs=64 --end_fsync=1
fio --name=random-write --iodepth=4 --rw=randwrite --bs=64k --direct=0 \
--size=128M --numjobs=64 --end_fsync=1
a couple of times. In my case I tested it on both a ZFS raidz2 and a btrfs
raid6 using LSI 9300-8i and 9400-8i controllers.
The fix consists in resembling the write ordering of writeq() by adding a
mandatory write memory barrier before device access and a compiler barrier
afterwards. The additional MMIO barrier is superfluous.
Signed-off-by: Stephan Günther <moepi@moepi.net>
Reported-by: Matt Corallo <linux@bluematt.me>
Acked-by: Sreekanth Reddy <Sreekanth.Reddy@broadcom.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/scsi/mpt3sas/mpt3sas_base.c')
-rw-r--r-- | drivers/scsi/mpt3sas/mpt3sas_base.c | 3 |
1 files changed, 2 insertions, 1 deletions
diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c index 8a0851ed0c39..0a6cb8f0680c 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_base.c +++ b/drivers/scsi/mpt3sas/mpt3sas_base.c @@ -3345,8 +3345,9 @@ _base_mpi_ep_writeq(__u64 b, volatile void __iomem *addr, static inline void _base_writeq(__u64 b, volatile void __iomem *addr, spinlock_t *writeq_lock) { + wmb(); __raw_writeq(b, addr); - mmiowb(); + barrier(); } #else static inline void |