Commit d78f8d83 authored by David S. Miller's avatar David S. Miller
Browse files
Tony Nguyen says:

====================
net: implement devlink reload in ice

Michal Swiatkowski says:

This is a part of changes done in patchset [0]. Resource management is
kind of controversial part, so I split it into two patchsets.

It is the first one, covering refactor and implement reload API call.
The refactor will unblock some of the patches needed by SIOV or
subfunction.

Most of this patchset is about implementing driver reload mechanism.
Part of code from probe and rebuild is used to not duplicate code.
To allow this reuse probe and rebuild path are split into smaller
functions.

Patch "ice: split ice_vsi_setup into smaller functions" changes
boolean variable in function call to integer and adds define
for it. Instead of having the function called with true/false now it
can be called with readable defines ICE_VSI_FLAG_INIT or
ICE_VSI_FLAG_NO_INIT. It was suggested by Jacob Keller and probably this
mechanism will be implemented across ice driver in follow up patchset.

Previously the code was reviewed here [0].

[0] https://lore.kernel.org/netdev/Y3ckRWtAtZU1BdXm@unreal/T/#m3bb8feba0a62f9b4cd54cd94917b7e2143fc2ecd



====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 9dde0cd3 31c8db2c
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
@@ -353,7 +353,6 @@ struct ice_vsi {

	struct ice_vf *vf;		/* VF associated with this VSI */

	u16 ethtype;			/* Ethernet protocol for pause frame */
	u16 num_gfltr;
	u16 num_bfltr;

@@ -889,7 +888,7 @@ ice_fetch_u64_stats_per_ring(struct u64_stats_sync *syncp,
int ice_up(struct ice_vsi *vsi);
int ice_down(struct ice_vsi *vsi);
int ice_down_up(struct ice_vsi *vsi);
int ice_vsi_cfg(struct ice_vsi *vsi);
int ice_vsi_cfg_lan(struct ice_vsi *vsi);
struct ice_vsi *ice_lb_vsi_setup(struct ice_pf *pf, struct ice_port_info *pi);
int ice_vsi_determine_xdp_res(struct ice_vsi *vsi);
int ice_prepare_xdp_rings(struct ice_vsi *vsi, struct bpf_prog *prog);
@@ -907,6 +906,7 @@ void ice_print_link_msg(struct ice_vsi *vsi, bool isup);
int ice_plug_aux_dev(struct ice_pf *pf);
void ice_unplug_aux_dev(struct ice_pf *pf);
int ice_init_rdma(struct ice_pf *pf);
void ice_deinit_rdma(struct ice_pf *pf);
const char *ice_aq_str(enum ice_aq_err aq_err);
bool ice_is_wol_supported(struct ice_hw *hw);
void ice_fdir_del_all_fltrs(struct ice_vsi *vsi);
@@ -931,6 +931,8 @@ int ice_open(struct net_device *netdev);
int ice_open_internal(struct net_device *netdev);
int ice_stop(struct net_device *netdev);
void ice_service_task_schedule(struct ice_pf *pf);
int ice_load(struct ice_pf *pf);
void ice_unload(struct ice_pf *pf);

/**
 * ice_set_rdma_cap - enable RDMA support
+4 −7
Original line number Diff line number Diff line
@@ -1088,8 +1088,10 @@ int ice_init_hw(struct ice_hw *hw)
	if (status)
		goto err_unroll_cqinit;

	if (!hw->port_info)
		hw->port_info = devm_kzalloc(ice_hw_to_dev(hw),
				     sizeof(*hw->port_info), GFP_KERNEL);
					     sizeof(*hw->port_info),
					     GFP_KERNEL);
	if (!hw->port_info) {
		status = -ENOMEM;
		goto err_unroll_cqinit;
@@ -1217,11 +1219,6 @@ void ice_deinit_hw(struct ice_hw *hw)
	ice_free_hw_tbls(hw);
	mutex_destroy(&hw->tnl_lock);

	if (hw->port_info) {
		devm_kfree(ice_hw_to_dev(hw), hw->port_info);
		hw->port_info = NULL;
	}

	/* Attempt to disable FW logging before shutting down control queues */
	ice_cfg_fw_log(hw, false);
	ice_destroy_all_ctrlq(hw);
+81 −22
Original line number Diff line number Diff line
@@ -371,10 +371,7 @@ static int ice_devlink_info_get(struct devlink *devlink,

/**
 * ice_devlink_reload_empr_start - Start EMP reset to activate new firmware
 * @devlink: pointer to the devlink instance to reload
 * @netns_change: if true, the network namespace is changing
 * @action: the action to perform. Must be DEVLINK_RELOAD_ACTION_FW_ACTIVATE
 * @limit: limits on what reload should do, such as not resetting
 * @pf: pointer to the pf instance
 * @extack: netlink extended ACK structure
 *
 * Allow user to activate new Embedded Management Processor firmware by
@@ -387,12 +384,9 @@ static int ice_devlink_info_get(struct devlink *devlink,
 * any source.
 */
static int
ice_devlink_reload_empr_start(struct devlink *devlink, bool netns_change,
			      enum devlink_reload_action action,
			      enum devlink_reload_limit limit,
ice_devlink_reload_empr_start(struct ice_pf *pf,
			      struct netlink_ext_ack *extack)
{
	struct ice_pf *pf = devlink_priv(devlink);
	struct device *dev = ice_pf_to_dev(pf);
	struct ice_hw *hw = &pf->hw;
	u8 pending;
@@ -430,12 +424,52 @@ ice_devlink_reload_empr_start(struct devlink *devlink, bool netns_change,
	return 0;
}

/**
 * ice_devlink_reload_down - prepare for reload
 * @devlink: pointer to the devlink instance to reload
 * @netns_change: if true, the network namespace is changing
 * @action: the action to perform
 * @limit: limits on what reload should do, such as not resetting
 * @extack: netlink extended ACK structure
 */
static int
ice_devlink_reload_down(struct devlink *devlink, bool netns_change,
			enum devlink_reload_action action,
			enum devlink_reload_limit limit,
			struct netlink_ext_ack *extack)
{
	struct ice_pf *pf = devlink_priv(devlink);

	switch (action) {
	case DEVLINK_RELOAD_ACTION_DRIVER_REINIT:
		if (ice_is_eswitch_mode_switchdev(pf)) {
			NL_SET_ERR_MSG_MOD(extack,
					   "Go to legacy mode before doing reinit\n");
			return -EOPNOTSUPP;
		}
		if (ice_is_adq_active(pf)) {
			NL_SET_ERR_MSG_MOD(extack,
					   "Turn off ADQ before doing reinit\n");
			return -EOPNOTSUPP;
		}
		if (ice_has_vfs(pf)) {
			NL_SET_ERR_MSG_MOD(extack,
					   "Remove all VFs before doing reinit\n");
			return -EOPNOTSUPP;
		}
		ice_unload(pf);
		return 0;
	case DEVLINK_RELOAD_ACTION_FW_ACTIVATE:
		return ice_devlink_reload_empr_start(pf, extack);
	default:
		WARN_ON(1);
		return -EOPNOTSUPP;
	}
}

/**
 * ice_devlink_reload_empr_finish - Wait for EMP reset to finish
 * @devlink: pointer to the devlink instance reloading
 * @action: the action requested
 * @limit: limits imposed by userspace, such as not resetting
 * @actions_performed: on return, indicate what actions actually performed
 * @pf: pointer to the pf instance
 * @extack: netlink extended ACK structure
 *
 * Wait for driver to finish rebuilding after EMP reset is completed. This
@@ -443,17 +477,11 @@ ice_devlink_reload_empr_start(struct devlink *devlink, bool netns_change,
 * for the driver's rebuild to complete.
 */
static int
ice_devlink_reload_empr_finish(struct devlink *devlink,
			       enum devlink_reload_action action,
			       enum devlink_reload_limit limit,
			       u32 *actions_performed,
ice_devlink_reload_empr_finish(struct ice_pf *pf,
			       struct netlink_ext_ack *extack)
{
	struct ice_pf *pf = devlink_priv(devlink);
	int err;

	*actions_performed = BIT(DEVLINK_RELOAD_ACTION_FW_ACTIVATE);

	err = ice_wait_for_reset(pf, 60 * HZ);
	if (err) {
		NL_SET_ERR_MSG_MOD(extack, "Device still resetting after 1 minute");
@@ -1192,12 +1220,43 @@ static int ice_devlink_set_parent(struct devlink_rate *devlink_rate,
	return status;
}

/**
 * ice_devlink_reload_up - do reload up after reinit
 * @devlink: pointer to the devlink instance reloading
 * @action: the action requested
 * @limit: limits imposed by userspace, such as not resetting
 * @actions_performed: on return, indicate what actions actually performed
 * @extack: netlink extended ACK structure
 */
static int
ice_devlink_reload_up(struct devlink *devlink,
		      enum devlink_reload_action action,
		      enum devlink_reload_limit limit,
		      u32 *actions_performed,
		      struct netlink_ext_ack *extack)
{
	struct ice_pf *pf = devlink_priv(devlink);

	switch (action) {
	case DEVLINK_RELOAD_ACTION_DRIVER_REINIT:
		*actions_performed = BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT);
		return ice_load(pf);
	case DEVLINK_RELOAD_ACTION_FW_ACTIVATE:
		*actions_performed = BIT(DEVLINK_RELOAD_ACTION_FW_ACTIVATE);
		return ice_devlink_reload_empr_finish(pf, extack);
	default:
		WARN_ON(1);
		return -EOPNOTSUPP;
	}
}

static const struct devlink_ops ice_devlink_ops = {
	.supported_flash_update_params = DEVLINK_SUPPORT_FLASH_UPDATE_OVERWRITE_MASK,
	.reload_actions = BIT(DEVLINK_RELOAD_ACTION_FW_ACTIVATE),
	.reload_actions = BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT) |
			  BIT(DEVLINK_RELOAD_ACTION_FW_ACTIVATE),
	/* The ice driver currently does not support driver reinit */
	.reload_down = ice_devlink_reload_empr_start,
	.reload_up = ice_devlink_reload_empr_finish,
	.reload_down = ice_devlink_reload_down,
	.reload_up = ice_devlink_reload_up,
	.port_split = ice_devlink_port_split,
	.port_unsplit = ice_devlink_port_unsplit,
	.eswitch_mode_get = ice_eswitch_mode_get,
+1 −1
Original line number Diff line number Diff line
@@ -656,7 +656,7 @@ static int ice_lbtest_prepare_rings(struct ice_vsi *vsi)
	if (status)
		goto err_setup_rx_ring;

	status = ice_vsi_cfg(vsi);
	status = ice_vsi_cfg_lan(vsi);
	if (status)
		goto err_setup_rx_ring;

+5 −0
Original line number Diff line number Diff line
@@ -208,6 +208,11 @@ static int ice_fltr_remove_eth_list(struct ice_vsi *vsi, struct list_head *list)
void ice_fltr_remove_all(struct ice_vsi *vsi)
{
	ice_remove_vsi_fltr(&vsi->back->hw, vsi->idx);
	/* sync netdev filters if exist */
	if (vsi->netdev) {
		__dev_uc_unsync(vsi->netdev, NULL);
		__dev_mc_unsync(vsi->netdev, NULL);
	}
}

/**
Loading