]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/4.20.17/net-mlx4_core-fix-locking-in-sriov-mode-when-switching-between-events-and-polling.patch
Linux 5.0.3
[thirdparty/kernel/stable-queue.git] / releases / 4.20.17 / net-mlx4_core-fix-locking-in-sriov-mode-when-switching-between-events-and-polling.patch
1 From foo@baz Thu Mar 14 23:20:15 PDT 2019
2 From: Jack Morgenstein <jackm@dev.mellanox.co.il>
3 Date: Tue, 12 Mar 2019 17:05:48 +0200
4 Subject: net/mlx4_core: Fix locking in SRIOV mode when switching between events and polling
5
6 From: Jack Morgenstein <jackm@dev.mellanox.co.il>
7
8 [ Upstream commit c07d27927f2f2e96fcd27bb9fb330c9ea65612d0 ]
9
10 In procedures mlx4_cmd_use_events() and mlx4_cmd_use_polling(), we need to
11 guarantee that there are no FW commands in progress on the comm channel
12 (for VFs) or wrapped FW commands (on the PF) when SRIOV is active.
13
14 We do this by also taking the slave_cmd_mutex when SRIOV is active.
15
16 This is especially important when switching from event to polling, since we
17 free the command-context array during the switch. If there are FW commands
18 in progress (e.g., waiting for a completion event), the completion event
19 handler will access freed memory.
20
21 Since the decision to use comm_wait or comm_poll is taken before grabbing
22 the event_sem/poll_sem in mlx4_comm_cmd_wait/poll, we must take the
23 slave_cmd_mutex as well (to guarantee that the decision to use events or
24 polling and the call to the appropriate cmd function are atomic).
25
26 Fixes: a7e1f04905e5 ("net/mlx4_core: Fix deadlock when switching between polling and event fw commands")
27 Signed-off-by: Jack Morgenstein <jackm@dev.mellanox.co.il>
28 Signed-off-by: Tariq Toukan <tariqt@mellanox.com>
29 Signed-off-by: David S. Miller <davem@davemloft.net>
30 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
31 ---
32 drivers/net/ethernet/mellanox/mlx4/cmd.c | 8 ++++++++
33 1 file changed, 8 insertions(+)
34
35 --- a/drivers/net/ethernet/mellanox/mlx4/cmd.c
36 +++ b/drivers/net/ethernet/mellanox/mlx4/cmd.c
37 @@ -2645,6 +2645,8 @@ int mlx4_cmd_use_events(struct mlx4_dev
38 if (!priv->cmd.context)
39 return -ENOMEM;
40
41 + if (mlx4_is_mfunc(dev))
42 + mutex_lock(&priv->cmd.slave_cmd_mutex);
43 down_write(&priv->cmd.switch_sem);
44 for (i = 0; i < priv->cmd.max_cmds; ++i) {
45 priv->cmd.context[i].token = i;
46 @@ -2670,6 +2672,8 @@ int mlx4_cmd_use_events(struct mlx4_dev
47 down(&priv->cmd.poll_sem);
48 priv->cmd.use_events = 1;
49 up_write(&priv->cmd.switch_sem);
50 + if (mlx4_is_mfunc(dev))
51 + mutex_unlock(&priv->cmd.slave_cmd_mutex);
52
53 return err;
54 }
55 @@ -2682,6 +2686,8 @@ void mlx4_cmd_use_polling(struct mlx4_de
56 struct mlx4_priv *priv = mlx4_priv(dev);
57 int i;
58
59 + if (mlx4_is_mfunc(dev))
60 + mutex_lock(&priv->cmd.slave_cmd_mutex);
61 down_write(&priv->cmd.switch_sem);
62 priv->cmd.use_events = 0;
63
64 @@ -2693,6 +2699,8 @@ void mlx4_cmd_use_polling(struct mlx4_de
65
66 up(&priv->cmd.poll_sem);
67 up_write(&priv->cmd.switch_sem);
68 + if (mlx4_is_mfunc(dev))
69 + mutex_unlock(&priv->cmd.slave_cmd_mutex);
70 }
71
72 struct mlx4_cmd_mailbox *mlx4_alloc_cmd_mailbox(struct mlx4_dev *dev)