Skip to content

Commit

Permalink
net/mlx4_core: mlx4_init_slave() shouldn't access comm channel before…
Browse files Browse the repository at this point in the history
… 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>
  • Loading branch information
Amir Vadai authored and David S. Miller committed Mar 6, 2014
1 parent 57352ef commit 9798935
Showing 1 changed file with 11 additions and 0 deletions.
11 changes: 11 additions & 0 deletions drivers/net/ethernet/mellanox/mlx4/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,8 @@ struct mlx4_port_config {
struct pci_dev *pdev;
};

static atomic_t pf_loading = ATOMIC_INIT(0);

int mlx4_check_port_params(struct mlx4_dev *dev,
enum mlx4_port_type *port_type)
{
Expand Down Expand Up @@ -1407,6 +1409,11 @@ static int mlx4_init_slave(struct mlx4_dev *dev)
u32 slave_read;
u32 cmd_channel_ver;

if (atomic_read(&pf_loading)) {
mlx4_warn(dev, "PF is not ready. Deferring probe\n");
return -EPROBE_DEFER;
}

mutex_lock(&priv->cmd.slave_cmd_mutex);
priv->cmd.max_cmds = 1;
mlx4_warn(dev, "Sending reset\n");
Expand Down Expand Up @@ -2319,7 +2326,11 @@ static int __mlx4_init_one(struct pci_dev *pdev, int pci_dev_data)

if (num_vfs) {
mlx4_warn(dev, "Enabling SR-IOV with %d VFs\n", num_vfs);

atomic_inc(&pf_loading);
err = pci_enable_sriov(pdev, num_vfs);
atomic_dec(&pf_loading);

if (err) {
mlx4_err(dev, "Failed to enable SR-IOV, continuing without SR-IOV (err = %d).\n",
err);
Expand Down

0 comments on commit 9798935

Please sign in to comment.