Merge branch 'devlink_register-last'

Leon Romanovsky says:

====================
Move devlink_register to be last devlink command

This is second version of patch series
https://lore.kernel.org/netdev/cover.1628599239.git.leonro@nvidia.com/

The main change is addition of delayed notification logic that will
allowed us to delete devlink_params_publish API (future series will
remove it completely) and conversion of all drivers to have devlink_register
being last commend.

The series itself is pretty straightforward, except liquidio driver
which performs initializations in various workqueues without proper
locks. That driver doesn't hole device_lock and it is clearly broken
for any parallel driver core flows (modprobe + devlink + PCI reset will
100% crash it).

In order to annotate devlink_register() will lockdep of holding
device_lock, I added workaround in this driver.

Thanks

----------------------
From previous cover letter:
Hi Dave and Jakub,

This series prepares code to remove devlink_reload_enable/_disable API
and in order to do, we move all devlink_register() calls to be right
before devlink_reload_enable().

The best place for such a call should be right before exiting from
the probe().

This is done because devlink_register() opens devlink netlink to the
users and gives them a venue to issue commands before initialization
is finished.

1. Some drivers were aware of such "functionality" and tried to protect
themselves with extra locks, state machines and devlink_reload_enable().
Let's assume that it worked for them, but I'm personally skeptical about
it.

2. Some drivers copied that pattern, but without locks and state
machines. That protected them from reload flows, but not from any _set_
routines.

3. And all other drivers simply didn't understand the implications of early
devlink_register() and can be seen as "broken".
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
David S. Miller 2021-09-27 16:32:21 +01:00
commit d06d54a346
30 changed files with 204 additions and 179 deletions

View file

@ -745,14 +745,10 @@ static int bnxt_dl_params_register(struct bnxt *bp)
rc = devlink_params_register(bp->dl, bnxt_dl_params,
ARRAY_SIZE(bnxt_dl_params));
if (rc) {
if (rc)
netdev_warn(bp->dev, "devlink_params_register failed. rc=%d\n",
rc);
return rc;
}
devlink_params_publish(bp->dl);
return 0;
return rc;
}
static void bnxt_dl_params_unregister(struct bnxt *bp)
@ -792,9 +788,8 @@ int bnxt_dl_register(struct bnxt *bp)
bp->hwrm_spec_code > 0x10803)
bp->eswitch_mode = DEVLINK_ESWITCH_MODE_LEGACY;
devlink_register(dl);
if (!BNXT_PF(bp))
return 0;
goto out;
attrs.flavour = DEVLINK_PORT_FLAVOUR_PHYSICAL;
attrs.phys.port_number = bp->pf.port_id;
@ -811,6 +806,8 @@ int bnxt_dl_register(struct bnxt *bp)
if (rc)
goto err_dl_port_unreg;
out:
devlink_register(dl);
return 0;
err_dl_port_unreg:
@ -824,10 +821,10 @@ void bnxt_dl_unregister(struct bnxt *bp)
{
struct devlink *dl = bp->dl;
devlink_unregister(dl);
if (BNXT_PF(bp)) {
bnxt_dl_params_unregister(bp);
devlink_port_unregister(&bp->dl_port);
}
devlink_unregister(dl);
devlink_free(dl);
}

View file

@ -1279,6 +1279,14 @@ static int liquidio_stop_nic_module(struct octeon_device *oct)
struct lio *lio;
dev_dbg(&oct->pci_dev->dev, "Stopping network interfaces\n");
device_lock(&oct->pci_dev->dev);
if (oct->devlink) {
devlink_unregister(oct->devlink);
devlink_free(oct->devlink);
oct->devlink = NULL;
}
device_unlock(&oct->pci_dev->dev);
if (!oct->ifcount) {
dev_err(&oct->pci_dev->dev, "Init for Octeon was not completed\n");
return 1;
@ -1300,12 +1308,6 @@ static int liquidio_stop_nic_module(struct octeon_device *oct)
for (i = 0; i < oct->ifcount; i++)
liquidio_destroy_nic_device(oct, i);
if (oct->devlink) {
devlink_unregister(oct->devlink);
devlink_free(oct->devlink);
oct->devlink = NULL;
}
dev_dbg(&oct->pci_dev->dev, "Network interfaces stopped\n");
return 0;
}
@ -3749,10 +3751,12 @@ static int setup_nic_devices(struct octeon_device *octeon_dev)
}
}
device_lock(&octeon_dev->pci_dev->dev);
devlink = devlink_alloc(&liquidio_devlink_ops,
sizeof(struct lio_devlink_priv),
&octeon_dev->pci_dev->dev);
if (!devlink) {
device_unlock(&octeon_dev->pci_dev->dev);
dev_err(&octeon_dev->pci_dev->dev, "devlink alloc failed\n");
goto setup_nic_dev_free;
}
@ -3760,9 +3764,10 @@ static int setup_nic_devices(struct octeon_device *octeon_dev)
lio_devlink = devlink_priv(devlink);
lio_devlink->oct = octeon_dev;
devlink_register(devlink);
octeon_dev->devlink = devlink;
octeon_dev->eswitch_mode = DEVLINK_ESWITCH_MODE_LEGACY;
devlink_register(devlink);
device_unlock(&octeon_dev->pci_dev->dev);
return 0;

View file

@ -189,7 +189,7 @@ static const struct devlink_ops dpaa2_eth_devlink_ops = {
.trap_group_action_set = dpaa2_eth_dl_trap_group_action_set,
};
int dpaa2_eth_dl_register(struct dpaa2_eth_priv *priv)
int dpaa2_eth_dl_alloc(struct dpaa2_eth_priv *priv)
{
struct net_device *net_dev = priv->net_dev;
struct device *dev = net_dev->dev.parent;
@ -203,15 +203,23 @@ int dpaa2_eth_dl_register(struct dpaa2_eth_priv *priv)
}
dl_priv = devlink_priv(priv->devlink);
dl_priv->dpaa2_priv = priv;
devlink_register(priv->devlink);
return 0;
}
void dpaa2_eth_dl_free(struct dpaa2_eth_priv *priv)
{
devlink_free(priv->devlink);
}
void dpaa2_eth_dl_register(struct dpaa2_eth_priv *priv)
{
devlink_register(priv->devlink);
}
void dpaa2_eth_dl_unregister(struct dpaa2_eth_priv *priv)
{
devlink_unregister(priv->devlink);
devlink_free(priv->devlink);
}
int dpaa2_eth_dl_port_add(struct dpaa2_eth_priv *priv)

View file

@ -4431,7 +4431,7 @@ static int dpaa2_eth_probe(struct fsl_mc_device *dpni_dev)
if (err)
goto err_connect_mac;
err = dpaa2_eth_dl_register(priv);
err = dpaa2_eth_dl_alloc(priv);
if (err)
goto err_dl_register;
@ -4453,6 +4453,7 @@ static int dpaa2_eth_probe(struct fsl_mc_device *dpni_dev)
dpaa2_dbg_add(priv);
#endif
dpaa2_eth_dl_register(priv);
dev_info(dev, "Probed interface %s\n", net_dev->name);
return 0;
@ -4461,7 +4462,7 @@ static int dpaa2_eth_probe(struct fsl_mc_device *dpni_dev)
err_dl_port_add:
dpaa2_eth_dl_traps_unregister(priv);
err_dl_trap_register:
dpaa2_eth_dl_unregister(priv);
dpaa2_eth_dl_free(priv);
err_dl_register:
dpaa2_eth_disconnect_mac(priv);
err_connect_mac:
@ -4508,6 +4509,8 @@ static int dpaa2_eth_remove(struct fsl_mc_device *ls_dev)
net_dev = dev_get_drvdata(dev);
priv = netdev_priv(net_dev);
dpaa2_eth_dl_unregister(priv);
#ifdef CONFIG_DEBUG_FS
dpaa2_dbg_remove(priv);
#endif
@ -4519,7 +4522,7 @@ static int dpaa2_eth_remove(struct fsl_mc_device *ls_dev)
dpaa2_eth_dl_port_del(priv);
dpaa2_eth_dl_traps_unregister(priv);
dpaa2_eth_dl_unregister(priv);
dpaa2_eth_dl_free(priv);
if (priv->do_link_poll)
kthread_stop(priv->poll_thread);

View file

@ -725,7 +725,10 @@ void dpaa2_eth_set_rx_taildrop(struct dpaa2_eth_priv *priv,
extern const struct dcbnl_rtnl_ops dpaa2_eth_dcbnl_ops;
int dpaa2_eth_dl_register(struct dpaa2_eth_priv *priv);
int dpaa2_eth_dl_alloc(struct dpaa2_eth_priv *priv);
void dpaa2_eth_dl_free(struct dpaa2_eth_priv *priv);
void dpaa2_eth_dl_register(struct dpaa2_eth_priv *priv);
void dpaa2_eth_dl_unregister(struct dpaa2_eth_priv *priv);
int dpaa2_eth_dl_port_add(struct dpaa2_eth_priv *priv);

View file

@ -754,11 +754,9 @@ static int init_pfhwdev(struct hinic_pfhwdev *pfhwdev)
return err;
}
hinic_devlink_register(hwdev->devlink_dev);
err = hinic_func_to_func_init(hwdev);
if (err) {
dev_err(&hwif->pdev->dev, "Failed to init mailbox\n");
hinic_devlink_unregister(hwdev->devlink_dev);
hinic_pf_to_mgmt_free(&pfhwdev->pf_to_mgmt);
return err;
}
@ -781,7 +779,7 @@ static int init_pfhwdev(struct hinic_pfhwdev *pfhwdev)
}
hinic_set_pf_action(hwif, HINIC_PF_MGMT_ACTIVE);
hinic_devlink_register(hwdev->devlink_dev);
return 0;
}
@ -793,6 +791,7 @@ static void free_pfhwdev(struct hinic_pfhwdev *pfhwdev)
{
struct hinic_hwdev *hwdev = &pfhwdev->hwdev;
hinic_devlink_unregister(hwdev->devlink_dev);
hinic_set_pf_action(hwdev->hwif, HINIC_PF_MGMT_INIT);
if (!HINIC_IS_VF(hwdev->hwif)) {
@ -810,8 +809,6 @@ static void free_pfhwdev(struct hinic_pfhwdev *pfhwdev)
hinic_func_to_func_free(hwdev);
hinic_devlink_unregister(hwdev->devlink_dev);
hinic_pf_to_mgmt_free(&pfhwdev->pf_to_mgmt);
}

View file

@ -4258,8 +4258,6 @@ ice_probe(struct pci_dev *pdev, const struct pci_device_id __always_unused *ent)
pf->msg_enable = netif_msg_init(debug, ICE_DFLT_NETIF_M);
ice_devlink_register(pf);
#ifndef CONFIG_DYNAMIC_DEBUG
if (debug < -1)
hw->debug_mask = debug;
@ -4493,6 +4491,7 @@ ice_probe(struct pci_dev *pdev, const struct pci_device_id __always_unused *ent)
dev_warn(dev, "RDMA is not supported on this device\n");
}
ice_devlink_register(pf);
return 0;
err_init_aux_unroll:
@ -4516,7 +4515,6 @@ ice_probe(struct pci_dev *pdev, const struct pci_device_id __always_unused *ent)
ice_devlink_destroy_regions(pf);
ice_deinit_hw(hw);
err_exit_unroll:
ice_devlink_unregister(pf);
pci_disable_pcie_error_reporting(pdev);
pci_disable_device(pdev);
return err;
@ -4593,6 +4591,7 @@ static void ice_remove(struct pci_dev *pdev)
struct ice_pf *pf = pci_get_drvdata(pdev);
int i;
ice_devlink_unregister(pf);
for (i = 0; i < ICE_MAX_RESET_WAIT; i++) {
if (!ice_is_reset_in_progress(pf->state))
break;
@ -4629,7 +4628,6 @@ static void ice_remove(struct pci_dev *pdev)
ice_deinit_pf(pf);
ice_devlink_destroy_regions(pf);
ice_deinit_hw(&pf->hw);
ice_devlink_unregister(pf);
/* Issue a PFR as part of the prescribed driver unload flow. Do not
* do it via ice_schedule_reset() since there is no need to rebuild

View file

@ -1510,7 +1510,6 @@ int rvu_register_dl(struct rvu *rvu)
return -ENOMEM;
}
devlink_register(dl);
rvu_dl = devlink_priv(dl);
rvu_dl->dl = dl;
rvu_dl->rvu = rvu;
@ -1531,13 +1530,11 @@ int rvu_register_dl(struct rvu *rvu)
goto err_dl_health;
}
devlink_params_publish(dl);
devlink_register(dl);
return 0;
err_dl_health:
rvu_health_reporters_destroy(rvu);
devlink_unregister(dl);
devlink_free(dl);
return err;
}
@ -1547,12 +1544,9 @@ void rvu_unregister_dl(struct rvu *rvu)
struct rvu_devlink *rvu_dl = rvu->rvu_dl;
struct devlink *dl = rvu_dl->dl;
if (!dl)
return;
devlink_unregister(dl);
devlink_params_unregister(dl, rvu_af_dl_params,
ARRAY_SIZE(rvu_af_dl_params));
rvu_health_reporters_destroy(rvu);
devlink_unregister(dl);
devlink_free(dl);
}

View file

@ -108,7 +108,6 @@ int otx2_register_dl(struct otx2_nic *pfvf)
return -ENOMEM;
}
devlink_register(dl);
otx2_dl = devlink_priv(dl);
otx2_dl->dl = dl;
otx2_dl->pfvf = pfvf;
@ -122,12 +121,10 @@ int otx2_register_dl(struct otx2_nic *pfvf)
goto err_dl;
}
devlink_params_publish(dl);
devlink_register(dl);
return 0;
err_dl:
devlink_unregister(dl);
devlink_free(dl);
return err;
}
@ -135,16 +132,10 @@ int otx2_register_dl(struct otx2_nic *pfvf)
void otx2_unregister_dl(struct otx2_nic *pfvf)
{
struct otx2_devlink *otx2_dl = pfvf->dl;
struct devlink *dl;
if (!otx2_dl || !otx2_dl->dl)
return;
dl = otx2_dl->dl;
devlink_params_unregister(dl, otx2_dl_params,
ARRAY_SIZE(otx2_dl_params));
struct devlink *dl = otx2_dl->dl;
devlink_unregister(dl);
devlink_params_unregister(dl, otx2_dl_params,
ARRAY_SIZE(otx2_dl_params));
devlink_free(dl);
}

View file

@ -345,8 +345,6 @@ static struct prestera_trap prestera_trap_items_arr[] = {
},
};
static void prestera_devlink_traps_fini(struct prestera_switch *sw);
static int prestera_drop_counter_get(struct devlink *devlink,
const struct devlink_trap *trap,
u64 *p_drops);
@ -381,8 +379,6 @@ static int prestera_trap_action_set(struct devlink *devlink,
enum devlink_trap_action action,
struct netlink_ext_ack *extack);
static int prestera_devlink_traps_register(struct prestera_switch *sw);
static const struct devlink_ops prestera_dl_ops = {
.info_get = prestera_dl_info_get,
.trap_init = prestera_trap_init,
@ -407,34 +403,18 @@ void prestera_devlink_free(struct prestera_switch *sw)
devlink_free(dl);
}
int prestera_devlink_register(struct prestera_switch *sw)
void prestera_devlink_register(struct prestera_switch *sw)
{
struct devlink *dl = priv_to_devlink(sw);
int err;
devlink_register(dl);
err = prestera_devlink_traps_register(sw);
if (err) {
devlink_unregister(dl);
dev_err(sw->dev->dev, "devlink_traps_register failed: %d\n",
err);
return err;
}
return 0;
}
void prestera_devlink_unregister(struct prestera_switch *sw)
{
struct prestera_trap_data *trap_data = sw->trap_data;
struct devlink *dl = priv_to_devlink(sw);
prestera_devlink_traps_fini(sw);
devlink_unregister(dl);
kfree(trap_data->trap_items_arr);
kfree(trap_data);
}
int prestera_devlink_port_register(struct prestera_port *port)
@ -482,7 +462,7 @@ struct devlink_port *prestera_devlink_get_port(struct net_device *dev)
return &port->dl_port;
}
static int prestera_devlink_traps_register(struct prestera_switch *sw)
int prestera_devlink_traps_register(struct prestera_switch *sw)
{
const u32 groups_count = ARRAY_SIZE(prestera_trap_groups_arr);
const u32 traps_count = ARRAY_SIZE(prestera_trap_items_arr);
@ -621,8 +601,9 @@ static int prestera_drop_counter_get(struct devlink *devlink,
cpu_code_type, p_drops);
}
static void prestera_devlink_traps_fini(struct prestera_switch *sw)
void prestera_devlink_traps_unregister(struct prestera_switch *sw)
{
struct prestera_trap_data *trap_data = sw->trap_data;
struct devlink *dl = priv_to_devlink(sw);
const struct devlink_trap *trap;
int i;
@ -634,4 +615,6 @@ static void prestera_devlink_traps_fini(struct prestera_switch *sw)
devlink_trap_groups_unregister(dl, prestera_trap_groups_arr,
ARRAY_SIZE(prestera_trap_groups_arr));
kfree(trap_data->trap_items_arr);
kfree(trap_data);
}

View file

@ -9,7 +9,7 @@
struct prestera_switch *prestera_devlink_alloc(struct prestera_device *dev);
void prestera_devlink_free(struct prestera_switch *sw);
int prestera_devlink_register(struct prestera_switch *sw);
void prestera_devlink_register(struct prestera_switch *sw);
void prestera_devlink_unregister(struct prestera_switch *sw);
int prestera_devlink_port_register(struct prestera_port *port);
@ -22,5 +22,7 @@ struct devlink_port *prestera_devlink_get_port(struct net_device *dev);
void prestera_devlink_trap_report(struct prestera_port *port,
struct sk_buff *skb, u8 cpu_code);
int prestera_devlink_traps_register(struct prestera_switch *sw);
void prestera_devlink_traps_unregister(struct prestera_switch *sw);
#endif /* _PRESTERA_DEVLINK_H_ */

View file

@ -851,7 +851,7 @@ static int prestera_switch_init(struct prestera_switch *sw)
if (err)
goto err_span_init;
err = prestera_devlink_register(sw);
err = prestera_devlink_traps_register(sw);
if (err)
goto err_dl_register;
@ -863,12 +863,13 @@ static int prestera_switch_init(struct prestera_switch *sw)
if (err)
goto err_ports_create;
prestera_devlink_register(sw);
return 0;
err_ports_create:
prestera_lag_fini(sw);
err_lag_init:
prestera_devlink_unregister(sw);
prestera_devlink_traps_unregister(sw);
err_dl_register:
prestera_span_fini(sw);
err_span_init:
@ -888,9 +889,10 @@ static int prestera_switch_init(struct prestera_switch *sw)
static void prestera_switch_fini(struct prestera_switch *sw)
{
prestera_devlink_unregister(sw);
prestera_destroy_ports(sw);
prestera_lag_fini(sw);
prestera_devlink_unregister(sw);
prestera_devlink_traps_unregister(sw);
prestera_span_fini(sw);
prestera_acl_fini(sw);
prestera_event_handlers_unregister(sw);

View file

@ -4015,7 +4015,6 @@ static int mlx4_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
mutex_init(&dev->persist->interface_state_mutex);
mutex_init(&dev->persist->pci_status_mutex);
devlink_register(devlink);
ret = devlink_params_register(devlink, mlx4_devlink_params,
ARRAY_SIZE(mlx4_devlink_params));
if (ret)
@ -4025,16 +4024,15 @@ static int mlx4_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
if (ret)
goto err_params_unregister;
devlink_params_publish(devlink);
devlink_reload_enable(devlink);
pci_save_state(pdev);
devlink_register(devlink);
devlink_reload_enable(devlink);
return 0;
err_params_unregister:
devlink_params_unregister(devlink, mlx4_devlink_params,
ARRAY_SIZE(mlx4_devlink_params));
err_devlink_unregister:
devlink_unregister(devlink);
kfree(dev->persist);
err_devlink_free:
devlink_free(devlink);
@ -4138,6 +4136,7 @@ static void mlx4_remove_one(struct pci_dev *pdev)
int active_vfs = 0;
devlink_reload_disable(devlink);
devlink_unregister(devlink);
if (mlx4_is_slave(dev))
persist->interface_state |= MLX4_INTERFACE_STATE_NOWAIT;
@ -4173,7 +4172,6 @@ static void mlx4_remove_one(struct pci_dev *pdev)
mlx4_pci_disable_device(dev);
devlink_params_unregister(devlink, mlx4_devlink_params,
ARRAY_SIZE(mlx4_devlink_params));
devlink_unregister(devlink);
kfree(dev->persist);
devlink_free(devlink);
}

View file

@ -793,11 +793,11 @@ int mlx5_devlink_register(struct devlink *devlink)
{
int err;
devlink_register(devlink);
err = devlink_params_register(devlink, mlx5_devlink_params,
ARRAY_SIZE(mlx5_devlink_params));
if (err)
goto params_reg_err;
return err;
mlx5_devlink_set_params_init_values(devlink);
err = mlx5_devlink_auxdev_params_register(devlink);
@ -808,7 +808,6 @@ int mlx5_devlink_register(struct devlink *devlink)
if (err)
goto traps_reg_err;
devlink_params_publish(devlink);
return 0;
traps_reg_err:
@ -816,17 +815,13 @@ int mlx5_devlink_register(struct devlink *devlink)
auxdev_reg_err:
devlink_params_unregister(devlink, mlx5_devlink_params,
ARRAY_SIZE(mlx5_devlink_params));
params_reg_err:
devlink_unregister(devlink);
return err;
}
void mlx5_devlink_unregister(struct devlink *devlink)
{
devlink_params_unpublish(devlink);
mlx5_devlink_traps_unregister(devlink);
mlx5_devlink_auxdev_params_unregister(devlink);
devlink_params_unregister(devlink, mlx5_devlink_params,
ARRAY_SIZE(mlx5_devlink_params));
devlink_unregister(devlink);
}

View file

@ -1537,6 +1537,7 @@ static int probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
dev_err(&pdev->dev, "mlx5_crdump_enable failed with error code %d\n", err);
pci_save_state(pdev);
devlink_register(devlink);
if (!mlx5_core_is_mp_slave(dev))
devlink_reload_enable(devlink);
return 0;
@ -1559,6 +1560,7 @@ static void remove_one(struct pci_dev *pdev)
struct devlink *devlink = priv_to_devlink(dev);
devlink_reload_disable(devlink);
devlink_unregister(devlink);
mlx5_crdump_disable(dev);
mlx5_drain_health_wq(dev);
mlx5_uninit_one(dev);

View file

@ -46,6 +46,7 @@ static int mlx5_sf_dev_probe(struct auxiliary_device *adev, const struct auxilia
mlx5_core_warn(mdev, "mlx5_init_one err=%d\n", err);
goto init_one_err;
}
devlink_register(devlink);
devlink_reload_enable(devlink);
return 0;
@ -65,6 +66,7 @@ static void mlx5_sf_dev_remove(struct auxiliary_device *adev)
devlink = priv_to_devlink(sf_dev->mdev);
devlink_reload_disable(devlink);
devlink_unregister(devlink);
mlx5_uninit_one(sf_dev->mdev);
iounmap(sf_dev->mdev->iseg);
mlx5_mdev_uninit(sf_dev->mdev);

View file

@ -1973,9 +1973,6 @@ __mlxsw_core_bus_device_register(const struct mlxsw_bus_info *mlxsw_bus_info,
if (err)
goto err_emad_init;
if (!reload)
devlink_register(devlink);
if (!reload) {
err = mlxsw_core_params_register(mlxsw_core);
if (err)
@ -2010,10 +2007,10 @@ __mlxsw_core_bus_device_register(const struct mlxsw_bus_info *mlxsw_bus_info,
goto err_driver_init;
}
devlink_params_publish(devlink);
if (!reload)
if (!reload) {
devlink_register(devlink);
devlink_reload_enable(devlink);
}
return 0;
@ -2030,8 +2027,6 @@ __mlxsw_core_bus_device_register(const struct mlxsw_bus_info *mlxsw_bus_info,
if (!reload)
mlxsw_core_params_unregister(mlxsw_core);
err_register_params:
if (!reload)
devlink_unregister(devlink);
mlxsw_emad_fini(mlxsw_core);
err_emad_init:
kfree(mlxsw_core->lag.mapping);
@ -2080,8 +2075,10 @@ void mlxsw_core_bus_device_unregister(struct mlxsw_core *mlxsw_core,
{
struct devlink *devlink = priv_to_devlink(mlxsw_core);
if (!reload)
if (!reload) {
devlink_reload_disable(devlink);
devlink_unregister(devlink);
}
if (devlink_is_reload_failed(devlink)) {
if (!reload)
/* Only the parts that were not de-initialized in the
@ -2092,7 +2089,6 @@ void mlxsw_core_bus_device_unregister(struct mlxsw_core *mlxsw_core,
return;
}
devlink_params_unpublish(devlink);
if (mlxsw_core->driver->fini)
mlxsw_core->driver->fini(mlxsw_core);
mlxsw_env_fini(mlxsw_core->env);
@ -2101,8 +2097,6 @@ void mlxsw_core_bus_device_unregister(struct mlxsw_core *mlxsw_core,
mlxsw_core_health_fini(mlxsw_core);
if (!reload)
mlxsw_core_params_unregister(mlxsw_core);
if (!reload)
devlink_unregister(devlink);
mlxsw_emad_fini(mlxsw_core);
kfree(mlxsw_core->lag.mapping);
mlxsw_ports_fini(mlxsw_core, reload);
@ -2116,7 +2110,6 @@ void mlxsw_core_bus_device_unregister(struct mlxsw_core *mlxsw_core,
reload_fail_deinit:
mlxsw_core_params_unregister(mlxsw_core);
devlink_unregister(devlink);
devlink_resources_unregister(devlink, NULL);
devlink_free(devlink);
}

View file

@ -1134,7 +1134,6 @@ static int mscc_ocelot_probe(struct platform_device *pdev)
if (err)
goto out_put_ports;
devlink_register(devlink);
err = mscc_ocelot_init_ports(pdev, ports);
if (err)
goto out_ocelot_devlink_unregister;
@ -1157,6 +1156,7 @@ static int mscc_ocelot_probe(struct platform_device *pdev)
register_switchdev_blocking_notifier(&ocelot_switchdev_blocking_nb);
of_node_put(ports);
devlink_register(devlink);
dev_info(&pdev->dev, "Ocelot switch probed\n");
@ -1166,7 +1166,6 @@ static int mscc_ocelot_probe(struct platform_device *pdev)
mscc_ocelot_release_ports(ocelot);
mscc_ocelot_teardown_devlink_ports(ocelot);
out_ocelot_devlink_unregister:
devlink_unregister(devlink);
ocelot_deinit(ocelot);
out_put_ports:
of_node_put(ports);
@ -1179,11 +1178,11 @@ static int mscc_ocelot_remove(struct platform_device *pdev)
{
struct ocelot *ocelot = platform_get_drvdata(pdev);
devlink_unregister(ocelot->devlink);
ocelot_deinit_timestamp(ocelot);
ocelot_devlink_sb_unregister(ocelot);
mscc_ocelot_release_ports(ocelot);
mscc_ocelot_teardown_devlink_ports(ocelot);
devlink_unregister(ocelot->devlink);
ocelot_deinit(ocelot);
unregister_switchdev_blocking_notifier(&ocelot_switchdev_blocking_nb);
unregister_switchdev_notifier(&ocelot_switchdev_nb);

View file

@ -233,13 +233,8 @@ int nfp_devlink_params_register(struct nfp_pf *pf)
if (err <= 0)
return err;
err = devlink_params_register(devlink, nfp_devlink_params,
ARRAY_SIZE(nfp_devlink_params));
if (err)
return err;
devlink_params_publish(devlink);
return 0;
return devlink_params_register(devlink, nfp_devlink_params,
ARRAY_SIZE(nfp_devlink_params));
}
void nfp_devlink_params_unregister(struct nfp_pf *pf)

View file

@ -701,7 +701,6 @@ int nfp_net_pci_probe(struct nfp_pf *pf)
if (err)
goto err_unmap;
devlink_register(devlink);
err = nfp_shared_buf_register(pf);
if (err)
goto err_devlink_unreg;
@ -731,6 +730,7 @@ int nfp_net_pci_probe(struct nfp_pf *pf)
goto err_stop_app;
mutex_unlock(&pf->lock);
devlink_register(devlink);
return 0;
@ -748,7 +748,6 @@ int nfp_net_pci_probe(struct nfp_pf *pf)
nfp_shared_buf_unregister(pf);
err_devlink_unreg:
cancel_work_sync(&pf->port_refresh_work);
devlink_unregister(devlink);
nfp_net_pf_app_clean(pf);
err_unmap:
nfp_net_pci_unmap_mem(pf);
@ -759,6 +758,7 @@ void nfp_net_pci_remove(struct nfp_pf *pf)
{
struct nfp_net *nn, *next;
devlink_unregister(priv_to_devlink(pf));
mutex_lock(&pf->lock);
list_for_each_entry_safe(nn, next, &pf->vnics, vnic_list) {
if (!nfp_net_is_data_vnic(nn))
@ -775,7 +775,6 @@ void nfp_net_pci_remove(struct nfp_pf *pf)
nfp_devlink_params_unregister(pf);
nfp_shared_buf_unregister(pf);
devlink_unregister(priv_to_devlink(pf));
nfp_net_pf_free_irqs(pf);
nfp_net_pf_app_clean(pf);

View file

@ -82,7 +82,6 @@ int ionic_devlink_register(struct ionic *ionic)
struct devlink_port_attrs attrs = {};
int err;
devlink_register(dl);
attrs.flavour = DEVLINK_PORT_FLAVOUR_PHYSICAL;
devlink_port_attrs_set(&ionic->dl_port, &attrs);
err = devlink_port_register(dl, &ionic->dl_port, 0);
@ -93,6 +92,7 @@ int ionic_devlink_register(struct ionic *ionic)
}
devlink_port_type_eth_set(&ionic->dl_port, ionic->lif->netdev);
devlink_register(dl);
return 0;
}
@ -100,6 +100,6 @@ void ionic_devlink_unregister(struct ionic *ionic)
{
struct devlink *dl = priv_to_devlink(ionic);
devlink_port_unregister(&ionic->dl_port);
devlink_unregister(dl);
devlink_port_unregister(&ionic->dl_port);
}

View file

@ -215,7 +215,6 @@ struct devlink *qed_devlink_register(struct qed_dev *cdev)
qdevlink = devlink_priv(dl);
qdevlink->cdev = cdev;
devlink_register(dl);
rc = devlink_params_register(dl, qed_devlink_params,
ARRAY_SIZE(qed_devlink_params));
if (rc)
@ -226,15 +225,13 @@ struct devlink *qed_devlink_register(struct qed_dev *cdev)
QED_DEVLINK_PARAM_ID_IWARP_CMT,
value);
devlink_params_publish(dl);
cdev->iwarp_cmt = false;
qed_fw_reporters_create(dl);
devlink_register(dl);
return dl;
err_unregister:
devlink_unregister(dl);
devlink_free(dl);
return ERR_PTR(rc);
@ -245,11 +242,11 @@ void qed_devlink_unregister(struct devlink *devlink)
if (!devlink)
return;
devlink_unregister(devlink);
qed_fw_reporters_destroy(devlink);
devlink_params_unregister(devlink, qed_devlink_params,
ARRAY_SIZE(qed_devlink_params));
devlink_unregister(devlink);
devlink_free(devlink);
}

View file

@ -2429,7 +2429,6 @@ static int am65_cpsw_nuss_register_devlink(struct am65_cpsw_common *common)
dl_priv = devlink_priv(common->devlink);
dl_priv->common = common;
devlink_register(common->devlink);
/* Provide devlink hook to switch mode when multiple external ports
* are present NUSS switchdev driver is enabled.
*/
@ -2442,7 +2441,6 @@ static int am65_cpsw_nuss_register_devlink(struct am65_cpsw_common *common)
dev_err(dev, "devlink params reg fail ret:%d\n", ret);
goto dl_unreg;
}
devlink_params_publish(common->devlink);
}
for (i = 1; i <= common->port_num; i++) {
@ -2463,7 +2461,7 @@ static int am65_cpsw_nuss_register_devlink(struct am65_cpsw_common *common)
}
devlink_port_type_eth_set(dl_port, port->ndev);
}
devlink_register(common->devlink);
return ret;
dl_port_unreg:
@ -2474,7 +2472,6 @@ static int am65_cpsw_nuss_register_devlink(struct am65_cpsw_common *common)
devlink_port_unregister(dl_port);
}
dl_unreg:
devlink_unregister(common->devlink);
devlink_free(common->devlink);
return ret;
}
@ -2485,6 +2482,8 @@ static void am65_cpsw_unregister_devlink(struct am65_cpsw_common *common)
struct am65_cpsw_port *port;
int i;
devlink_unregister(common->devlink);
for (i = 1; i <= common->port_num; i++) {
port = am65_common_get_port(common, i);
dl_port = &port->devlink_port;
@ -2493,13 +2492,11 @@ static void am65_cpsw_unregister_devlink(struct am65_cpsw_common *common)
}
if (!AM65_CPSW_IS_CPSW2G(common) &&
IS_ENABLED(CONFIG_TI_K3_AM65_CPSW_SWITCHDEV)) {
devlink_params_unpublish(common->devlink);
devlink_params_unregister(common->devlink, am65_cpsw_devlink_params,
IS_ENABLED(CONFIG_TI_K3_AM65_CPSW_SWITCHDEV))
devlink_params_unregister(common->devlink,
am65_cpsw_devlink_params,
ARRAY_SIZE(am65_cpsw_devlink_params));
}
devlink_unregister(common->devlink);
devlink_free(common->devlink);
}

View file

@ -1810,7 +1810,6 @@ static int cpsw_register_devlink(struct cpsw_common *cpsw)
dl_priv = devlink_priv(cpsw->devlink);
dl_priv->cpsw = cpsw;
devlink_register(cpsw->devlink);
ret = devlink_params_register(cpsw->devlink, cpsw_devlink_params,
ARRAY_SIZE(cpsw_devlink_params));
if (ret) {
@ -1818,21 +1817,19 @@ static int cpsw_register_devlink(struct cpsw_common *cpsw)
goto dl_unreg;
}
devlink_params_publish(cpsw->devlink);
devlink_register(cpsw->devlink);
return ret;
dl_unreg:
devlink_unregister(cpsw->devlink);
devlink_free(cpsw->devlink);
return ret;
}
static void cpsw_unregister_devlink(struct cpsw_common *cpsw)
{
devlink_params_unpublish(cpsw->devlink);
devlink_unregister(cpsw->devlink);
devlink_params_unregister(cpsw->devlink, cpsw_devlink_params,
ARRAY_SIZE(cpsw_devlink_params));
devlink_unregister(cpsw->devlink);
devlink_free(cpsw->devlink);
}

View file

@ -1470,7 +1470,6 @@ int nsim_dev_probe(struct nsim_bus_dev *nsim_bus_dev)
if (err)
goto err_devlink_free;
devlink_register(devlink);
err = devlink_params_register(devlink, nsim_devlink_params,
ARRAY_SIZE(nsim_devlink_params));
if (err)
@ -1511,9 +1510,9 @@ int nsim_dev_probe(struct nsim_bus_dev *nsim_bus_dev)
if (err)
goto err_psample_exit;
devlink_params_publish(devlink);
devlink_reload_enable(devlink);
nsim_dev->esw_mode = DEVLINK_ESWITCH_MODE_LEGACY;
devlink_register(devlink);
devlink_reload_enable(devlink);
return 0;
err_psample_exit:
@ -1534,7 +1533,6 @@ int nsim_dev_probe(struct nsim_bus_dev *nsim_bus_dev)
devlink_params_unregister(devlink, nsim_devlink_params,
ARRAY_SIZE(nsim_devlink_params));
err_dl_unregister:
devlink_unregister(devlink);
devlink_resources_unregister(devlink, NULL);
err_devlink_free:
devlink_free(devlink);
@ -1569,6 +1567,7 @@ void nsim_dev_remove(struct nsim_bus_dev *nsim_bus_dev)
struct devlink *devlink = priv_to_devlink(nsim_dev);
devlink_reload_disable(devlink);
devlink_unregister(devlink);
nsim_dev_reload_destroy(nsim_dev);
@ -1576,7 +1575,6 @@ void nsim_dev_remove(struct nsim_bus_dev *nsim_bus_dev)
nsim_dev_debugfs_exit(nsim_dev);
devlink_params_unregister(devlink, nsim_devlink_params,
ARRAY_SIZE(nsim_devlink_params));
devlink_unregister(devlink);
devlink_resources_unregister(devlink, NULL);
devlink_free(devlink);
}

View file

@ -305,7 +305,6 @@ struct iosm_devlink *ipc_devlink_init(struct iosm_imem *ipc_imem)
ipc_devlink->devlink_ctx = devlink_ctx;
ipc_devlink->pcie = ipc_imem->pcie;
ipc_devlink->dev = ipc_imem->dev;
devlink_register(devlink_ctx);
rc = devlink_params_register(devlink_ctx, iosm_devlink_params,
ARRAY_SIZE(iosm_devlink_params));
@ -315,7 +314,6 @@ struct iosm_devlink *ipc_devlink_init(struct iosm_imem *ipc_imem)
goto param_reg_fail;
}
devlink_params_publish(devlink_ctx);
ipc_devlink->cd_file_info = list;
rc = ipc_devlink_create_region(ipc_devlink);
@ -334,6 +332,7 @@ struct iosm_devlink *ipc_devlink_init(struct iosm_imem *ipc_imem)
init_completion(&ipc_devlink->devlink_sio.read_sem);
skb_queue_head_init(&ipc_devlink->devlink_sio.rx_list);
devlink_register(devlink_ctx);
dev_dbg(ipc_devlink->dev, "iosm devlink register success");
return ipc_devlink;
@ -341,7 +340,6 @@ struct iosm_devlink *ipc_devlink_init(struct iosm_imem *ipc_imem)
chnl_get_fail:
ipc_devlink_destroy_region(ipc_devlink);
region_create_fail:
devlink_params_unpublish(devlink_ctx);
devlink_params_unregister(devlink_ctx, iosm_devlink_params,
ARRAY_SIZE(iosm_devlink_params));
param_reg_fail:
@ -358,8 +356,8 @@ void ipc_devlink_deinit(struct iosm_devlink *ipc_devlink)
{
struct devlink *devlink_ctx = ipc_devlink->devlink_ctx;
devlink_unregister(devlink_ctx);
ipc_devlink_destroy_region(ipc_devlink);
devlink_params_unpublish(devlink_ctx);
devlink_params_unregister(devlink_ctx, iosm_devlink_params,
ARRAY_SIZE(iosm_devlink_params));
if (ipc_devlink->devlink_sio.devlink_read_pend) {
@ -370,6 +368,5 @@ void ipc_devlink_deinit(struct iosm_devlink *ipc_devlink)
skb_queue_purge(&ipc_devlink->devlink_sio.rx_list);
ipc_imem_sys_devlink_close(ipc_devlink);
devlink_unregister(devlink_ctx);
devlink_free(devlink_ctx);
}

View file

@ -2455,7 +2455,6 @@ ptp_ocp_probe(struct pci_dev *pdev, const struct pci_device_id *id)
return -ENOMEM;
}
devlink_register(devlink);
err = pci_enable_device(pdev);
if (err) {
dev_err(&pdev->dev, "pci_enable_device\n");
@ -2497,7 +2496,7 @@ ptp_ocp_probe(struct pci_dev *pdev, const struct pci_device_id *id)
goto out;
ptp_ocp_info(bp);
devlink_register(devlink);
return 0;
out:
@ -2506,7 +2505,6 @@ ptp_ocp_probe(struct pci_dev *pdev, const struct pci_device_id *id)
out_disable:
pci_disable_device(pdev);
out_unregister:
devlink_unregister(devlink);
devlink_free(devlink);
return err;
}
@ -2517,11 +2515,11 @@ ptp_ocp_remove(struct pci_dev *pdev)
struct ptp_ocp *bp = pci_get_drvdata(pdev);
struct devlink *devlink = priv_to_devlink(bp);
devlink_unregister(devlink);
ptp_ocp_detach(bp);
pci_set_drvdata(pdev, NULL);
pci_disable_device(pdev);
devlink_unregister(devlink);
devlink_free(devlink);
}

View file

@ -4614,10 +4614,9 @@ static int qlge_probe(struct pci_dev *pdev,
goto netdev_free;
}
devlink_register(devlink);
err = qlge_health_create_reporters(qdev);
if (err)
goto devlink_unregister;
goto netdev_free;
/* Start up the timer to trigger EEH if
* the bus goes dead
@ -4628,10 +4627,9 @@ static int qlge_probe(struct pci_dev *pdev,
qlge_display_dev_info(ndev);
atomic_set(&qdev->lb_count, 0);
cards_found++;
devlink_register(devlink);
return 0;
devlink_unregister:
devlink_unregister(devlink);
netdev_free:
free_netdev(ndev);
devlink_free:
@ -4656,13 +4654,13 @@ static void qlge_remove(struct pci_dev *pdev)
struct net_device *ndev = qdev->ndev;
struct devlink *devlink = priv_to_devlink(qdev);
devlink_unregister(devlink);
del_timer_sync(&qdev->timer);
qlge_cancel_all_work_sync(qdev);
unregister_netdev(ndev);
qlge_release_all(pdev);
pci_disable_device(pdev);
devlink_health_reporter_destroy(qdev->reporter);
devlink_unregister(devlink);
devlink_free(devlink);
free_netdev(ndev);
}

View file

@ -742,6 +742,7 @@ static void devlink_notify(struct devlink *devlink, enum devlink_command cmd)
int err;
WARN_ON(cmd != DEVLINK_CMD_NEW && cmd != DEVLINK_CMD_DEL);
WARN_ON(!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED));
msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
if (!msg)
@ -1040,11 +1041,15 @@ static int devlink_nl_port_fill(struct sk_buff *msg,
static void devlink_port_notify(struct devlink_port *devlink_port,
enum devlink_command cmd)
{
struct devlink *devlink = devlink_port->devlink;
struct sk_buff *msg;
int err;
WARN_ON(cmd != DEVLINK_CMD_PORT_NEW && cmd != DEVLINK_CMD_PORT_DEL);
if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED))
return;
msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
if (!msg)
return;
@ -1055,18 +1060,19 @@ static void devlink_port_notify(struct devlink_port *devlink_port,
return;
}
genlmsg_multicast_netns(&devlink_nl_family,
devlink_net(devlink_port->devlink), msg, 0,
DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink), msg,
0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
}
static void devlink_rate_notify(struct devlink_rate *devlink_rate,
enum devlink_command cmd)
{
struct devlink *devlink = devlink_rate->devlink;
struct sk_buff *msg;
int err;
WARN_ON(cmd != DEVLINK_CMD_RATE_NEW && cmd != DEVLINK_CMD_RATE_DEL);
WARN_ON(!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED));
msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
if (!msg)
@ -1078,9 +1084,8 @@ static void devlink_rate_notify(struct devlink_rate *devlink_rate,
return;
}
genlmsg_multicast_netns(&devlink_nl_family,
devlink_net(devlink_rate->devlink), msg, 0,
DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink), msg,
0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
}
static int devlink_nl_cmd_rate_get_dumpit(struct sk_buff *msg,
@ -4150,6 +4155,7 @@ static void __devlink_flash_update_notify(struct devlink *devlink,
WARN_ON(cmd != DEVLINK_CMD_FLASH_UPDATE &&
cmd != DEVLINK_CMD_FLASH_UPDATE_END &&
cmd != DEVLINK_CMD_FLASH_UPDATE_STATUS);
WARN_ON(!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED));
msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
if (!msg)
@ -5145,17 +5151,18 @@ static void devlink_nl_region_notify(struct devlink_region *region,
struct devlink_snapshot *snapshot,
enum devlink_command cmd)
{
struct devlink *devlink = region->devlink;
struct sk_buff *msg;
WARN_ON(cmd != DEVLINK_CMD_REGION_NEW && cmd != DEVLINK_CMD_REGION_DEL);
WARN_ON(!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED));
msg = devlink_nl_region_notify_build(region, snapshot, cmd, 0, 0);
if (IS_ERR(msg))
return;
genlmsg_multicast_netns(&devlink_nl_family,
devlink_net(region->devlink), msg, 0,
DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink), msg,
0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
}
/**
@ -6920,10 +6927,12 @@ devlink_nl_health_reporter_fill(struct sk_buff *msg,
static void devlink_recover_notify(struct devlink_health_reporter *reporter,
enum devlink_command cmd)
{
struct devlink *devlink = reporter->devlink;
struct sk_buff *msg;
int err;
WARN_ON(cmd != DEVLINK_CMD_HEALTH_REPORTER_RECOVER);
WARN_ON(!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED));
msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
if (!msg)
@ -6935,9 +6944,8 @@ static void devlink_recover_notify(struct devlink_health_reporter *reporter,
return;
}
genlmsg_multicast_netns(&devlink_nl_family,
devlink_net(reporter->devlink),
msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink), msg,
0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
}
void
@ -8955,6 +8963,68 @@ struct devlink *devlink_alloc_ns(const struct devlink_ops *ops,
}
EXPORT_SYMBOL_GPL(devlink_alloc_ns);
static void
devlink_trap_policer_notify(struct devlink *devlink,
const struct devlink_trap_policer_item *policer_item,
enum devlink_command cmd);
static void
devlink_trap_group_notify(struct devlink *devlink,
const struct devlink_trap_group_item *group_item,
enum devlink_command cmd);
static void devlink_trap_notify(struct devlink *devlink,
const struct devlink_trap_item *trap_item,
enum devlink_command cmd);
static void devlink_notify_register(struct devlink *devlink)
{
struct devlink_trap_policer_item *policer_item;
struct devlink_trap_group_item *group_item;
struct devlink_trap_item *trap_item;
struct devlink_port *devlink_port;
devlink_notify(devlink, DEVLINK_CMD_NEW);
list_for_each_entry(devlink_port, &devlink->port_list, list)
devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
list_for_each_entry(policer_item, &devlink->trap_policer_list, list)
devlink_trap_policer_notify(devlink, policer_item,
DEVLINK_CMD_TRAP_POLICER_NEW);
list_for_each_entry(group_item, &devlink->trap_group_list, list)
devlink_trap_group_notify(devlink, group_item,
DEVLINK_CMD_TRAP_GROUP_NEW);
list_for_each_entry(trap_item, &devlink->trap_list, list)
devlink_trap_notify(devlink, trap_item, DEVLINK_CMD_TRAP_NEW);
devlink_params_publish(devlink);
}
static void devlink_notify_unregister(struct devlink *devlink)
{
struct devlink_trap_policer_item *policer_item;
struct devlink_trap_group_item *group_item;
struct devlink_trap_item *trap_item;
struct devlink_port *devlink_port;
devlink_params_unpublish(devlink);
list_for_each_entry_reverse(trap_item, &devlink->trap_list, list)
devlink_trap_notify(devlink, trap_item, DEVLINK_CMD_TRAP_DEL);
list_for_each_entry_reverse(group_item, &devlink->trap_group_list, list)
devlink_trap_group_notify(devlink, group_item,
DEVLINK_CMD_TRAP_GROUP_DEL);
list_for_each_entry_reverse(policer_item, &devlink->trap_policer_list,
list)
devlink_trap_policer_notify(devlink, policer_item,
DEVLINK_CMD_TRAP_POLICER_DEL);
list_for_each_entry_reverse(devlink_port, &devlink->port_list, list)
devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_DEL);
devlink_notify(devlink, DEVLINK_CMD_DEL);
}
/**
* devlink_register - Register devlink instance
*
@ -8964,7 +9034,7 @@ void devlink_register(struct devlink *devlink)
{
mutex_lock(&devlink_mutex);
xa_set_mark(&devlinks, devlink->index, DEVLINK_REGISTERED);
devlink_notify(devlink, DEVLINK_CMD_NEW);
devlink_notify_register(devlink);
mutex_unlock(&devlink_mutex);
}
EXPORT_SYMBOL_GPL(devlink_register);
@ -8982,7 +9052,7 @@ void devlink_unregister(struct devlink *devlink)
mutex_lock(&devlink_mutex);
WARN_ON(devlink_reload_supported(devlink->ops) &&
devlink->reload_enabled);
devlink_notify(devlink, DEVLINK_CMD_DEL);
devlink_notify_unregister(devlink);
xa_clear_mark(&devlinks, devlink->index, DEVLINK_REGISTERED);
mutex_unlock(&devlink_mutex);
}
@ -10086,6 +10156,9 @@ void devlink_params_publish(struct devlink *devlink)
{
struct devlink_param_item *param_item;
if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED))
return;
list_for_each_entry(param_item, &devlink->param_list, list) {
if (param_item->published)
continue;
@ -10631,6 +10704,8 @@ devlink_trap_group_notify(struct devlink *devlink,
WARN_ON_ONCE(cmd != DEVLINK_CMD_TRAP_GROUP_NEW &&
cmd != DEVLINK_CMD_TRAP_GROUP_DEL);
if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED))
return;
msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
if (!msg)
@ -10672,6 +10747,8 @@ static void devlink_trap_notify(struct devlink *devlink,
WARN_ON_ONCE(cmd != DEVLINK_CMD_TRAP_NEW &&
cmd != DEVLINK_CMD_TRAP_DEL);
if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED))
return;
msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
if (!msg)
@ -11053,6 +11130,8 @@ devlink_trap_policer_notify(struct devlink *devlink,
WARN_ON_ONCE(cmd != DEVLINK_CMD_TRAP_POLICER_NEW &&
cmd != DEVLINK_CMD_TRAP_POLICER_DEL);
if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED))
return;
msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
if (!msg)

View file

@ -848,7 +848,6 @@ static int dsa_switch_setup(struct dsa_switch *ds)
dl_priv = devlink_priv(ds->devlink);
dl_priv->ds = ds;
devlink_register(ds->devlink);
/* Setup devlink port instances now, so that the switch
* setup() can register regions etc, against the ports
*/
@ -874,8 +873,6 @@ static int dsa_switch_setup(struct dsa_switch *ds)
if (err)
goto teardown;
devlink_params_publish(ds->devlink);
if (!ds->slave_mii_bus && ds->ops->phy_read) {
ds->slave_mii_bus = mdiobus_alloc();
if (!ds->slave_mii_bus) {
@ -891,7 +888,7 @@ static int dsa_switch_setup(struct dsa_switch *ds)
}
ds->setup = true;
devlink_register(ds->devlink);
return 0;
free_slave_mii_bus:
@ -906,7 +903,6 @@ static int dsa_switch_setup(struct dsa_switch *ds)
list_for_each_entry(dp, &ds->dst->ports, list)
if (dp->ds == ds)
dsa_port_devlink_teardown(dp);
devlink_unregister(ds->devlink);
devlink_free(ds->devlink);
ds->devlink = NULL;
return err;
@ -919,6 +915,9 @@ static void dsa_switch_teardown(struct dsa_switch *ds)
if (!ds->setup)
return;
if (ds->devlink)
devlink_unregister(ds->devlink);
if (ds->slave_mii_bus && ds->ops->phy_read) {
mdiobus_unregister(ds->slave_mii_bus);
mdiobus_free(ds->slave_mii_bus);
@ -934,7 +933,6 @@ static void dsa_switch_teardown(struct dsa_switch *ds)
list_for_each_entry(dp, &ds->dst->ports, list)
if (dp->ds == ds)
dsa_port_devlink_teardown(dp);
devlink_unregister(ds->devlink);
devlink_free(ds->devlink);
ds->devlink = NULL;
}