Skip to content

Commit

Permalink
IB/mlx5: Use __iowrite64_copy() for write combining stores
Browse files Browse the repository at this point in the history
BugLink: https://bugs.launchpad.net/bugs/2071655

mlx5 has a built in self-test at driver startup to evaluate if the
platform supports write combining to generate a 64 byte PCIe TLP or
not. This has proven necessary because a lot of common scenarios end up
with broken write combining (especially inside virtual machines) and there
is other way to learn this information.

This self test has been consistently failing on new ARM64 CPU
designs (specifically with NVIDIA Grace's implementation of Neoverse
V2). The C loop around writeq() generates some pretty terrible ARM64
assembly, but historically this has worked on a lot of existing ARM64 CPUs
till now.

We see it succeed about 1 time in 10,000 on the worst effected
systems. The CPU architects speculate that the load instructions
interspersed with the stores makes the WC buffers statistically flush too
often and thus the generation of large TLPs becomes infrequent. This makes
the boot up test unreliable in that it indicates no write-combining,
however userspace would be fine since it uses a ST4 instruction.

Further, S390 has similar issues where only the special zpci_memcpy_toio()
will actually generate large TLPs, and the open coded loop does not
trigger it at all.

Fix both ARM64 and S390 by switching to __iowrite64_copy() which now
provides architecture specific variants that have a high change of
generating a large TLP with write combining. x86 continues to use a
similar writeq loop in the generate __iowrite64_copy().

Fixes: 11f552e ("IB/mlx5: Test write combining support")
Link: https://lore.kernel.org/r/[email protected]
Tested-by: Niklas Schnelle <[email protected]>
Acked-by: Leon Romanovsky <[email protected]>
Signed-off-by: Jason Gunthorpe <[email protected]>
(cherry picked from commit ef30228)
Signed-off-by: Jamie Nguyen <[email protected]>
Acked-by: Brad Figg <[email protected]>
Acked-by: Noah Wager <[email protected]>
Acked-by: Jacob Martin <[email protected]>
Signed-off-by: Brad Figg <[email protected]>
  • Loading branch information
jgunthorpe authored and jacobmartin0 committed Jul 15, 2024
1 parent 8409e65 commit 085a4b3
Showing 1 changed file with 3 additions and 5 deletions.
8 changes: 3 additions & 5 deletions drivers/infiniband/hw/mlx5/mem.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
* SOFTWARE.
*/

#include <linux/io.h>
#include <rdma/ib_umem_odp.h>
#include "mlx5_ib.h"
#include <linux/jiffies.h>
Expand Down Expand Up @@ -108,7 +109,6 @@ static int post_send_nop(struct mlx5_ib_dev *dev, struct ib_qp *ibqp, u64 wr_id,
__be32 mmio_wqe[16] = {};
unsigned long flags;
unsigned int idx;
int i;

if (unlikely(dev->mdev->state == MLX5_DEVICE_STATE_INTERNAL_ERROR))
return -EIO;
Expand Down Expand Up @@ -148,10 +148,8 @@ static int post_send_nop(struct mlx5_ib_dev *dev, struct ib_qp *ibqp, u64 wr_id,
* we hit doorbell
*/
wmb();
for (i = 0; i < 8; i++)
mlx5_write64(&mmio_wqe[i * 2],
bf->bfreg->map + bf->offset + i * 8);
io_stop_wc();
__iowrite64_copy(bf->bfreg->map + bf->offset, mmio_wqe,
sizeof(mmio_wqe) / 8);

bf->offset ^= bf->buf_size;

Expand Down

0 comments on commit 085a4b3

Please sign in to comment.