diff options
author | Jack Morgenstein <jackm@dev.mellanox.co.il> | 2015-03-24 09:18:39 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-03-24 15:22:52 -0400 |
commit | bffb023ad2d44c0cfa8142ad8247391b32000998 (patch) | |
tree | d565e26d41d3039f8af40d2316025d99af247d10 | |
parent | e5eda89d97ec256ba14e7e861387cc0468259c18 (diff) |
net/mlx4_core: Fix GEN_EQE accessing uninitialixed mutex
We occasionally see in procedure mlx4_GEN_EQE that the driver tries
to grab an uninitialized mutex.
This can occur in only one of two ways:
1. We are trying to generate an async event on an uninitialized slave.
2. We are trying to generate an async event on an illegal slave number
( < 0 or > persist->num_vfs) or an inactive slave.
To deal with #1: move the mutex initialization from specific slave init
sequence in procedure mlx_master_do_cmd to mlx4_multi_func_init() (so that
the mutex is always initialized for all slaves).
To deal with #2: check in procedure mlx4_GEN_EQE that the slave number
provided is in the proper range and that the slave is active.
Signed-off-by: Jack Morgenstein <jackm@dev.mellanox.co.il>
Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/cmd.c | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/eq.c | 18 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/resource_tracker.c | 6 |
3 files changed, 14 insertions, 12 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx4/cmd.c b/drivers/net/ethernet/mellanox/mlx4/cmd.c index a681d7c0bb9f..3350721bf515 100644 --- a/drivers/net/ethernet/mellanox/mlx4/cmd.c +++ b/drivers/net/ethernet/mellanox/mlx4/cmd.c | |||
@@ -1993,7 +1993,6 @@ static void mlx4_master_do_cmd(struct mlx4_dev *dev, int slave, u8 cmd, | |||
1993 | goto reset_slave; | 1993 | goto reset_slave; |
1994 | slave_state[slave].vhcr_dma = ((u64) param) << 48; | 1994 | slave_state[slave].vhcr_dma = ((u64) param) << 48; |
1995 | priv->mfunc.master.slave_state[slave].cookie = 0; | 1995 | priv->mfunc.master.slave_state[slave].cookie = 0; |
1996 | mutex_init(&priv->mfunc.master.gen_eqe_mutex[slave]); | ||
1997 | break; | 1996 | break; |
1998 | case MLX4_COMM_CMD_VHCR1: | 1997 | case MLX4_COMM_CMD_VHCR1: |
1999 | if (slave_state[slave].last_cmd != MLX4_COMM_CMD_VHCR0) | 1998 | if (slave_state[slave].last_cmd != MLX4_COMM_CMD_VHCR0) |
@@ -2225,6 +2224,7 @@ int mlx4_multi_func_init(struct mlx4_dev *dev) | |||
2225 | for (i = 0; i < dev->num_slaves; ++i) { | 2224 | for (i = 0; i < dev->num_slaves; ++i) { |
2226 | s_state = &priv->mfunc.master.slave_state[i]; | 2225 | s_state = &priv->mfunc.master.slave_state[i]; |
2227 | s_state->last_cmd = MLX4_COMM_CMD_RESET; | 2226 | s_state->last_cmd = MLX4_COMM_CMD_RESET; |
2227 | mutex_init(&priv->mfunc.master.gen_eqe_mutex[i]); | ||
2228 | for (j = 0; j < MLX4_EVENT_TYPES_NUM; ++j) | 2228 | for (j = 0; j < MLX4_EVENT_TYPES_NUM; ++j) |
2229 | s_state->event_eq[j].eqn = -1; | 2229 | s_state->event_eq[j].eqn = -1; |
2230 | __raw_writel((__force u32) 0, | 2230 | __raw_writel((__force u32) 0, |
diff --git a/drivers/net/ethernet/mellanox/mlx4/eq.c b/drivers/net/ethernet/mellanox/mlx4/eq.c index 264bc15c1ff2..6e70ffee8e87 100644 --- a/drivers/net/ethernet/mellanox/mlx4/eq.c +++ b/drivers/net/ethernet/mellanox/mlx4/eq.c | |||
@@ -153,12 +153,10 @@ void mlx4_gen_slave_eqe(struct work_struct *work) | |||
153 | 153 | ||
154 | /* All active slaves need to receive the event */ | 154 | /* All active slaves need to receive the event */ |
155 | if (slave == ALL_SLAVES) { | 155 | if (slave == ALL_SLAVES) { |
156 | for (i = 0; i < dev->num_slaves; i++) { | 156 | for (i = 0; i <= dev->persist->num_vfs; i++) { |
157 | if (i != dev->caps.function && | 157 | if (mlx4_GEN_EQE(dev, i, eqe)) |
158 | master->slave_state[i].active) | 158 | mlx4_warn(dev, "Failed to generate event for slave %d\n", |
159 | if (mlx4_GEN_EQE(dev, i, eqe)) | 159 | i); |
160 | mlx4_warn(dev, "Failed to generate event for slave %d\n", | ||
161 | i); | ||
162 | } | 160 | } |
163 | } else { | 161 | } else { |
164 | if (mlx4_GEN_EQE(dev, slave, eqe)) | 162 | if (mlx4_GEN_EQE(dev, slave, eqe)) |
@@ -203,13 +201,11 @@ static void mlx4_slave_event(struct mlx4_dev *dev, int slave, | |||
203 | struct mlx4_eqe *eqe) | 201 | struct mlx4_eqe *eqe) |
204 | { | 202 | { |
205 | struct mlx4_priv *priv = mlx4_priv(dev); | 203 | struct mlx4_priv *priv = mlx4_priv(dev); |
206 | struct mlx4_slave_state *s_slave = | ||
207 | &priv->mfunc.master.slave_state[slave]; | ||
208 | 204 | ||
209 | if (!s_slave->active) { | 205 | if (slave < 0 || slave > dev->persist->num_vfs || |
210 | /*mlx4_warn(dev, "Trying to pass event to inactive slave\n");*/ | 206 | slave == dev->caps.function || |
207 | !priv->mfunc.master.slave_state[slave].active) | ||
211 | return; | 208 | return; |
212 | } | ||
213 | 209 | ||
214 | slave_event(dev, slave, eqe); | 210 | slave_event(dev, slave, eqe); |
215 | } | 211 | } |
diff --git a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c index d97ca88c55b5..6e413ac4e940 100644 --- a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c +++ b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c | |||
@@ -3095,6 +3095,12 @@ int mlx4_GEN_EQE(struct mlx4_dev *dev, int slave, struct mlx4_eqe *eqe) | |||
3095 | if (!priv->mfunc.master.slave_state) | 3095 | if (!priv->mfunc.master.slave_state) |
3096 | return -EINVAL; | 3096 | return -EINVAL; |
3097 | 3097 | ||
3098 | /* check for slave valid, slave not PF, and slave active */ | ||
3099 | if (slave < 0 || slave > dev->persist->num_vfs || | ||
3100 | slave == dev->caps.function || | ||
3101 | !priv->mfunc.master.slave_state[slave].active) | ||
3102 | return 0; | ||
3103 | |||
3098 | event_eq = &priv->mfunc.master.slave_state[slave].event_eq[eqe->type]; | 3104 | event_eq = &priv->mfunc.master.slave_state[slave].event_eq[eqe->type]; |
3099 | 3105 | ||
3100 | /* Create the event only if the slave is registered */ | 3106 | /* Create the event only if the slave is registered */ |