aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
diff options
context:
space:
mode:
authorJason Gunthorpe <jgg@mellanox.com>2018-07-29 11:34:59 +0300
committerJason Gunthorpe <jgg@mellanox.com>2018-08-02 20:27:44 -0600
commit13476d35bba60b59521ff25d902fdb552b8bf2ac (patch)
treea6064d13b53ae0cd8cc5ad8f7672244918fbfdff /drivers/infiniband/ulp/ipoib/ipoib_vlan.c
parentIB/ipoib: Do not remove child devices from within the ndo_uninit (diff)
downloadlinux-dev-13476d35bba60b59521ff25d902fdb552b8bf2ac.tar.xz
linux-dev-13476d35bba60b59521ff25d902fdb552b8bf2ac.zip
IB/ipoib: Maintain the child_intfs list from ndo_init/uninit
This fixes a bug in the netlink path where the vlan_rwsem was not held around __ipoib_vlan_add causing the child_intfs to be manipulated unsafely. In the process this greatly simplifies the vlan_rwsem write side locking to only cover a single non-sleeping statement. This also further increases the safety of the removal ordering by holding the netdev of the parent while the child is active to ensure most bugs become either an oops on a NULL priv or a deadlock on the netdev refcount. Signed-off-by: Jason Gunthorpe <jgg@mellanox.com> Signed-off-by: Leon Romanovsky <leonro@mellanox.com>
Diffstat (limited to '')
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_vlan.c12
1 files changed, 0 insertions, 12 deletions
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_vlan.c b/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
index fa4dfcee2644..ca3a7f6c0998 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
@@ -106,8 +106,6 @@ int __ipoib_vlan_add(struct ipoib_dev_priv *ppriv, struct ipoib_dev_priv *priv,
goto sysfs_failed;
}
- list_add_tail(&priv->list, &ppriv->child_intfs);
-
return 0;
sysfs_failed:
@@ -139,11 +137,6 @@ int ipoib_vlan_add(struct net_device *pdev, unsigned short pkey)
return -EPERM;
}
- if (!down_write_trylock(&ppriv->vlan_rwsem)) {
- rtnl_unlock();
- return restart_syscall();
- }
-
/*
* First ensure this isn't a duplicate. We check the parent device and
* then all of the legacy child interfaces to make sure the Pkey
@@ -175,7 +168,6 @@ int ipoib_vlan_add(struct net_device *pdev, unsigned short pkey)
free_netdev(ndev);
out:
- up_write(&ppriv->vlan_rwsem);
rtnl_unlock();
return result;
@@ -209,10 +201,6 @@ static void ipoib_vlan_delete_task(struct work_struct *work)
struct ipoib_dev_priv *priv = ipoib_priv(dev);
struct ipoib_dev_priv *ppriv = ipoib_priv(priv->parent);
- down_write(&ppriv->vlan_rwsem);
- list_del(&priv->list);
- up_write(&ppriv->vlan_rwsem);
-
ipoib_dbg(ppriv, "delete child vlan %s\n", dev->name);
unregister_netdevice(dev);
}