Merge tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma
[sfrench/cifs-2.6.git] / drivers / infiniband / ulp / ipoib / ipoib_main.c
index 04ea7db08e87edf6a8302070e661abd0fe35f790..ac0583ff280d1b5fd3efecec56a9ce9c92a43a11 100644 (file)
@@ -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,15 +1982,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)