Commit c9ca6165 authored by Carol L Soto's avatar Carol L Soto Committed by Luis Henriques

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

commit c02b0501 upstream.

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>
[ luis: backported to 3.16: adjusted context ]
Signed-off-by: default avatarLuis Henriques <luis.henriques@canonical.com>
parent 45f29add
...@@ -2029,7 +2029,7 @@ int mlx4_multi_func_init(struct mlx4_dev *dev) ...@@ -2029,7 +2029,7 @@ int mlx4_multi_func_init(struct mlx4_dev *dev)
spin_lock_init(&s_state->lock); spin_lock_init(&s_state->lock);
} }
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);
......
...@@ -182,7 +182,7 @@ static void slave_event(struct mlx4_dev *dev, u8 slave, struct mlx4_eqe *eqe) ...@@ -182,7 +182,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 */
wmb(); 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