Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c69453e2 authored by Yishai Hadas's avatar Yishai Hadas Committed by David S. Miller
Browse files

net/mlx4_core: Manage interface state for Reset flow cases



We need to manage interface state to sync between reset flow and some other
relative cases such as remove_one. This has to be done to prevent certain
races. For example in case software stack is down as a result of unload call,
the remove_one should skip the unload phase.

Implement the remove_one case, handling AER and other cases comes next.

The interface can be up/down, upon remove_one, the state will include an extra
bit indicating that the device is cleaned-up, forcing other tasks to finish
before the final cleanup.

Signed-off-by: default avatarYishai Hadas <yishaih@mellanox.com>
Signed-off-by: default avatarOr Gerlitz <ogerlitz@mellanox.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent f5aef5aa
Loading
Loading
Loading
Loading
+11 −2
Original line number Diff line number Diff line
@@ -122,8 +122,14 @@ static void mlx4_handle_error_state(struct mlx4_dev_persistent *persist)
	int err = 0;

	mlx4_enter_error_state(persist);
	mutex_lock(&persist->interface_state_mutex);
	if (persist->interface_state & MLX4_INTERFACE_STATE_UP &&
	    !(persist->interface_state & MLX4_INTERFACE_STATE_DELETION)) {
		err = mlx4_restart_one(persist->pdev);
	mlx4_info(persist->dev, "mlx4_restart_one was ended, ret=%d\n", err);
		mlx4_info(persist->dev, "mlx4_restart_one was ended, ret=%d\n",
			  err);
	}
	mutex_unlock(&persist->interface_state_mutex);
}

static void dump_err_buf(struct mlx4_dev *dev)
@@ -211,6 +217,9 @@ void mlx4_stop_catas_poll(struct mlx4_dev *dev)
		iounmap(priv->catas_err.map);
		priv->catas_err.map = NULL;
	}

	if (dev->persist->interface_state & MLX4_INTERFACE_STATE_DELETION)
		flush_workqueue(dev->persist->catas_wq);
}

int  mlx4_catas_init(struct mlx4_dev *dev)
+2 −0
Original line number Diff line number Diff line
@@ -138,6 +138,7 @@ int mlx4_register_device(struct mlx4_dev *dev)

	mutex_lock(&intf_mutex);

	dev->persist->interface_state |= MLX4_INTERFACE_STATE_UP;
	list_add_tail(&priv->dev_list, &dev_list);
	list_for_each_entry(intf, &intf_list, list)
		mlx4_add_device(intf, priv);
@@ -162,6 +163,7 @@ void mlx4_unregister_device(struct mlx4_dev *dev)
		mlx4_remove_device(intf, priv);

	list_del(&priv->dev_list);
	dev->persist->interface_state &= ~MLX4_INTERFACE_STATE_UP;

	mutex_unlock(&intf_mutex);
}
+12 −1
Original line number Diff line number Diff line
@@ -3114,6 +3114,7 @@ static int mlx4_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
	pci_set_drvdata(pdev, dev->persist);
	priv->pci_dev_data = id->driver_data;
	mutex_init(&dev->persist->device_state_mutex);
	mutex_init(&dev->persist->interface_state_mutex);

	ret =  __mlx4_init_one(pdev, id->driver_data, priv);
	if (ret) {
@@ -3232,7 +3233,17 @@ static void mlx4_remove_one(struct pci_dev *pdev)
	struct mlx4_dev  *dev  = persist->dev;
	struct mlx4_priv *priv = mlx4_priv(dev);

	mutex_lock(&persist->interface_state_mutex);
	persist->interface_state |= MLX4_INTERFACE_STATE_DELETION;
	mutex_unlock(&persist->interface_state_mutex);

	/* device marked to be under deletion running now without the lock
	 * letting other tasks to be terminated
	 */
	if (persist->interface_state & MLX4_INTERFACE_STATE_UP)
		mlx4_unload_one(pdev);
	else
		mlx4_info(dev, "%s: interface is down\n", __func__);
	mlx4_catas_end(dev);
	pci_release_regions(pdev);
	pci_disable_device(pdev);
+7 −0
Original line number Diff line number Diff line
@@ -416,6 +416,11 @@ enum {
	MLX4_DEVICE_STATE_INTERNAL_ERROR	= 1 << 1,
};

enum {
	MLX4_INTERFACE_STATE_UP		= 1 << 0,
	MLX4_INTERFACE_STATE_DELETION	= 1 << 1,
};

#define MSTR_SM_CHANGE_MASK (MLX4_EQ_PORT_INFO_MSTR_SM_SL_CHANGE_MASK | \
			     MLX4_EQ_PORT_INFO_MSTR_SM_LID_CHANGE_MASK)

@@ -760,6 +765,8 @@ struct mlx4_dev_persistent {
	struct workqueue_struct *catas_wq;
	struct mutex	device_state_mutex; /* protect HW state */
	u8		state;
	struct mutex	interface_state_mutex; /* protect SW state */
	u8	interface_state;
};

struct mlx4_dev {