ipoib: Need to do dst_neigh_lookup_skb() outside of priv->lock.
authorDavid S. Miller <davem@davemloft.net>
Fri, 6 Jul 2012 04:08:05 +0000 (21:08 -0700)
committerDavid S. Miller <davem@davemloft.net>
Fri, 6 Jul 2012 04:08:05 +0000 (21:08 -0700)
Otherwise local_bh_enable() complains.

Reported-by: Or Gerlitz <ogerlitz@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/infiniband/ulp/ipoib/ipoib_multicast.c

index fbb95ee538b2dc1b10c25131c86faeb81307398e..7cecb16d3d48c20e8237b1c1acdc173931a78979 100644 (file)
@@ -658,9 +658,15 @@ static int ipoib_mcast_leave(struct net_device *dev, struct ipoib_mcast *mcast)
 void ipoib_mcast_send(struct net_device *dev, void *mgid, struct sk_buff *skb)
 {
        struct ipoib_dev_priv *priv = netdev_priv(dev);
+       struct dst_entry *dst = skb_dst(skb);
        struct ipoib_mcast *mcast;
+       struct neighbour *n;
        unsigned long flags;
 
+       n = NULL;
+       if (dst)
+               n = dst_neigh_lookup_skb(dst, skb);
+
        spin_lock_irqsave(&priv->lock, flags);
 
        if (!test_bit(IPOIB_FLAG_OPER_UP, &priv->flags)         ||
@@ -715,12 +721,6 @@ void ipoib_mcast_send(struct net_device *dev, void *mgid, struct sk_buff *skb)
 
 out:
        if (mcast && mcast->ah) {
-               struct dst_entry *dst = skb_dst(skb);
-               struct neighbour *n = NULL;
-
-               rcu_read_lock();
-               if (dst)
-                       n = dst_neigh_lookup_skb(dst, skb);
                if (n) {
                        if (!*to_ipoib_neigh(n)) {
                                struct ipoib_neigh *neigh;
@@ -735,13 +735,14 @@ out:
                        }
                        neigh_release(n);
                }
-               rcu_read_unlock();
                spin_unlock_irqrestore(&priv->lock, flags);
                ipoib_send(dev, skb, mcast->ah, IB_MULTICAST_QPN);
                return;
        }
 
 unlock:
+       if (n)
+               neigh_release(n);
        spin_unlock_irqrestore(&priv->lock, flags);
 }