aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAmir Vadai <amirv@mellanox.com>2014-03-06 11:28:17 -0500
committerDavid S. Miller <davem@davemloft.net>2014-03-06 17:09:04 -0500
commit97989356af0ec8b1b1658d804892abb354127330 (patch)
treec73f68a57e4e2a24b8d8d7b071ea9b7658dd3998
parent57352ef4f5f19969a50d42e84b274287993b576f (diff)
net/mlx4_core: mlx4_init_slave() shouldn't access comm channel before PF is ready
Currently, the PF call to pci_enable_sriov from the PF probe function stalls for 10 seconds times the number of VFs probed on the host. This happens because the way for such VFs to determine of the PF initialization finished, is by attempting to issue reset on the comm-channel and get timeout (after 10s). The PF probe function is called from a kenernel workqueue, and therefore during that time, rcu lock is being held and kernel's workqueue is stalled. This blocks other processes that try to use the workqueue or rcu lock. For example, interface renaming which is calling rcu_synchronize is blocked, and timedout by systemd. Changed mlx4_init_slave() to allow VF probed on the host to immediatly detect that the PF is not ready, and return EPROBE_DEFER instantly. Only when the PF finishes the initialization, allow such VFs to access the comm channel. This issue and fix are relevant only for probed VFs on the hypervisor, there is no way to pass this information to a VM until comm channel is ready, so in a VM, if PF is not ready, the first command will be timedout after 10 seconds and return EPROBE_DEFER. Signed-off-by: Amir Vadai <amirv@mellanox.com> 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/main.c11
1 files changed, 11 insertions, 0 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c
index 5a6105f1ba6d..30a08a60f059 100644
--- a/drivers/net/ethernet/mellanox/mlx4/main.c
+++ b/drivers/net/ethernet/mellanox/mlx4/main.c
@@ -150,6 +150,8 @@ struct mlx4_port_config {
150 struct pci_dev *pdev; 150 struct pci_dev *pdev;
151}; 151};
152 152
153static atomic_t pf_loading = ATOMIC_INIT(0);
154
153int mlx4_check_port_params(struct mlx4_dev *dev, 155int mlx4_check_port_params(struct mlx4_dev *dev,
154 enum mlx4_port_type *port_type) 156 enum mlx4_port_type *port_type)
155{ 157{
@@ -1407,6 +1409,11 @@ static int mlx4_init_slave(struct mlx4_dev *dev)
1407 u32 slave_read; 1409 u32 slave_read;
1408 u32 cmd_channel_ver; 1410 u32 cmd_channel_ver;
1409 1411
1412 if (atomic_read(&pf_loading)) {
1413 mlx4_warn(dev, "PF is not ready. Deferring probe\n");
1414 return -EPROBE_DEFER;
1415 }
1416
1410 mutex_lock(&priv->cmd.slave_cmd_mutex); 1417 mutex_lock(&priv->cmd.slave_cmd_mutex);
1411 priv->cmd.max_cmds = 1; 1418 priv->cmd.max_cmds = 1;
1412 mlx4_warn(dev, "Sending reset\n"); 1419 mlx4_warn(dev, "Sending reset\n");
@@ -2319,7 +2326,11 @@ static int __mlx4_init_one(struct pci_dev *pdev, int pci_dev_data)
2319 2326
2320 if (num_vfs) { 2327 if (num_vfs) {
2321 mlx4_warn(dev, "Enabling SR-IOV with %d VFs\n", num_vfs); 2328 mlx4_warn(dev, "Enabling SR-IOV with %d VFs\n", num_vfs);
2329
2330 atomic_inc(&pf_loading);
2322 err = pci_enable_sriov(pdev, num_vfs); 2331 err = pci_enable_sriov(pdev, num_vfs);
2332 atomic_dec(&pf_loading);
2333
2323 if (err) { 2334 if (err) {
2324 mlx4_err(dev, "Failed to enable SR-IOV, continuing without SR-IOV (err = %d).\n", 2335 mlx4_err(dev, "Failed to enable SR-IOV, continuing without SR-IOV (err = %d).\n",
2325 err); 2336 err);