Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 91b01061 authored by Valentine Fatiev's avatar Valentine Fatiev Committed by Jason Gunthorpe
Browse files

IB/ipoib: Add child to parent list only if device initialized



Despite failure in ipoib_dev_init() we continue with initialization flow
and creation of child device. It causes to the situation where this child
device is added too early to parent device list.

Change the logic, so in case of failure we properly return error from
ipoib_dev_init() and add child only in success path.

Fixes: eaeb3984 ("IB/ipoib: Move init code to ndo_init")
Signed-off-by: default avatarValentine Fatiev <valentinef@mellanox.com>
Reviewed-by: default avatarFeras Daoud <ferasda@mellanox.com>
Signed-off-by: default avatarLeon Romanovsky <leonro@mellanox.com>
Reviewed-by: default avatarJason Gunthorpe <jgg@mellanox.com>
Signed-off-by: default avatarJason Gunthorpe <jgg@mellanox.com>
parent 50ba3c18
Loading
Loading
Loading
Loading
+20 −14
Original line number Diff line number Diff line
@@ -1893,12 +1893,6 @@ static void ipoib_child_init(struct net_device *ndev)
	struct ipoib_dev_priv *priv = ipoib_priv(ndev);
	struct ipoib_dev_priv *ppriv = ipoib_priv(priv->parent);

	dev_hold(priv->parent);

	down_write(&ppriv->vlan_rwsem);
	list_add_tail(&priv->list, &ppriv->child_intfs);
	up_write(&ppriv->vlan_rwsem);

	priv->max_ib_mtu = ppriv->max_ib_mtu;
	set_bit(IPOIB_FLAG_SUBINTERFACE, &priv->flags);
	memcpy(priv->dev->dev_addr, ppriv->dev->dev_addr, INFINIBAND_ALEN);
@@ -1941,6 +1935,17 @@ static int ipoib_ndo_init(struct net_device *ndev)
	if (rc) {
		pr_warn("%s: failed to initialize device: %s port %d (ret = %d)\n",
			priv->ca->name, priv->dev->name, priv->port, rc);
		return rc;
	}

	if (priv->parent) {
		struct ipoib_dev_priv *ppriv = ipoib_priv(priv->parent);

		dev_hold(priv->parent);

		down_write(&ppriv->vlan_rwsem);
		list_add_tail(&priv->list, &ppriv->child_intfs);
		up_write(&ppriv->vlan_rwsem);
	}

	return 0;
@@ -1958,6 +1963,14 @@ static void ipoib_ndo_uninit(struct net_device *dev)
	 */
	WARN_ON(!list_empty(&priv->child_intfs));

	if (priv->parent) {
		struct ipoib_dev_priv *ppriv = ipoib_priv(priv->parent);

		down_write(&ppriv->vlan_rwsem);
		list_del(&priv->list);
		up_write(&ppriv->vlan_rwsem);
	}

	ipoib_neigh_hash_uninit(dev);

	ipoib_ib_dev_cleanup(dev);
@@ -1969,16 +1982,9 @@ static void ipoib_ndo_uninit(struct net_device *dev)
		priv->wq = NULL;
	}

	if (priv->parent) {
		struct ipoib_dev_priv *ppriv = ipoib_priv(priv->parent);

		down_write(&ppriv->vlan_rwsem);
		list_del(&priv->list);
		up_write(&ppriv->vlan_rwsem);

	if (priv->parent)
		dev_put(priv->parent);
}
}

static int ipoib_set_vf_link_state(struct net_device *dev, int vf, int link_state)
{