提交 97989356 编写于 作者: A Amir Vadai 提交者: David S. Miller

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: NAmir Vadai <amirv@mellanox.com>
Signed-off-by: NOr Gerlitz <ogerlitz@mellanox.com>
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
上级 57352ef4
...@@ -150,6 +150,8 @@ struct mlx4_port_config { ...@@ -150,6 +150,8 @@ struct mlx4_port_config {
struct pci_dev *pdev; struct pci_dev *pdev;
}; };
static atomic_t pf_loading = ATOMIC_INIT(0);
int mlx4_check_port_params(struct mlx4_dev *dev, int mlx4_check_port_params(struct mlx4_dev *dev,
enum mlx4_port_type *port_type) enum mlx4_port_type *port_type)
{ {
...@@ -1407,6 +1409,11 @@ static int mlx4_init_slave(struct mlx4_dev *dev) ...@@ -1407,6 +1409,11 @@ static int mlx4_init_slave(struct mlx4_dev *dev)
u32 slave_read; u32 slave_read;
u32 cmd_channel_ver; 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); mutex_lock(&priv->cmd.slave_cmd_mutex);
priv->cmd.max_cmds = 1; priv->cmd.max_cmds = 1;
mlx4_warn(dev, "Sending reset\n"); mlx4_warn(dev, "Sending reset\n");
...@@ -2319,7 +2326,11 @@ static int __mlx4_init_one(struct pci_dev *pdev, int pci_dev_data) ...@@ -2319,7 +2326,11 @@ static int __mlx4_init_one(struct pci_dev *pdev, int pci_dev_data)
if (num_vfs) { if (num_vfs) {
mlx4_warn(dev, "Enabling SR-IOV with %d VFs\n", 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); err = pci_enable_sriov(pdev, num_vfs);
atomic_dec(&pf_loading);
if (err) { if (err) {
mlx4_err(dev, "Failed to enable SR-IOV, continuing without SR-IOV (err = %d).\n", mlx4_err(dev, "Failed to enable SR-IOV, continuing without SR-IOV (err = %d).\n",
err); err);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册