ice: Remove and readd netdev during devlink reload
Recent changes to the devlink reload (commit 9b2348e2d6c9 ("devlink: warn about existing entities during reload-reinit")) force the drivers to destroy devlink ports during reinit. Adjust ice driver to this requirement, unregister netdvice, destroy devlink port. ice_init_eth() was removed and all the common code between probe and reload was moved to ice_load(). During devlink reload we can't take devl_lock (it's already taken) and in ice_probe() we have to lock it. Use devl_* variant of the API which does not acquire and release devl_lock. Guard ice_load() with devl_lock only in case of probe. Suggested-by: Jiri Pirko <jiri@nvidia.com> Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com> Reviewed-by: Vadim Fedorenko <vadim.fedorenko@linux.dev> Reviewed-by: Simon Horman <horms@kernel.org> Reviewed-by: Brett Creeley <brett.creeley@amd.com> Signed-off-by: Wojciech Drewek <wojciech.drewek@intel.com> Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel) Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
This commit is contained in:
parent
372e27de4c
commit
41cc4e5393
@ -983,6 +983,8 @@ void ice_service_task_schedule(struct ice_pf *pf);
|
||||
int ice_load(struct ice_pf *pf);
|
||||
void ice_unload(struct ice_pf *pf);
|
||||
void ice_adv_lnk_speed_maps_init(void);
|
||||
int ice_init_dev(struct ice_pf *pf);
|
||||
void ice_deinit_dev(struct ice_pf *pf);
|
||||
|
||||
/**
|
||||
* ice_set_rdma_cap - enable RDMA support
|
||||
|
@ -444,6 +444,20 @@ ice_devlink_reload_empr_start(struct ice_pf *pf,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_devlink_reinit_down - unload given PF
|
||||
* @pf: pointer to the PF struct
|
||||
*/
|
||||
static void ice_devlink_reinit_down(struct ice_pf *pf)
|
||||
{
|
||||
/* No need to take devl_lock, it's already taken by devlink API */
|
||||
ice_unload(pf);
|
||||
rtnl_lock();
|
||||
ice_vsi_decfg(ice_get_main_vsi(pf));
|
||||
rtnl_unlock();
|
||||
ice_deinit_dev(pf);
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_devlink_reload_down - prepare for reload
|
||||
* @devlink: pointer to the devlink instance to reload
|
||||
@ -477,7 +491,7 @@ ice_devlink_reload_down(struct devlink *devlink, bool netns_change,
|
||||
"Remove all VFs before doing reinit\n");
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
ice_unload(pf);
|
||||
ice_devlink_reinit_down(pf);
|
||||
return 0;
|
||||
case DEVLINK_RELOAD_ACTION_FW_ACTIVATE:
|
||||
return ice_devlink_reload_empr_start(pf, extack);
|
||||
@ -1269,6 +1283,45 @@ static int ice_devlink_set_parent(struct devlink_rate *devlink_rate,
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_devlink_reinit_up - do reinit of the given PF
|
||||
* @pf: pointer to the PF struct
|
||||
*/
|
||||
static int ice_devlink_reinit_up(struct ice_pf *pf)
|
||||
{
|
||||
struct ice_vsi *vsi = ice_get_main_vsi(pf);
|
||||
struct ice_vsi_cfg_params params;
|
||||
int err;
|
||||
|
||||
err = ice_init_dev(pf);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
params = ice_vsi_to_params(vsi);
|
||||
params.flags = ICE_VSI_FLAG_INIT;
|
||||
|
||||
rtnl_lock();
|
||||
err = ice_vsi_cfg(vsi, ¶ms);
|
||||
rtnl_unlock();
|
||||
if (err)
|
||||
goto err_vsi_cfg;
|
||||
|
||||
/* No need to take devl_lock, it's already taken by devlink API */
|
||||
err = ice_load(pf);
|
||||
if (err)
|
||||
goto err_load;
|
||||
|
||||
return 0;
|
||||
|
||||
err_load:
|
||||
rtnl_lock();
|
||||
ice_vsi_decfg(vsi);
|
||||
rtnl_unlock();
|
||||
err_vsi_cfg:
|
||||
ice_deinit_dev(pf);
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_devlink_reload_up - do reload up after reinit
|
||||
* @devlink: pointer to the devlink instance reloading
|
||||
@ -1289,7 +1342,7 @@ ice_devlink_reload_up(struct devlink *devlink,
|
||||
switch (action) {
|
||||
case DEVLINK_RELOAD_ACTION_DRIVER_REINIT:
|
||||
*actions_performed = BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT);
|
||||
return ice_load(pf);
|
||||
return ice_devlink_reinit_up(pf);
|
||||
case DEVLINK_RELOAD_ACTION_FW_ACTIVATE:
|
||||
*actions_performed = BIT(DEVLINK_RELOAD_ACTION_FW_ACTIVATE);
|
||||
return ice_devlink_reload_empr_finish(pf, extack);
|
||||
@ -1569,6 +1622,7 @@ static const struct devlink_port_ops ice_devlink_port_ops = {
|
||||
* @pf: the PF to create a devlink port for
|
||||
*
|
||||
* Create and register a devlink_port for this PF.
|
||||
* This function has to be called under devl_lock.
|
||||
*
|
||||
* Return: zero on success or an error code on failure.
|
||||
*/
|
||||
@ -1581,6 +1635,8 @@ int ice_devlink_create_pf_port(struct ice_pf *pf)
|
||||
struct device *dev;
|
||||
int err;
|
||||
|
||||
devlink = priv_to_devlink(pf);
|
||||
|
||||
dev = ice_pf_to_dev(pf);
|
||||
|
||||
devlink_port = &pf->devlink_port;
|
||||
@ -1601,10 +1657,9 @@ int ice_devlink_create_pf_port(struct ice_pf *pf)
|
||||
ice_devlink_set_switch_id(pf, &attrs.switch_id);
|
||||
|
||||
devlink_port_attrs_set(devlink_port, &attrs);
|
||||
devlink = priv_to_devlink(pf);
|
||||
|
||||
err = devlink_port_register_with_ops(devlink, devlink_port, vsi->idx,
|
||||
&ice_devlink_port_ops);
|
||||
err = devl_port_register_with_ops(devlink, devlink_port, vsi->idx,
|
||||
&ice_devlink_port_ops);
|
||||
if (err) {
|
||||
dev_err(dev, "Failed to create devlink port for PF %d, error %d\n",
|
||||
pf->hw.pf_id, err);
|
||||
@ -1619,10 +1674,11 @@ int ice_devlink_create_pf_port(struct ice_pf *pf)
|
||||
* @pf: the PF to cleanup
|
||||
*
|
||||
* Unregisters the devlink_port structure associated with this PF.
|
||||
* This function has to be called under devl_lock.
|
||||
*/
|
||||
void ice_devlink_destroy_pf_port(struct ice_pf *pf)
|
||||
{
|
||||
devlink_port_unregister(&pf->devlink_port);
|
||||
devl_port_unregister(&pf->devlink_port);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -4574,90 +4574,6 @@ static void ice_decfg_netdev(struct ice_vsi *vsi)
|
||||
vsi->netdev = NULL;
|
||||
}
|
||||
|
||||
static int ice_start_eth(struct ice_vsi *vsi)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = ice_init_mac_fltr(vsi->back);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = ice_vsi_open(vsi);
|
||||
if (err)
|
||||
ice_fltr_remove_all(vsi);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static void ice_stop_eth(struct ice_vsi *vsi)
|
||||
{
|
||||
ice_fltr_remove_all(vsi);
|
||||
ice_vsi_close(vsi);
|
||||
}
|
||||
|
||||
static int ice_init_eth(struct ice_pf *pf)
|
||||
{
|
||||
struct ice_vsi *vsi = ice_get_main_vsi(pf);
|
||||
int err;
|
||||
|
||||
if (!vsi)
|
||||
return -EINVAL;
|
||||
|
||||
/* init channel list */
|
||||
INIT_LIST_HEAD(&vsi->ch_list);
|
||||
|
||||
err = ice_cfg_netdev(vsi);
|
||||
if (err)
|
||||
return err;
|
||||
/* Setup DCB netlink interface */
|
||||
ice_dcbnl_setup(vsi);
|
||||
|
||||
err = ice_init_mac_fltr(pf);
|
||||
if (err)
|
||||
goto err_init_mac_fltr;
|
||||
|
||||
err = ice_devlink_create_pf_port(pf);
|
||||
if (err)
|
||||
goto err_devlink_create_pf_port;
|
||||
|
||||
SET_NETDEV_DEVLINK_PORT(vsi->netdev, &pf->devlink_port);
|
||||
|
||||
err = ice_register_netdev(vsi);
|
||||
if (err)
|
||||
goto err_register_netdev;
|
||||
|
||||
err = ice_tc_indir_block_register(vsi);
|
||||
if (err)
|
||||
goto err_tc_indir_block_register;
|
||||
|
||||
ice_napi_add(vsi);
|
||||
|
||||
return 0;
|
||||
|
||||
err_tc_indir_block_register:
|
||||
ice_unregister_netdev(vsi);
|
||||
err_register_netdev:
|
||||
ice_devlink_destroy_pf_port(pf);
|
||||
err_devlink_create_pf_port:
|
||||
err_init_mac_fltr:
|
||||
ice_decfg_netdev(vsi);
|
||||
return err;
|
||||
}
|
||||
|
||||
static void ice_deinit_eth(struct ice_pf *pf)
|
||||
{
|
||||
struct ice_vsi *vsi = ice_get_main_vsi(pf);
|
||||
|
||||
if (!vsi)
|
||||
return;
|
||||
|
||||
ice_vsi_close(vsi);
|
||||
ice_unregister_netdev(vsi);
|
||||
ice_devlink_destroy_pf_port(pf);
|
||||
ice_tc_indir_block_unregister(vsi);
|
||||
ice_decfg_netdev(vsi);
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_wait_for_fw - wait for full FW readiness
|
||||
* @hw: pointer to the hardware structure
|
||||
@ -4683,7 +4599,7 @@ static int ice_wait_for_fw(struct ice_hw *hw, u32 timeout)
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
static int ice_init_dev(struct ice_pf *pf)
|
||||
int ice_init_dev(struct ice_pf *pf)
|
||||
{
|
||||
struct device *dev = ice_pf_to_dev(pf);
|
||||
struct ice_hw *hw = &pf->hw;
|
||||
@ -4776,7 +4692,7 @@ err_init_pf:
|
||||
return err;
|
||||
}
|
||||
|
||||
static void ice_deinit_dev(struct ice_pf *pf)
|
||||
void ice_deinit_dev(struct ice_pf *pf)
|
||||
{
|
||||
ice_free_irq_msix_misc(pf);
|
||||
ice_deinit_pf(pf);
|
||||
@ -5081,31 +4997,47 @@ static void ice_deinit(struct ice_pf *pf)
|
||||
/**
|
||||
* ice_load - load pf by init hw and starting VSI
|
||||
* @pf: pointer to the pf instance
|
||||
*
|
||||
* This function has to be called under devl_lock.
|
||||
*/
|
||||
int ice_load(struct ice_pf *pf)
|
||||
{
|
||||
struct ice_vsi_cfg_params params = {};
|
||||
struct ice_vsi *vsi;
|
||||
int err;
|
||||
|
||||
err = ice_init_dev(pf);
|
||||
if (err)
|
||||
return err;
|
||||
devl_assert_locked(priv_to_devlink(pf));
|
||||
|
||||
vsi = ice_get_main_vsi(pf);
|
||||
|
||||
params = ice_vsi_to_params(vsi);
|
||||
params.flags = ICE_VSI_FLAG_INIT;
|
||||
/* init channel list */
|
||||
INIT_LIST_HEAD(&vsi->ch_list);
|
||||
|
||||
rtnl_lock();
|
||||
err = ice_vsi_cfg(vsi, ¶ms);
|
||||
err = ice_cfg_netdev(vsi);
|
||||
if (err)
|
||||
goto err_vsi_cfg;
|
||||
return err;
|
||||
|
||||
err = ice_start_eth(ice_get_main_vsi(pf));
|
||||
/* Setup DCB netlink interface */
|
||||
ice_dcbnl_setup(vsi);
|
||||
|
||||
err = ice_init_mac_fltr(pf);
|
||||
if (err)
|
||||
goto err_start_eth;
|
||||
rtnl_unlock();
|
||||
goto err_init_mac_fltr;
|
||||
|
||||
err = ice_devlink_create_pf_port(pf);
|
||||
if (err)
|
||||
goto err_devlink_create_pf_port;
|
||||
|
||||
SET_NETDEV_DEVLINK_PORT(vsi->netdev, &pf->devlink_port);
|
||||
|
||||
err = ice_register_netdev(vsi);
|
||||
if (err)
|
||||
goto err_register_netdev;
|
||||
|
||||
err = ice_tc_indir_block_register(vsi);
|
||||
if (err)
|
||||
goto err_tc_indir_block_register;
|
||||
|
||||
ice_napi_add(vsi);
|
||||
|
||||
err = ice_init_rdma(pf);
|
||||
if (err)
|
||||
@ -5119,29 +5051,35 @@ int ice_load(struct ice_pf *pf)
|
||||
return 0;
|
||||
|
||||
err_init_rdma:
|
||||
ice_vsi_close(ice_get_main_vsi(pf));
|
||||
rtnl_lock();
|
||||
err_start_eth:
|
||||
ice_vsi_decfg(ice_get_main_vsi(pf));
|
||||
err_vsi_cfg:
|
||||
rtnl_unlock();
|
||||
ice_deinit_dev(pf);
|
||||
ice_tc_indir_block_unregister(vsi);
|
||||
err_tc_indir_block_register:
|
||||
ice_unregister_netdev(vsi);
|
||||
err_register_netdev:
|
||||
ice_devlink_destroy_pf_port(pf);
|
||||
err_devlink_create_pf_port:
|
||||
err_init_mac_fltr:
|
||||
ice_decfg_netdev(vsi);
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_unload - unload pf by stopping VSI and deinit hw
|
||||
* @pf: pointer to the pf instance
|
||||
*
|
||||
* This function has to be called under devl_lock.
|
||||
*/
|
||||
void ice_unload(struct ice_pf *pf)
|
||||
{
|
||||
struct ice_vsi *vsi = ice_get_main_vsi(pf);
|
||||
|
||||
devl_assert_locked(priv_to_devlink(pf));
|
||||
|
||||
ice_deinit_features(pf);
|
||||
ice_deinit_rdma(pf);
|
||||
rtnl_lock();
|
||||
ice_stop_eth(ice_get_main_vsi(pf));
|
||||
ice_vsi_decfg(ice_get_main_vsi(pf));
|
||||
rtnl_unlock();
|
||||
ice_deinit_dev(pf);
|
||||
ice_tc_indir_block_unregister(vsi);
|
||||
ice_unregister_netdev(vsi);
|
||||
ice_devlink_destroy_pf_port(pf);
|
||||
ice_decfg_netdev(vsi);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -5239,27 +5177,23 @@ ice_probe(struct pci_dev *pdev, const struct pci_device_id __always_unused *ent)
|
||||
if (err)
|
||||
goto err_init;
|
||||
|
||||
err = ice_init_eth(pf);
|
||||
devl_lock(priv_to_devlink(pf));
|
||||
err = ice_load(pf);
|
||||
devl_unlock(priv_to_devlink(pf));
|
||||
if (err)
|
||||
goto err_init_eth;
|
||||
|
||||
err = ice_init_rdma(pf);
|
||||
if (err)
|
||||
goto err_init_rdma;
|
||||
goto err_load;
|
||||
|
||||
err = ice_init_devlink(pf);
|
||||
if (err)
|
||||
goto err_init_devlink;
|
||||
|
||||
ice_init_features(pf);
|
||||
|
||||
return 0;
|
||||
|
||||
err_init_devlink:
|
||||
ice_deinit_rdma(pf);
|
||||
err_init_rdma:
|
||||
ice_deinit_eth(pf);
|
||||
err_init_eth:
|
||||
devl_lock(priv_to_devlink(pf));
|
||||
ice_unload(pf);
|
||||
devl_unlock(priv_to_devlink(pf));
|
||||
err_load:
|
||||
ice_deinit(pf);
|
||||
err_init:
|
||||
pci_disable_device(pdev);
|
||||
@ -5357,12 +5291,14 @@ static void ice_remove(struct pci_dev *pdev)
|
||||
|
||||
if (!ice_is_safe_mode(pf))
|
||||
ice_remove_arfs(pf);
|
||||
ice_deinit_features(pf);
|
||||
ice_deinit_devlink(pf);
|
||||
ice_deinit_rdma(pf);
|
||||
ice_deinit_eth(pf);
|
||||
ice_deinit(pf);
|
||||
|
||||
ice_deinit_devlink(pf);
|
||||
|
||||
devl_lock(priv_to_devlink(pf));
|
||||
ice_unload(pf);
|
||||
devl_unlock(priv_to_devlink(pf));
|
||||
|
||||
ice_deinit(pf);
|
||||
ice_vsi_release_all(pf);
|
||||
|
||||
ice_setup_mc_magic_wake(pf);
|
||||
|
Loading…
x
Reference in New Issue
Block a user