Commit 919d13a7 authored by Leon Romanovsky's avatar Leon Romanovsky Committed by David S. Miller
Browse files

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: default avatarLeon Romanovsky <leonro@nvidia.com>
Reviewed-by: default avatarJiri Pirko <jiri@nvidia.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 94c0a6fb
Loading
Loading
Loading
Loading
+6 −3
Original line number Diff line number Diff line
@@ -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;
@@ -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;
+3 −2
Original line number Diff line number Diff line
@@ -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;
@@ -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");
+3 −2
Original line number Diff line number Diff line
@@ -196,7 +196,8 @@ 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;
@@ -204,7 +205,7 @@ int dpaa2_eth_dl_register(struct dpaa2_eth_priv *priv)
	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;
+2 −2
Original line number Diff line number Diff line
@@ -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);
+4 −3
Original line number Diff line number Diff line
@@ -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);
Loading