Skip to content

Commit

Permalink
devlink: Set device as early as possible
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Leon Romanovsky authored and David S. Miller committed Aug 9, 2021
1 parent 94c0a6f commit 919d13a
Show file tree
Hide file tree
Showing 33 changed files with 91 additions and 94 deletions.
9 changes: 6 additions & 3 deletions drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -743,14 +743,17 @@ static void bnxt_dl_params_unregister(struct bnxt *bp)

int bnxt_dl_register(struct bnxt *bp)
{
const struct devlink_ops *devlink_ops;
struct devlink_port_attrs attrs = {};
struct devlink *dl;
int rc;

if (BNXT_PF(bp))
dl = devlink_alloc(&bnxt_dl_ops, sizeof(struct bnxt_dl));
devlink_ops = &bnxt_dl_ops;
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) {
netdev_warn(bp->dev, "devlink_alloc failed\n");
return -ENOMEM;
Expand All @@ -763,7 +766,7 @@ int bnxt_dl_register(struct bnxt *bp)
bp->hwrm_spec_code > 0x10803)
bp->eswitch_mode = DEVLINK_ESWITCH_MODE_LEGACY;

rc = devlink_register(dl, &bp->pdev->dev);
rc = devlink_register(dl);
if (rc) {
netdev_warn(bp->dev, "devlink_register failed. rc=%d\n", rc);
goto err_dl_free;
Expand Down
5 changes: 3 additions & 2 deletions drivers/net/ethernet/cavium/liquidio/lio_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -3750,7 +3750,8 @@ static int setup_nic_devices(struct octeon_device *octeon_dev)
}

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

if (devlink_register(devlink, &octeon_dev->pci_dev->dev)) {
if (devlink_register(devlink)) {
devlink_free(devlink);
dev_err(&octeon_dev->pci_dev->dev,
"devlink registration failed\n");
Expand Down
5 changes: 3 additions & 2 deletions drivers/net/ethernet/freescale/dpaa2/dpaa2-eth-devlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -196,15 +196,16 @@ int dpaa2_eth_dl_register(struct dpaa2_eth_priv *priv)
struct dpaa2_eth_devlink_priv *dl_priv;
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) {
dev_err(dev, "devlink_alloc failed\n");
return -ENOMEM;
}
dl_priv = devlink_priv(priv->devlink);
dl_priv->dpaa2_priv = priv;

err = devlink_register(priv->devlink, dev);
err = devlink_register(priv->devlink);
if (err) {
dev_err(dev, "devlink_register() = %d\n", err);
goto devlink_free;
Expand Down
4 changes: 2 additions & 2 deletions drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_devlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -112,14 +112,14 @@ int hclge_devlink_init(struct hclge_dev *hdev)
int ret;

devlink = devlink_alloc(&hclge_devlink_ops,
sizeof(struct hclge_devlink_priv));
sizeof(struct hclge_devlink_priv), &pdev->dev);
if (!devlink)
return -ENOMEM;

priv = devlink_priv(devlink);
priv->hdev = hdev;

ret = devlink_register(devlink, &pdev->dev);
ret = devlink_register(devlink);
if (ret) {
dev_err(&pdev->dev, "failed to register devlink, ret = %d\n",
ret);
Expand Down
7 changes: 4 additions & 3 deletions drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_devlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -112,15 +112,16 @@ int hclgevf_devlink_init(struct hclgevf_dev *hdev)
struct devlink *devlink;
int ret;

devlink = devlink_alloc(&hclgevf_devlink_ops,
sizeof(struct hclgevf_devlink_priv));
devlink =
devlink_alloc(&hclgevf_devlink_ops,
sizeof(struct hclgevf_devlink_priv), &pdev->dev);
if (!devlink)
return -ENOMEM;

priv = devlink_priv(devlink);
priv->hdev = hdev;

ret = devlink_register(devlink, &pdev->dev);
ret = devlink_register(devlink);
if (ret) {
dev_err(&pdev->dev, "failed to register devlink, ret = %d\n",
ret);
Expand Down
8 changes: 4 additions & 4 deletions drivers/net/ethernet/huawei/hinic/hinic_devlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -293,21 +293,21 @@ static const struct devlink_ops hinic_devlink_ops = {
.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)
{
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);

return devlink_register(devlink, dev);
return devlink_register(devlink);
}

void hinic_devlink_unregister(struct hinic_devlink_priv *priv)
Expand Down
4 changes: 2 additions & 2 deletions drivers/net/ethernet/huawei/hinic/hinic_devlink.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,9 +108,9 @@ struct host_image_st {
u32 device_id;
};

struct devlink *hinic_devlink_alloc(void);
struct devlink *hinic_devlink_alloc(struct device *dev);
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);

int hinic_health_reporters_create(struct hinic_devlink_priv *priv);
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -754,7 +754,7 @@ static int init_pfhwdev(struct hinic_pfhwdev *pfhwdev)
return err;
}

err = hinic_devlink_register(hwdev->devlink_dev, &pdev->dev);
err = hinic_devlink_register(hwdev->devlink_dev);
if (err) {
dev_err(&hwif->pdev->dev, "Failed to register devlink\n");
hinic_pf_to_mgmt_free(&pfhwdev->pf_to_mgmt);
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/ethernet/huawei/hinic/hinic_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1183,7 +1183,7 @@ static int nic_dev_init(struct pci_dev *pdev)
struct devlink *devlink;
int err, num_qps;

devlink = hinic_devlink_alloc();
devlink = hinic_devlink_alloc(&pdev->dev);
if (!devlink) {
dev_err(&pdev->dev, "Hinic devlink alloc failed\n");
return -ENOMEM;
Expand Down
4 changes: 2 additions & 2 deletions drivers/net/ethernet/intel/ice/ice_devlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -475,7 +475,7 @@ struct ice_pf *ice_allocate_pf(struct device *dev)
{
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)
return NULL;

Expand All @@ -502,7 +502,7 @@ int ice_devlink_register(struct ice_pf *pf)
struct device *dev = ice_pf_to_dev(pf);
int err;

err = devlink_register(devlink, dev);
err = devlink_register(devlink);
if (err) {
dev_err(dev, "devlink registration failed: %d\n", err);
return err;
Expand Down
5 changes: 3 additions & 2 deletions drivers/net/ethernet/marvell/octeontx2/af/rvu_devlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -1503,13 +1503,14 @@ int rvu_register_dl(struct rvu *rvu)
struct devlink *dl;
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) {
dev_warn(rvu->dev, "devlink_alloc failed\n");
return -ENOMEM;
}

err = devlink_register(dl, rvu->dev);
err = devlink_register(dl);
if (err) {
dev_err(rvu->dev, "devlink register failed with error %d\n", err);
devlink_free(dl);
Expand Down
7 changes: 4 additions & 3 deletions drivers/net/ethernet/marvell/prestera/prestera_devlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -390,11 +390,12 @@ static const struct devlink_ops prestera_dl_ops = {
.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;

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);
}
Expand All @@ -411,7 +412,7 @@ int prestera_devlink_register(struct prestera_switch *sw)
struct devlink *dl = priv_to_devlink(sw);
int err;

err = devlink_register(dl, sw->dev->dev);
err = devlink_register(dl);
if (err) {
dev_err(prestera_dev(sw), "devlink_register failed: %d\n", err);
return err;
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/ethernet/marvell/prestera/prestera_devlink.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

#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);

int prestera_devlink_register(struct prestera_switch *sw);
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/ethernet/marvell/prestera/prestera_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -905,7 +905,7 @@ int prestera_device_register(struct prestera_device *dev)
struct prestera_switch *sw;
int err;

sw = prestera_devlink_alloc();
sw = prestera_devlink_alloc(dev);
if (!sw)
return -ENOMEM;

Expand Down
4 changes: 2 additions & 2 deletions drivers/net/ethernet/mellanox/mlx4/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

devlink = devlink_alloc(&mlx4_devlink_ops, sizeof(*priv));
devlink = devlink_alloc(&mlx4_devlink_ops, sizeof(*priv), &pdev->dev);
if (!devlink)
return -ENOMEM;
priv = devlink_priv(devlink);
Expand All @@ -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->pci_status_mutex);

ret = devlink_register(devlink, &pdev->dev);
ret = devlink_register(devlink);
if (ret)
goto err_persist_free;
ret = devlink_params_register(devlink, mlx4_devlink_params,
Expand Down
9 changes: 5 additions & 4 deletions drivers/net/ethernet/mellanox/mlx5/core/devlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -359,9 +359,10 @@ int mlx5_devlink_traps_get_action(struct mlx5_core_dev *dev, int trap_id,
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)
Expand Down Expand Up @@ -638,11 +639,11 @@ static void mlx5_devlink_traps_unregister(struct devlink *devlink)
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;

err = devlink_register(devlink, dev);
err = devlink_register(devlink);
if (err)
return err;

Expand Down
4 changes: 2 additions & 2 deletions drivers/net/ethernet/mellanox/mlx5/core/devlink.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
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);
int mlx5_devlink_register(struct devlink *devlink, struct device *dev);
int mlx5_devlink_register(struct devlink *devlink);
void mlx5_devlink_unregister(struct devlink *devlink);

#endif /* __MLX5_DEVLINK_H__ */
4 changes: 2 additions & 2 deletions drivers/net/ethernet/mellanox/mlx5/core/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1271,7 +1271,7 @@ int mlx5_init_one(struct mlx5_core_dev *dev)

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)
goto err_devlink_reg;

Expand Down Expand Up @@ -1452,7 +1452,7 @@ static int probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
struct devlink *devlink;
int err;

devlink = mlx5_devlink_alloc();
devlink = mlx5_devlink_alloc(&pdev->dev);
if (!devlink) {
dev_err(&pdev->dev, "devlink alloc failed\n");
return -ENOMEM;
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/ethernet/mellanox/mlx5/core/sf/dev/driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ static int mlx5_sf_dev_probe(struct auxiliary_device *adev, const struct auxilia
struct devlink *devlink;
int err;

devlink = mlx5_devlink_alloc();
devlink = mlx5_devlink_alloc(&adev->dev);
if (!devlink)
return -ENOMEM;

Expand Down
5 changes: 3 additions & 2 deletions drivers/net/ethernet/mellanox/mlxsw/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -1927,7 +1927,8 @@ __mlxsw_core_bus_device_register(const struct mlxsw_bus_info *mlxsw_bus_info,

if (!reload) {
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) {
err = -ENOMEM;
goto err_devlink_alloc;
Expand Down Expand Up @@ -1974,7 +1975,7 @@ __mlxsw_core_bus_device_register(const struct mlxsw_bus_info *mlxsw_bus_info,
goto err_emad_init;

if (!reload) {
err = devlink_register(devlink, mlxsw_bus_info->dev);
err = devlink_register(devlink);
if (err)
goto err_devlink_register;
}
Expand Down
5 changes: 3 additions & 2 deletions drivers/net/ethernet/mscc/ocelot_vsc7514.c
Original file line number Diff line number Diff line change
Expand Up @@ -1103,7 +1103,8 @@ static int mscc_ocelot_probe(struct platform_device *pdev)
if (!np && !pdev->dev.platform_data)
return -ENODEV;

devlink = devlink_alloc(&ocelot_devlink_ops, sizeof(*ocelot));
devlink =
devlink_alloc(&ocelot_devlink_ops, sizeof(*ocelot), &pdev->dev);
if (!devlink)
return -ENOMEM;

Expand Down Expand Up @@ -1187,7 +1188,7 @@ static int mscc_ocelot_probe(struct platform_device *pdev)
if (err)
goto out_put_ports;

err = devlink_register(devlink, ocelot->dev);
err = devlink_register(devlink);
if (err)
goto out_ocelot_deinit;

Expand Down
2 changes: 1 addition & 1 deletion drivers/net/ethernet/netronome/nfp/nfp_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -692,7 +692,7 @@ static int nfp_pci_probe(struct pci_dev *pdev,
goto err_pci_disable;
}

devlink = devlink_alloc(&nfp_devlink_ops, sizeof(*pf));
devlink = devlink_alloc(&nfp_devlink_ops, sizeof(*pf), &pdev->dev);
if (!devlink) {
err = -ENOMEM;
goto err_rel_regions;
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/ethernet/netronome/nfp/nfp_net_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -701,7 +701,7 @@ int nfp_net_pci_probe(struct nfp_pf *pf)
if (err)
goto err_unmap;

err = devlink_register(devlink, &pf->pdev->dev);
err = devlink_register(devlink);
if (err)
goto err_app_clean;

Expand Down
4 changes: 2 additions & 2 deletions drivers/net/ethernet/pensando/ionic/ionic_devlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ struct ionic *ionic_devlink_alloc(struct device *dev)
{
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);
}
Expand All @@ -82,7 +82,7 @@ int ionic_devlink_register(struct ionic *ionic)
struct devlink_port_attrs attrs = {};
int err;

err = devlink_register(dl, ionic->dev);
err = devlink_register(dl);
if (err) {
dev_warn(ionic->dev, "devlink_register failed: %d\n", err);
return err;
Expand Down
Loading

0 comments on commit 919d13a

Please sign in to comment.