devlink: Set device as early as possible

All kernel devlink implementations call to devlink_alloc() during
initialization routine for specific device which is used later as
a parent device for devlink_register().

Such late device assignment causes to the situation which requires us to
call to device_register() before setting other parameters, but that call
opens devlink to the world and makes accessible for the netlink users.

Any attempt to move devlink_register() to be the last call generates the
following error due to access to the devlink->dev pointer.

[    8.758862]  devlink_nl_param_fill+0x2e8/0xe50
[    8.760305]  devlink_param_notify+0x6d/0x180
[    8.760435]  __devlink_params_register+0x2f1/0x670
[    8.760558]  devlink_params_register+0x1e/0x20

The simple change of API to set devlink device in the devlink_alloc()
instead of devlink_register() fixes all this above and ensures that
prior to call to devlink_register() everything already set.

Signed-off-by: Leon Romanovsky <leonro@nvidia.com>
Reviewed-by: Jiri Pirko <jiri@nvidia.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Leon Romanovsky 2021-08-08 21:57:43 +03:00 committed by David S. Miller
parent 94c0a6fbd5
commit 919d13a7e4
33 changed files with 91 additions and 94 deletions

View file

@ -743,14 +743,17 @@ static void bnxt_dl_params_unregister(struct bnxt *bp)
int bnxt_dl_register(struct bnxt *bp) int bnxt_dl_register(struct bnxt *bp)
{ {
const struct devlink_ops *devlink_ops;
struct devlink_port_attrs attrs = {}; struct devlink_port_attrs attrs = {};
struct devlink *dl; struct devlink *dl;
int rc; int rc;
if (BNXT_PF(bp)) if (BNXT_PF(bp))
dl = devlink_alloc(&bnxt_dl_ops, sizeof(struct bnxt_dl)); devlink_ops = &bnxt_dl_ops;
else else
dl = devlink_alloc(&bnxt_vf_dl_ops, sizeof(struct bnxt_dl)); devlink_ops = &bnxt_vf_dl_ops;
dl = devlink_alloc(devlink_ops, sizeof(struct bnxt_dl), &bp->pdev->dev);
if (!dl) { if (!dl) {
netdev_warn(bp->dev, "devlink_alloc failed\n"); netdev_warn(bp->dev, "devlink_alloc failed\n");
return -ENOMEM; return -ENOMEM;
@ -763,7 +766,7 @@ int bnxt_dl_register(struct bnxt *bp)
bp->hwrm_spec_code > 0x10803) bp->hwrm_spec_code > 0x10803)
bp->eswitch_mode = DEVLINK_ESWITCH_MODE_LEGACY; bp->eswitch_mode = DEVLINK_ESWITCH_MODE_LEGACY;
rc = devlink_register(dl, &bp->pdev->dev); rc = devlink_register(dl);
if (rc) { if (rc) {
netdev_warn(bp->dev, "devlink_register failed. rc=%d\n", rc); netdev_warn(bp->dev, "devlink_register failed. rc=%d\n", rc);
goto err_dl_free; goto err_dl_free;

View file

@ -3750,7 +3750,8 @@ static int setup_nic_devices(struct octeon_device *octeon_dev)
} }
devlink = devlink_alloc(&liquidio_devlink_ops, devlink = devlink_alloc(&liquidio_devlink_ops,
sizeof(struct lio_devlink_priv)); sizeof(struct lio_devlink_priv),
&octeon_dev->pci_dev->dev);
if (!devlink) { if (!devlink) {
dev_err(&octeon_dev->pci_dev->dev, "devlink alloc failed\n"); dev_err(&octeon_dev->pci_dev->dev, "devlink alloc failed\n");
goto setup_nic_dev_free; goto setup_nic_dev_free;
@ -3759,7 +3760,7 @@ static int setup_nic_devices(struct octeon_device *octeon_dev)
lio_devlink = devlink_priv(devlink); lio_devlink = devlink_priv(devlink);
lio_devlink->oct = octeon_dev; lio_devlink->oct = octeon_dev;
if (devlink_register(devlink, &octeon_dev->pci_dev->dev)) { if (devlink_register(devlink)) {
devlink_free(devlink); devlink_free(devlink);
dev_err(&octeon_dev->pci_dev->dev, dev_err(&octeon_dev->pci_dev->dev,
"devlink registration failed\n"); "devlink registration failed\n");

View file

@ -196,7 +196,8 @@ int dpaa2_eth_dl_register(struct dpaa2_eth_priv *priv)
struct dpaa2_eth_devlink_priv *dl_priv; struct dpaa2_eth_devlink_priv *dl_priv;
int err; int err;
priv->devlink = devlink_alloc(&dpaa2_eth_devlink_ops, sizeof(*dl_priv)); priv->devlink =
devlink_alloc(&dpaa2_eth_devlink_ops, sizeof(*dl_priv), dev);
if (!priv->devlink) { if (!priv->devlink) {
dev_err(dev, "devlink_alloc failed\n"); dev_err(dev, "devlink_alloc failed\n");
return -ENOMEM; return -ENOMEM;
@ -204,7 +205,7 @@ int dpaa2_eth_dl_register(struct dpaa2_eth_priv *priv)
dl_priv = devlink_priv(priv->devlink); dl_priv = devlink_priv(priv->devlink);
dl_priv->dpaa2_priv = priv; dl_priv->dpaa2_priv = priv;
err = devlink_register(priv->devlink, dev); err = devlink_register(priv->devlink);
if (err) { if (err) {
dev_err(dev, "devlink_register() = %d\n", err); dev_err(dev, "devlink_register() = %d\n", err);
goto devlink_free; goto devlink_free;

View file

@ -112,14 +112,14 @@ int hclge_devlink_init(struct hclge_dev *hdev)
int ret; int ret;
devlink = devlink_alloc(&hclge_devlink_ops, devlink = devlink_alloc(&hclge_devlink_ops,
sizeof(struct hclge_devlink_priv)); sizeof(struct hclge_devlink_priv), &pdev->dev);
if (!devlink) if (!devlink)
return -ENOMEM; return -ENOMEM;
priv = devlink_priv(devlink); priv = devlink_priv(devlink);
priv->hdev = hdev; priv->hdev = hdev;
ret = devlink_register(devlink, &pdev->dev); ret = devlink_register(devlink);
if (ret) { if (ret) {
dev_err(&pdev->dev, "failed to register devlink, ret = %d\n", dev_err(&pdev->dev, "failed to register devlink, ret = %d\n",
ret); ret);

View file

@ -112,15 +112,16 @@ int hclgevf_devlink_init(struct hclgevf_dev *hdev)
struct devlink *devlink; struct devlink *devlink;
int ret; int ret;
devlink = devlink_alloc(&hclgevf_devlink_ops, devlink =
sizeof(struct hclgevf_devlink_priv)); devlink_alloc(&hclgevf_devlink_ops,
sizeof(struct hclgevf_devlink_priv), &pdev->dev);
if (!devlink) if (!devlink)
return -ENOMEM; return -ENOMEM;
priv = devlink_priv(devlink); priv = devlink_priv(devlink);
priv->hdev = hdev; priv->hdev = hdev;
ret = devlink_register(devlink, &pdev->dev); ret = devlink_register(devlink);
if (ret) { if (ret) {
dev_err(&pdev->dev, "failed to register devlink, ret = %d\n", dev_err(&pdev->dev, "failed to register devlink, ret = %d\n",
ret); ret);

View file

@ -293,9 +293,9 @@ static const struct devlink_ops hinic_devlink_ops = {
.flash_update = hinic_devlink_flash_update, .flash_update = hinic_devlink_flash_update,
}; };
struct devlink *hinic_devlink_alloc(void) struct devlink *hinic_devlink_alloc(struct device *dev)
{ {
return devlink_alloc(&hinic_devlink_ops, sizeof(struct hinic_dev)); return devlink_alloc(&hinic_devlink_ops, sizeof(struct hinic_dev), dev);
} }
void hinic_devlink_free(struct devlink *devlink) void hinic_devlink_free(struct devlink *devlink)
@ -303,11 +303,11 @@ void hinic_devlink_free(struct devlink *devlink)
devlink_free(devlink); devlink_free(devlink);
} }
int hinic_devlink_register(struct hinic_devlink_priv *priv, struct device *dev) int hinic_devlink_register(struct hinic_devlink_priv *priv)
{ {
struct devlink *devlink = priv_to_devlink(priv); struct devlink *devlink = priv_to_devlink(priv);
return devlink_register(devlink, dev); return devlink_register(devlink);
} }
void hinic_devlink_unregister(struct hinic_devlink_priv *priv) void hinic_devlink_unregister(struct hinic_devlink_priv *priv)

View file

@ -108,9 +108,9 @@ struct host_image_st {
u32 device_id; u32 device_id;
}; };
struct devlink *hinic_devlink_alloc(void); struct devlink *hinic_devlink_alloc(struct device *dev);
void hinic_devlink_free(struct devlink *devlink); void hinic_devlink_free(struct devlink *devlink);
int hinic_devlink_register(struct hinic_devlink_priv *priv, struct device *dev); int hinic_devlink_register(struct hinic_devlink_priv *priv);
void hinic_devlink_unregister(struct hinic_devlink_priv *priv); void hinic_devlink_unregister(struct hinic_devlink_priv *priv);
int hinic_health_reporters_create(struct hinic_devlink_priv *priv); int hinic_health_reporters_create(struct hinic_devlink_priv *priv);

View file

@ -754,7 +754,7 @@ static int init_pfhwdev(struct hinic_pfhwdev *pfhwdev)
return err; return err;
} }
err = hinic_devlink_register(hwdev->devlink_dev, &pdev->dev); err = hinic_devlink_register(hwdev->devlink_dev);
if (err) { if (err) {
dev_err(&hwif->pdev->dev, "Failed to register devlink\n"); dev_err(&hwif->pdev->dev, "Failed to register devlink\n");
hinic_pf_to_mgmt_free(&pfhwdev->pf_to_mgmt); hinic_pf_to_mgmt_free(&pfhwdev->pf_to_mgmt);

View file

@ -1183,7 +1183,7 @@ static int nic_dev_init(struct pci_dev *pdev)
struct devlink *devlink; struct devlink *devlink;
int err, num_qps; int err, num_qps;
devlink = hinic_devlink_alloc(); devlink = hinic_devlink_alloc(&pdev->dev);
if (!devlink) { if (!devlink) {
dev_err(&pdev->dev, "Hinic devlink alloc failed\n"); dev_err(&pdev->dev, "Hinic devlink alloc failed\n");
return -ENOMEM; return -ENOMEM;

View file

@ -475,7 +475,7 @@ struct ice_pf *ice_allocate_pf(struct device *dev)
{ {
struct devlink *devlink; struct devlink *devlink;
devlink = devlink_alloc(&ice_devlink_ops, sizeof(struct ice_pf)); devlink = devlink_alloc(&ice_devlink_ops, sizeof(struct ice_pf), dev);
if (!devlink) if (!devlink)
return NULL; return NULL;
@ -502,7 +502,7 @@ int ice_devlink_register(struct ice_pf *pf)
struct device *dev = ice_pf_to_dev(pf); struct device *dev = ice_pf_to_dev(pf);
int err; int err;
err = devlink_register(devlink, dev); err = devlink_register(devlink);
if (err) { if (err) {
dev_err(dev, "devlink registration failed: %d\n", err); dev_err(dev, "devlink registration failed: %d\n", err);
return err; return err;

View file

@ -1503,13 +1503,14 @@ int rvu_register_dl(struct rvu *rvu)
struct devlink *dl; struct devlink *dl;
int err; int err;
dl = devlink_alloc(&rvu_devlink_ops, sizeof(struct rvu_devlink)); dl = devlink_alloc(&rvu_devlink_ops, sizeof(struct rvu_devlink),
rvu->dev);
if (!dl) { if (!dl) {
dev_warn(rvu->dev, "devlink_alloc failed\n"); dev_warn(rvu->dev, "devlink_alloc failed\n");
return -ENOMEM; return -ENOMEM;
} }
err = devlink_register(dl, rvu->dev); err = devlink_register(dl);
if (err) { if (err) {
dev_err(rvu->dev, "devlink register failed with error %d\n", err); dev_err(rvu->dev, "devlink register failed with error %d\n", err);
devlink_free(dl); devlink_free(dl);

View file

@ -390,11 +390,12 @@ static const struct devlink_ops prestera_dl_ops = {
.trap_drop_counter_get = prestera_drop_counter_get, .trap_drop_counter_get = prestera_drop_counter_get,
}; };
struct prestera_switch *prestera_devlink_alloc(void) struct prestera_switch *prestera_devlink_alloc(struct prestera_device *dev)
{ {
struct devlink *dl; struct devlink *dl;
dl = devlink_alloc(&prestera_dl_ops, sizeof(struct prestera_switch)); dl = devlink_alloc(&prestera_dl_ops, sizeof(struct prestera_switch),
dev->dev);
return devlink_priv(dl); return devlink_priv(dl);
} }
@ -411,7 +412,7 @@ int prestera_devlink_register(struct prestera_switch *sw)
struct devlink *dl = priv_to_devlink(sw); struct devlink *dl = priv_to_devlink(sw);
int err; int err;
err = devlink_register(dl, sw->dev->dev); err = devlink_register(dl);
if (err) { if (err) {
dev_err(prestera_dev(sw), "devlink_register failed: %d\n", err); dev_err(prestera_dev(sw), "devlink_register failed: %d\n", err);
return err; return err;

View file

@ -6,7 +6,7 @@
#include "prestera.h" #include "prestera.h"
struct prestera_switch *prestera_devlink_alloc(void); struct prestera_switch *prestera_devlink_alloc(struct prestera_device *dev);
void prestera_devlink_free(struct prestera_switch *sw); void prestera_devlink_free(struct prestera_switch *sw);
int prestera_devlink_register(struct prestera_switch *sw); int prestera_devlink_register(struct prestera_switch *sw);

View file

@ -905,7 +905,7 @@ int prestera_device_register(struct prestera_device *dev)
struct prestera_switch *sw; struct prestera_switch *sw;
int err; int err;
sw = prestera_devlink_alloc(); sw = prestera_devlink_alloc(dev);
if (!sw) if (!sw)
return -ENOMEM; return -ENOMEM;

View file

@ -4005,7 +4005,7 @@ static int mlx4_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
printk_once(KERN_INFO "%s", mlx4_version); printk_once(KERN_INFO "%s", mlx4_version);
devlink = devlink_alloc(&mlx4_devlink_ops, sizeof(*priv)); devlink = devlink_alloc(&mlx4_devlink_ops, sizeof(*priv), &pdev->dev);
if (!devlink) if (!devlink)
return -ENOMEM; return -ENOMEM;
priv = devlink_priv(devlink); priv = devlink_priv(devlink);
@ -4024,7 +4024,7 @@ 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->interface_state_mutex);
mutex_init(&dev->persist->pci_status_mutex); mutex_init(&dev->persist->pci_status_mutex);
ret = devlink_register(devlink, &pdev->dev); ret = devlink_register(devlink);
if (ret) if (ret)
goto err_persist_free; goto err_persist_free;
ret = devlink_params_register(devlink, mlx4_devlink_params, ret = devlink_params_register(devlink, mlx4_devlink_params,

View file

@ -359,9 +359,10 @@ int mlx5_devlink_traps_get_action(struct mlx5_core_dev *dev, int trap_id,
return 0; return 0;
} }
struct devlink *mlx5_devlink_alloc(void) struct devlink *mlx5_devlink_alloc(struct device *dev)
{ {
return devlink_alloc(&mlx5_devlink_ops, sizeof(struct mlx5_core_dev)); return devlink_alloc(&mlx5_devlink_ops, sizeof(struct mlx5_core_dev),
dev);
} }
void mlx5_devlink_free(struct devlink *devlink) void mlx5_devlink_free(struct devlink *devlink)
@ -638,11 +639,11 @@ static void mlx5_devlink_traps_unregister(struct devlink *devlink)
ARRAY_SIZE(mlx5_trap_groups_arr)); ARRAY_SIZE(mlx5_trap_groups_arr));
} }
int mlx5_devlink_register(struct devlink *devlink, struct device *dev) int mlx5_devlink_register(struct devlink *devlink)
{ {
int err; int err;
err = devlink_register(devlink, dev); err = devlink_register(devlink);
if (err) if (err)
return err; return err;

View file

@ -31,9 +31,9 @@ int mlx5_devlink_trap_get_num_active(struct mlx5_core_dev *dev);
int mlx5_devlink_traps_get_action(struct mlx5_core_dev *dev, int trap_id, int mlx5_devlink_traps_get_action(struct mlx5_core_dev *dev, int trap_id,
enum devlink_trap_action *action); enum devlink_trap_action *action);
struct devlink *mlx5_devlink_alloc(void); struct devlink *mlx5_devlink_alloc(struct device *dev);
void mlx5_devlink_free(struct devlink *devlink); void mlx5_devlink_free(struct devlink *devlink);
int mlx5_devlink_register(struct devlink *devlink, struct device *dev); int mlx5_devlink_register(struct devlink *devlink);
void mlx5_devlink_unregister(struct devlink *devlink); void mlx5_devlink_unregister(struct devlink *devlink);
#endif /* __MLX5_DEVLINK_H__ */ #endif /* __MLX5_DEVLINK_H__ */

View file

@ -1271,7 +1271,7 @@ int mlx5_init_one(struct mlx5_core_dev *dev)
set_bit(MLX5_INTERFACE_STATE_UP, &dev->intf_state); set_bit(MLX5_INTERFACE_STATE_UP, &dev->intf_state);
err = mlx5_devlink_register(priv_to_devlink(dev), dev->device); err = mlx5_devlink_register(priv_to_devlink(dev));
if (err) if (err)
goto err_devlink_reg; goto err_devlink_reg;
@ -1452,7 +1452,7 @@ static int probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
struct devlink *devlink; struct devlink *devlink;
int err; int err;
devlink = mlx5_devlink_alloc(); devlink = mlx5_devlink_alloc(&pdev->dev);
if (!devlink) { if (!devlink) {
dev_err(&pdev->dev, "devlink alloc failed\n"); dev_err(&pdev->dev, "devlink alloc failed\n");
return -ENOMEM; return -ENOMEM;

View file

@ -14,7 +14,7 @@ static int mlx5_sf_dev_probe(struct auxiliary_device *adev, const struct auxilia
struct devlink *devlink; struct devlink *devlink;
int err; int err;
devlink = mlx5_devlink_alloc(); devlink = mlx5_devlink_alloc(&adev->dev);
if (!devlink) if (!devlink)
return -ENOMEM; return -ENOMEM;

View file

@ -1927,7 +1927,8 @@ __mlxsw_core_bus_device_register(const struct mlxsw_bus_info *mlxsw_bus_info,
if (!reload) { if (!reload) {
alloc_size = sizeof(*mlxsw_core) + mlxsw_driver->priv_size; alloc_size = sizeof(*mlxsw_core) + mlxsw_driver->priv_size;
devlink = devlink_alloc(&mlxsw_devlink_ops, alloc_size); devlink = devlink_alloc(&mlxsw_devlink_ops, alloc_size,
mlxsw_bus_info->dev);
if (!devlink) { if (!devlink) {
err = -ENOMEM; err = -ENOMEM;
goto err_devlink_alloc; goto err_devlink_alloc;
@ -1974,7 +1975,7 @@ __mlxsw_core_bus_device_register(const struct mlxsw_bus_info *mlxsw_bus_info,
goto err_emad_init; goto err_emad_init;
if (!reload) { if (!reload) {
err = devlink_register(devlink, mlxsw_bus_info->dev); err = devlink_register(devlink);
if (err) if (err)
goto err_devlink_register; goto err_devlink_register;
} }

View file

@ -1103,7 +1103,8 @@ static int mscc_ocelot_probe(struct platform_device *pdev)
if (!np && !pdev->dev.platform_data) if (!np && !pdev->dev.platform_data)
return -ENODEV; return -ENODEV;
devlink = devlink_alloc(&ocelot_devlink_ops, sizeof(*ocelot)); devlink =
devlink_alloc(&ocelot_devlink_ops, sizeof(*ocelot), &pdev->dev);
if (!devlink) if (!devlink)
return -ENOMEM; return -ENOMEM;
@ -1187,7 +1188,7 @@ static int mscc_ocelot_probe(struct platform_device *pdev)
if (err) if (err)
goto out_put_ports; goto out_put_ports;
err = devlink_register(devlink, ocelot->dev); err = devlink_register(devlink);
if (err) if (err)
goto out_ocelot_deinit; goto out_ocelot_deinit;

View file

@ -692,7 +692,7 @@ static int nfp_pci_probe(struct pci_dev *pdev,
goto err_pci_disable; goto err_pci_disable;
} }
devlink = devlink_alloc(&nfp_devlink_ops, sizeof(*pf)); devlink = devlink_alloc(&nfp_devlink_ops, sizeof(*pf), &pdev->dev);
if (!devlink) { if (!devlink) {
err = -ENOMEM; err = -ENOMEM;
goto err_rel_regions; goto err_rel_regions;

View file

@ -701,7 +701,7 @@ int nfp_net_pci_probe(struct nfp_pf *pf)
if (err) if (err)
goto err_unmap; goto err_unmap;
err = devlink_register(devlink, &pf->pdev->dev); err = devlink_register(devlink);
if (err) if (err)
goto err_app_clean; goto err_app_clean;

View file

@ -64,7 +64,7 @@ struct ionic *ionic_devlink_alloc(struct device *dev)
{ {
struct devlink *dl; struct devlink *dl;
dl = devlink_alloc(&ionic_dl_ops, sizeof(struct ionic)); dl = devlink_alloc(&ionic_dl_ops, sizeof(struct ionic), dev);
return devlink_priv(dl); return devlink_priv(dl);
} }
@ -82,7 +82,7 @@ int ionic_devlink_register(struct ionic *ionic)
struct devlink_port_attrs attrs = {}; struct devlink_port_attrs attrs = {};
int err; int err;
err = devlink_register(dl, ionic->dev); err = devlink_register(dl);
if (err) { if (err) {
dev_warn(ionic->dev, "devlink_register failed: %d\n", err); dev_warn(ionic->dev, "devlink_register failed: %d\n", err);
return err; return err;

View file

@ -207,14 +207,15 @@ struct devlink *qed_devlink_register(struct qed_dev *cdev)
struct devlink *dl; struct devlink *dl;
int rc; int rc;
dl = devlink_alloc(&qed_dl_ops, sizeof(struct qed_devlink)); dl = devlink_alloc(&qed_dl_ops, sizeof(struct qed_devlink),
&cdev->pdev->dev);
if (!dl) if (!dl)
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
qdevlink = devlink_priv(dl); qdevlink = devlink_priv(dl);
qdevlink->cdev = cdev; qdevlink->cdev = cdev;
rc = devlink_register(dl, &cdev->pdev->dev); rc = devlink_register(dl);
if (rc) if (rc)
goto err_free; goto err_free;

View file

@ -2422,14 +2422,14 @@ static int am65_cpsw_nuss_register_devlink(struct am65_cpsw_common *common)
int i; int i;
common->devlink = common->devlink =
devlink_alloc(&am65_cpsw_devlink_ops, sizeof(*dl_priv)); devlink_alloc(&am65_cpsw_devlink_ops, sizeof(*dl_priv), dev);
if (!common->devlink) if (!common->devlink)
return -ENOMEM; return -ENOMEM;
dl_priv = devlink_priv(common->devlink); dl_priv = devlink_priv(common->devlink);
dl_priv->common = common; dl_priv->common = common;
ret = devlink_register(common->devlink, dev); ret = devlink_register(common->devlink);
if (ret) { if (ret) {
dev_err(dev, "devlink reg fail ret:%d\n", ret); dev_err(dev, "devlink reg fail ret:%d\n", ret);
goto dl_free; goto dl_free;

View file

@ -1800,14 +1800,14 @@ static int cpsw_register_devlink(struct cpsw_common *cpsw)
struct cpsw_devlink *dl_priv; struct cpsw_devlink *dl_priv;
int ret = 0; int ret = 0;
cpsw->devlink = devlink_alloc(&cpsw_devlink_ops, sizeof(*dl_priv)); cpsw->devlink = devlink_alloc(&cpsw_devlink_ops, sizeof(*dl_priv), dev);
if (!cpsw->devlink) if (!cpsw->devlink)
return -ENOMEM; return -ENOMEM;
dl_priv = devlink_priv(cpsw->devlink); dl_priv = devlink_priv(cpsw->devlink);
dl_priv->cpsw = cpsw; dl_priv->cpsw = cpsw;
ret = devlink_register(cpsw->devlink, dev); ret = devlink_register(cpsw->devlink);
if (ret) { if (ret) {
dev_err(dev, "DL reg fail ret:%d\n", ret); dev_err(dev, "DL reg fail ret:%d\n", ret);
goto dl_free; goto dl_free;

View file

@ -1449,7 +1449,7 @@ int nsim_dev_probe(struct nsim_bus_dev *nsim_bus_dev)
int err; int err;
devlink = devlink_alloc_ns(&nsim_dev_devlink_ops, sizeof(*nsim_dev), devlink = devlink_alloc_ns(&nsim_dev_devlink_ops, sizeof(*nsim_dev),
nsim_bus_dev->initial_net); nsim_bus_dev->initial_net, &nsim_bus_dev->dev);
if (!devlink) if (!devlink)
return -ENOMEM; return -ENOMEM;
nsim_dev = devlink_priv(devlink); nsim_dev = devlink_priv(devlink);
@ -1470,7 +1470,7 @@ int nsim_dev_probe(struct nsim_bus_dev *nsim_bus_dev)
if (err) if (err)
goto err_devlink_free; goto err_devlink_free;
err = devlink_register(devlink, &nsim_bus_dev->dev); err = devlink_register(devlink);
if (err) if (err)
goto err_resources_unregister; goto err_resources_unregister;

View file

@ -735,24 +735,6 @@ ptp_ocp_info(struct ptp_ocp *bp)
ptp_ocp_tod_info(bp); ptp_ocp_tod_info(bp);
} }
static int
ptp_ocp_devlink_register(struct devlink *devlink, struct device *dev)
{
int err;
err = devlink_register(devlink, dev);
if (err)
return err;
return 0;
}
static void
ptp_ocp_devlink_unregister(struct devlink *devlink)
{
devlink_unregister(devlink);
}
static struct device * static struct device *
ptp_ocp_find_flash(struct ptp_ocp *bp) ptp_ocp_find_flash(struct ptp_ocp *bp)
{ {
@ -1437,13 +1419,13 @@ ptp_ocp_probe(struct pci_dev *pdev, const struct pci_device_id *id)
struct ptp_ocp *bp; struct ptp_ocp *bp;
int err; int err;
devlink = devlink_alloc(&ptp_ocp_devlink_ops, sizeof(*bp)); devlink = devlink_alloc(&ptp_ocp_devlink_ops, sizeof(*bp), &pdev->dev);
if (!devlink) { if (!devlink) {
dev_err(&pdev->dev, "devlink_alloc failed\n"); dev_err(&pdev->dev, "devlink_alloc failed\n");
return -ENOMEM; return -ENOMEM;
} }
err = ptp_ocp_devlink_register(devlink, &pdev->dev); err = devlink_register(devlink);
if (err) if (err)
goto out_free; goto out_free;
@ -1497,7 +1479,7 @@ out:
pci_disable_device(pdev); pci_disable_device(pdev);
pci_set_drvdata(pdev, NULL); pci_set_drvdata(pdev, NULL);
out_unregister: out_unregister:
ptp_ocp_devlink_unregister(devlink); devlink_unregister(devlink);
out_free: out_free:
devlink_free(devlink); devlink_free(devlink);
@ -1514,7 +1496,7 @@ ptp_ocp_remove(struct pci_dev *pdev)
pci_disable_device(pdev); pci_disable_device(pdev);
pci_set_drvdata(pdev, NULL); pci_set_drvdata(pdev, NULL);
ptp_ocp_devlink_unregister(devlink); devlink_unregister(devlink);
devlink_free(devlink); devlink_free(devlink);
} }

View file

@ -4547,7 +4547,8 @@ static int qlge_probe(struct pci_dev *pdev,
static int cards_found; static int cards_found;
int err; int err;
devlink = devlink_alloc(&qlge_devlink_ops, sizeof(struct qlge_adapter)); devlink = devlink_alloc(&qlge_devlink_ops, sizeof(struct qlge_adapter),
&pdev->dev);
if (!devlink) if (!devlink)
return -ENOMEM; return -ENOMEM;
@ -4613,7 +4614,7 @@ static int qlge_probe(struct pci_dev *pdev,
goto netdev_free; goto netdev_free;
} }
err = devlink_register(devlink, &pdev->dev); err = devlink_register(devlink);
if (err) if (err)
goto netdev_free; goto netdev_free;

View file

@ -1544,13 +1544,15 @@ struct net *devlink_net(const struct devlink *devlink);
* Drivers that operate on real HW must use devlink_alloc() instead. * Drivers that operate on real HW must use devlink_alloc() instead.
*/ */
struct devlink *devlink_alloc_ns(const struct devlink_ops *ops, struct devlink *devlink_alloc_ns(const struct devlink_ops *ops,
size_t priv_size, struct net *net); size_t priv_size, struct net *net,
struct device *dev);
static inline struct devlink *devlink_alloc(const struct devlink_ops *ops, static inline struct devlink *devlink_alloc(const struct devlink_ops *ops,
size_t priv_size) size_t priv_size,
struct device *dev)
{ {
return devlink_alloc_ns(ops, priv_size, &init_net); return devlink_alloc_ns(ops, priv_size, &init_net, dev);
} }
int devlink_register(struct devlink *devlink, struct device *dev); int devlink_register(struct devlink *devlink);
void devlink_unregister(struct devlink *devlink); void devlink_unregister(struct devlink *devlink);
void devlink_reload_enable(struct devlink *devlink); void devlink_reload_enable(struct devlink *devlink);
void devlink_reload_disable(struct devlink *devlink); void devlink_reload_disable(struct devlink *devlink);

View file

@ -8768,24 +8768,26 @@ static bool devlink_reload_actions_valid(const struct devlink_ops *ops)
* @ops: ops * @ops: ops
* @priv_size: size of user private data * @priv_size: size of user private data
* @net: net namespace * @net: net namespace
* @dev: parent device
* *
* Allocate new devlink instance resources, including devlink index * Allocate new devlink instance resources, including devlink index
* and name. * and name.
*/ */
struct devlink *devlink_alloc_ns(const struct devlink_ops *ops, struct devlink *devlink_alloc_ns(const struct devlink_ops *ops,
size_t priv_size, struct net *net) size_t priv_size, struct net *net,
struct device *dev)
{ {
struct devlink *devlink; struct devlink *devlink;
if (WARN_ON(!ops)) WARN_ON(!ops || !dev);
return NULL;
if (!devlink_reload_actions_valid(ops)) if (!devlink_reload_actions_valid(ops))
return NULL; return NULL;
devlink = kzalloc(sizeof(*devlink) + priv_size, GFP_KERNEL); devlink = kzalloc(sizeof(*devlink) + priv_size, GFP_KERNEL);
if (!devlink) if (!devlink)
return NULL; return NULL;
devlink->dev = dev;
devlink->ops = ops; devlink->ops = ops;
xa_init_flags(&devlink->snapshot_ids, XA_FLAGS_ALLOC); xa_init_flags(&devlink->snapshot_ids, XA_FLAGS_ALLOC);
write_pnet(&devlink->_net, net); write_pnet(&devlink->_net, net);
@ -8810,12 +8812,9 @@ EXPORT_SYMBOL_GPL(devlink_alloc_ns);
* devlink_register - Register devlink instance * devlink_register - Register devlink instance
* *
* @devlink: devlink * @devlink: devlink
* @dev: parent device
*/ */
int devlink_register(struct devlink *devlink, struct device *dev) int devlink_register(struct devlink *devlink)
{ {
WARN_ON(devlink->dev);
devlink->dev = dev;
mutex_lock(&devlink_mutex); mutex_lock(&devlink_mutex);
list_add_tail(&devlink->list, &devlink_list); list_add_tail(&devlink->list, &devlink_list);
devlink_notify(devlink, DEVLINK_CMD_NEW); devlink_notify(devlink, DEVLINK_CMD_NEW);

View file

@ -746,13 +746,14 @@ static int dsa_switch_setup(struct dsa_switch *ds)
/* Add the switch to devlink before calling setup, so that setup can /* Add the switch to devlink before calling setup, so that setup can
* add dpipe tables * add dpipe tables
*/ */
ds->devlink = devlink_alloc(&dsa_devlink_ops, sizeof(*dl_priv)); ds->devlink =
devlink_alloc(&dsa_devlink_ops, sizeof(*dl_priv), ds->dev);
if (!ds->devlink) if (!ds->devlink)
return -ENOMEM; return -ENOMEM;
dl_priv = devlink_priv(ds->devlink); dl_priv = devlink_priv(ds->devlink);
dl_priv->ds = ds; dl_priv->ds = ds;
err = devlink_register(ds->devlink, ds->dev); err = devlink_register(ds->devlink);
if (err) if (err)
goto free_devlink; goto free_devlink;