IPoIB: Avoid flushing the driver workqueue on dev_down
[cascardo/linux.git] / drivers / infiniband / ulp / ipoib / ipoib_ib.c
index 196b1d1..ff64b16 100644 (file)
@@ -685,15 +685,13 @@ int ipoib_ib_dev_open(struct net_device *dev)
        ret = ipoib_ib_post_receives(dev);
        if (ret) {
                ipoib_warn(priv, "ipoib_ib_post_receives returned %d\n", ret);
-               ipoib_ib_dev_stop(dev, 1);
-               return -1;
+               goto dev_stop;
        }
 
        ret = ipoib_cm_dev_open(dev);
        if (ret) {
                ipoib_warn(priv, "ipoib_cm_dev_open returned %d\n", ret);
-               ipoib_ib_dev_stop(dev, 1);
-               return -1;
+               goto dev_stop;
        }
 
        clear_bit(IPOIB_STOP_REAPER, &priv->flags);
@@ -704,6 +702,11 @@ int ipoib_ib_dev_open(struct net_device *dev)
                napi_enable(&priv->napi);
 
        return 0;
+dev_stop:
+       if (!test_and_set_bit(IPOIB_FLAG_INITIALIZED, &priv->flags))
+               napi_enable(&priv->napi);
+       ipoib_ib_dev_stop(dev, 1);
+       return -1;
 }
 
 static void ipoib_pkey_dev_check_presence(struct net_device *dev)
@@ -746,10 +749,8 @@ int ipoib_ib_dev_down(struct net_device *dev, int flush)
        if (!test_bit(IPOIB_PKEY_ASSIGNED, &priv->flags)) {
                mutex_lock(&pkey_mutex);
                set_bit(IPOIB_PKEY_STOP, &priv->flags);
-               cancel_delayed_work(&priv->pkey_poll_task);
+               cancel_delayed_work_sync(&priv->pkey_poll_task);
                mutex_unlock(&pkey_mutex);
-               if (flush)
-                       flush_workqueue(ipoib_workqueue);
        }
 
        ipoib_mcast_stop_thread(dev, flush);
@@ -974,7 +975,7 @@ static void __ipoib_ib_dev_flush(struct ipoib_dev_priv *priv,
        u16 new_index;
        int result;
 
-       mutex_lock(&priv->vlan_mutex);
+       down_read(&priv->vlan_rwsem);
 
        /*
         * Flush any child interfaces too -- they might be up even if
@@ -983,7 +984,7 @@ static void __ipoib_ib_dev_flush(struct ipoib_dev_priv *priv,
        list_for_each_entry(cpriv, &priv->child_intfs, list)
                __ipoib_ib_dev_flush(cpriv, level);
 
-       mutex_unlock(&priv->vlan_mutex);
+       up_read(&priv->vlan_rwsem);
 
        if (!test_bit(IPOIB_FLAG_INITIALIZED, &priv->flags)) {
                /* for non-child devices must check/update the pkey value here */