Commit c02b0501 authored by Carol L Soto's avatar Carol L Soto Committed by David S. Miller

net/mlx4: Copy/set only sizeof struct mlx4_eqe bytes

When doing memcpy/memset of EQEs, we should use sizeof struct
mlx4_eqe as the base size and not caps.eqe_size which could be bigger.

If caps.eqe_size is bigger than the struct mlx4_eqe then we corrupt
data in the master context.

When using a 64 byte stride, the memcpy copied over 63 bytes to the
slave_eq structure.  This resulted in copying over the entire eqe of
interest, including its ownership bit -- and also 31 bytes of garbage
into the next WQE in the slave EQ -- which did NOT include the ownership
bit (and therefore had no impact).

However, once the stride is increased to 128, we are overwriting the
ownership bits of *three* eqes in the slave_eq struct.  This results
in an incorrect ownership bit for those eqes, which causes the eq to
seem to be full. The issue therefore surfaced only once 128-byte EQEs
started being used in SRIOV and (overarchitectures that have 128/256
byte cache-lines such as PPC) - e.g after commit 77507aa2
"net/mlx4_core: Enable CQE/EQE stride support".

Fixes: 08ff3235 ('mlx4: 64-byte CQE/EQE support')
Signed-off-by: default avatarCarol L Soto <clsoto@linux.vnet.ibm.com>
Signed-off-by: default avatarJack Morgenstein <jackm@dev.mellanox.co.il>
Signed-off-by: default avatarOr Gerlitz <ogerlitz@mellanox.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 092bf0fc
...@@ -2398,7 +2398,7 @@ int mlx4_multi_func_init(struct mlx4_dev *dev) ...@@ -2398,7 +2398,7 @@ int mlx4_multi_func_init(struct mlx4_dev *dev)
} }
} }
memset(&priv->mfunc.master.cmd_eqe, 0, dev->caps.eqe_size); memset(&priv->mfunc.master.cmd_eqe, 0, sizeof(struct mlx4_eqe));
priv->mfunc.master.cmd_eqe.type = MLX4_EVENT_TYPE_CMD; priv->mfunc.master.cmd_eqe.type = MLX4_EVENT_TYPE_CMD;
INIT_WORK(&priv->mfunc.master.comm_work, INIT_WORK(&priv->mfunc.master.comm_work,
mlx4_master_comm_channel); mlx4_master_comm_channel);
......
...@@ -196,7 +196,7 @@ static void slave_event(struct mlx4_dev *dev, u8 slave, struct mlx4_eqe *eqe) ...@@ -196,7 +196,7 @@ static void slave_event(struct mlx4_dev *dev, u8 slave, struct mlx4_eqe *eqe)
return; return;
} }
memcpy(s_eqe, eqe, dev->caps.eqe_size - 1); memcpy(s_eqe, eqe, sizeof(struct mlx4_eqe) - 1);
s_eqe->slave_id = slave; s_eqe->slave_id = slave;
/* ensure all information is written before setting the ownersip bit */ /* ensure all information is written before setting the ownersip bit */
dma_wmb(); dma_wmb();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment