aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJack Morgenstein <jackm@dev.mellanox.co.il>2019-03-12 11:05:48 -0400
committerDavid S. Miller <davem@davemloft.net>2019-03-12 18:00:15 -0400
commitc07d27927f2f2e96fcd27bb9fb330c9ea65612d0 (patch)
tree2756f420fcafcfc2258e03f12ffba7fd5153cc01
parente15ce4b8d11227007577e6dc1364d288b8874fbe (diff)
net/mlx4_core: Fix locking in SRIOV mode when switching between events and polling
In procedures mlx4_cmd_use_events() and mlx4_cmd_use_polling(), we need to guarantee that there are no FW commands in progress on the comm channel (for VFs) or wrapped FW commands (on the PF) when SRIOV is active. We do this by also taking the slave_cmd_mutex when SRIOV is active. This is especially important when switching from event to polling, since we free the command-context array during the switch. If there are FW commands in progress (e.g., waiting for a completion event), the completion event handler will access freed memory. Since the decision to use comm_wait or comm_poll is taken before grabbing the event_sem/poll_sem in mlx4_comm_cmd_wait/poll, we must take the slave_cmd_mutex as well (to guarantee that the decision to use events or polling and the call to the appropriate cmd function are atomic). Fixes: a7e1f04905e5 ("net/mlx4_core: Fix deadlock when switching between polling and event fw commands") Signed-off-by: Jack Morgenstein <jackm@dev.mellanox.co.il> Signed-off-by: Tariq Toukan <tariqt@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/cmd.c8
1 files changed, 8 insertions, 0 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx4/cmd.c b/drivers/net/ethernet/mellanox/mlx4/cmd.c
index 44081acd48fb..a5d5d6fc1da0 100644
--- a/drivers/net/ethernet/mellanox/mlx4/cmd.c
+++ b/drivers/net/ethernet/mellanox/mlx4/cmd.c
@@ -2645,6 +2645,8 @@ int mlx4_cmd_use_events(struct mlx4_dev *dev)
2645 if (!priv->cmd.context) 2645 if (!priv->cmd.context)
2646 return -ENOMEM; 2646 return -ENOMEM;
2647 2647
2648 if (mlx4_is_mfunc(dev))
2649 mutex_lock(&priv->cmd.slave_cmd_mutex);
2648 down_write(&priv->cmd.switch_sem); 2650 down_write(&priv->cmd.switch_sem);
2649 for (i = 0; i < priv->cmd.max_cmds; ++i) { 2651 for (i = 0; i < priv->cmd.max_cmds; ++i) {
2650 priv->cmd.context[i].token = i; 2652 priv->cmd.context[i].token = i;
@@ -2670,6 +2672,8 @@ int mlx4_cmd_use_events(struct mlx4_dev *dev)
2670 down(&priv->cmd.poll_sem); 2672 down(&priv->cmd.poll_sem);
2671 priv->cmd.use_events = 1; 2673 priv->cmd.use_events = 1;
2672 up_write(&priv->cmd.switch_sem); 2674 up_write(&priv->cmd.switch_sem);
2675 if (mlx4_is_mfunc(dev))
2676 mutex_unlock(&priv->cmd.slave_cmd_mutex);
2673 2677
2674 return err; 2678 return err;
2675} 2679}
@@ -2682,6 +2686,8 @@ void mlx4_cmd_use_polling(struct mlx4_dev *dev)
2682 struct mlx4_priv *priv = mlx4_priv(dev); 2686 struct mlx4_priv *priv = mlx4_priv(dev);
2683 int i; 2687 int i;
2684 2688
2689 if (mlx4_is_mfunc(dev))
2690 mutex_lock(&priv->cmd.slave_cmd_mutex);
2685 down_write(&priv->cmd.switch_sem); 2691 down_write(&priv->cmd.switch_sem);
2686 priv->cmd.use_events = 0; 2692 priv->cmd.use_events = 0;
2687 2693
@@ -2693,6 +2699,8 @@ void mlx4_cmd_use_polling(struct mlx4_dev *dev)
2693 2699
2694 up(&priv->cmd.poll_sem); 2700 up(&priv->cmd.poll_sem);
2695 up_write(&priv->cmd.switch_sem); 2701 up_write(&priv->cmd.switch_sem);
2702 if (mlx4_is_mfunc(dev))
2703 mutex_unlock(&priv->cmd.slave_cmd_mutex);
2696} 2704}
2697 2705
2698struct mlx4_cmd_mailbox *mlx4_alloc_cmd_mailbox(struct mlx4_dev *dev) 2706struct mlx4_cmd_mailbox *mlx4_alloc_cmd_mailbox(struct mlx4_dev *dev)