mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-16 07:35:14 +00:00
IB/ipoib: Add child to parent list only if device initialized
[ Upstream commit91b01061fe
] 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:eaeb398425
("IB/ipoib: Move init code to ndo_init") Signed-off-by: Valentine Fatiev <valentinef@mellanox.com> Reviewed-by: Feras Daoud <ferasda@mellanox.com> Signed-off-by: Leon Romanovsky <leonro@mellanox.com> Reviewed-by: Jason Gunthorpe <jgg@mellanox.com> Signed-off-by: Jason Gunthorpe <jgg@mellanox.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
parent
d48720bafd
commit
007b01a27d
1 changed files with 20 additions and 14 deletions
|
@ -1892,12 +1892,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);
|
||||
|
@ -1940,6 +1934,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;
|
||||
|
@ -1957,6 +1962,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);
|
||||
|
@ -1968,15 +1981,8 @@ 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)
|
||||
|
|
Loading…
Reference in a new issue