提交 4bfd2e6e 编写于 作者: D Daniel Jurgens 提交者: David S. Miller

net/mlx4_core: Avoid repeated calls to pci enable/disable

Maintain the PCI status and provide wrappers for enabling and disabling
the PCI device.  Performing the actions more than once without doing
its opposite results in warning logs.

This occurred when EEH hotplugged the device causing a warning for
disabling an already disabled device.

Fixes: 2ba5fbd6 ('net/mlx4_core: Handle AER flow properly')
Signed-off-by: NDaniel Jurgens <danielj@mellanox.com>
Signed-off-by: NYishai Hadas <yishaih@mellanox.com>
Signed-off-by: NOr Gerlitz <ogerlitz@mellanox.com>
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
上级 c12833ac
...@@ -3172,6 +3172,34 @@ static int mlx4_check_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap ...@@ -3172,6 +3172,34 @@ static int mlx4_check_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap
return 0; return 0;
} }
static int mlx4_pci_enable_device(struct mlx4_dev *dev)
{
struct pci_dev *pdev = dev->persist->pdev;
int err = 0;
mutex_lock(&dev->persist->pci_status_mutex);
if (dev->persist->pci_status == MLX4_PCI_STATUS_DISABLED) {
err = pci_enable_device(pdev);
if (!err)
dev->persist->pci_status = MLX4_PCI_STATUS_ENABLED;
}
mutex_unlock(&dev->persist->pci_status_mutex);
return err;
}
static void mlx4_pci_disable_device(struct mlx4_dev *dev)
{
struct pci_dev *pdev = dev->persist->pdev;
mutex_lock(&dev->persist->pci_status_mutex);
if (dev->persist->pci_status == MLX4_PCI_STATUS_ENABLED) {
pci_disable_device(pdev);
dev->persist->pci_status = MLX4_PCI_STATUS_DISABLED;
}
mutex_unlock(&dev->persist->pci_status_mutex);
}
static int mlx4_load_one(struct pci_dev *pdev, int pci_dev_data, static int mlx4_load_one(struct pci_dev *pdev, int pci_dev_data,
int total_vfs, int *nvfs, struct mlx4_priv *priv, int total_vfs, int *nvfs, struct mlx4_priv *priv,
int reset_flow) int reset_flow)
...@@ -3582,7 +3610,7 @@ static int __mlx4_init_one(struct pci_dev *pdev, int pci_dev_data, ...@@ -3582,7 +3610,7 @@ static int __mlx4_init_one(struct pci_dev *pdev, int pci_dev_data,
pr_info(DRV_NAME ": Initializing %s\n", pci_name(pdev)); pr_info(DRV_NAME ": Initializing %s\n", pci_name(pdev));
err = pci_enable_device(pdev); err = mlx4_pci_enable_device(&priv->dev);
if (err) { if (err) {
dev_err(&pdev->dev, "Cannot enable PCI device, aborting\n"); dev_err(&pdev->dev, "Cannot enable PCI device, aborting\n");
return err; return err;
...@@ -3715,7 +3743,7 @@ static int __mlx4_init_one(struct pci_dev *pdev, int pci_dev_data, ...@@ -3715,7 +3743,7 @@ static int __mlx4_init_one(struct pci_dev *pdev, int pci_dev_data,
pci_release_regions(pdev); pci_release_regions(pdev);
err_disable_pdev: err_disable_pdev:
pci_disable_device(pdev); mlx4_pci_disable_device(&priv->dev);
pci_set_drvdata(pdev, NULL); pci_set_drvdata(pdev, NULL);
return err; return err;
} }
...@@ -3775,6 +3803,7 @@ static int mlx4_init_one(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -3775,6 +3803,7 @@ static int mlx4_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
priv->pci_dev_data = id->driver_data; priv->pci_dev_data = id->driver_data;
mutex_init(&dev->persist->device_state_mutex); mutex_init(&dev->persist->device_state_mutex);
mutex_init(&dev->persist->interface_state_mutex); mutex_init(&dev->persist->interface_state_mutex);
mutex_init(&dev->persist->pci_status_mutex);
ret = devlink_register(devlink, &pdev->dev); ret = devlink_register(devlink, &pdev->dev);
if (ret) if (ret)
...@@ -3923,7 +3952,7 @@ static void mlx4_remove_one(struct pci_dev *pdev) ...@@ -3923,7 +3952,7 @@ static void mlx4_remove_one(struct pci_dev *pdev)
} }
pci_release_regions(pdev); pci_release_regions(pdev);
pci_disable_device(pdev); mlx4_pci_disable_device(dev);
devlink_unregister(devlink); devlink_unregister(devlink);
kfree(dev->persist); kfree(dev->persist);
devlink_free(devlink); devlink_free(devlink);
...@@ -4042,7 +4071,7 @@ static pci_ers_result_t mlx4_pci_err_detected(struct pci_dev *pdev, ...@@ -4042,7 +4071,7 @@ static pci_ers_result_t mlx4_pci_err_detected(struct pci_dev *pdev,
if (state == pci_channel_io_perm_failure) if (state == pci_channel_io_perm_failure)
return PCI_ERS_RESULT_DISCONNECT; return PCI_ERS_RESULT_DISCONNECT;
pci_disable_device(pdev); mlx4_pci_disable_device(persist->dev);
return PCI_ERS_RESULT_NEED_RESET; return PCI_ERS_RESULT_NEED_RESET;
} }
...@@ -4053,7 +4082,7 @@ static pci_ers_result_t mlx4_pci_slot_reset(struct pci_dev *pdev) ...@@ -4053,7 +4082,7 @@ static pci_ers_result_t mlx4_pci_slot_reset(struct pci_dev *pdev)
int err; int err;
mlx4_err(dev, "mlx4_pci_slot_reset was called\n"); mlx4_err(dev, "mlx4_pci_slot_reset was called\n");
err = pci_enable_device(pdev); err = mlx4_pci_enable_device(dev);
if (err) { if (err) {
mlx4_err(dev, "Can not re-enable device, err=%d\n", err); mlx4_err(dev, "Can not re-enable device, err=%d\n", err);
return PCI_ERS_RESULT_DISCONNECT; return PCI_ERS_RESULT_DISCONNECT;
......
...@@ -828,6 +828,11 @@ struct mlx4_vf_dev { ...@@ -828,6 +828,11 @@ struct mlx4_vf_dev {
u8 n_ports; u8 n_ports;
}; };
enum mlx4_pci_status {
MLX4_PCI_STATUS_DISABLED,
MLX4_PCI_STATUS_ENABLED,
};
struct mlx4_dev_persistent { struct mlx4_dev_persistent {
struct pci_dev *pdev; struct pci_dev *pdev;
struct mlx4_dev *dev; struct mlx4_dev *dev;
...@@ -841,6 +846,8 @@ struct mlx4_dev_persistent { ...@@ -841,6 +846,8 @@ struct mlx4_dev_persistent {
u8 state; u8 state;
struct mutex interface_state_mutex; /* protect SW state */ struct mutex interface_state_mutex; /* protect SW state */
u8 interface_state; u8 interface_state;
struct mutex pci_status_mutex; /* sync pci state */
enum mlx4_pci_status pci_status;
}; };
struct mlx4_dev { struct mlx4_dev {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册