[ofa-general] Re: 2.6.30.1: possible irq lock inversion dependency detected
Roland Dreier
rdreier at cisco.com
Fri Jul 10 13:42:04 PDT 2009
> Thanks for the patch. With the patch applied the lockdep warning
> indeed occurs sooner and the output is now indeed shorter. You can
> find the new lockdep output here:
> http://bugzilla.kernel.org/attachment.cgi?id=22305.
Thanks, that actually looks like a completely different issue (that I
can actually understand). I was able to reproduce that here: the issue
is doing skb_orphan() inside of priv->lock, and the network stack
locking is not irq-safe. So the following hacky patch fixes that.
This would be a short-term solution for the immediate issue at least. A
better solution would be if we didn't need to make priv->lock
hardirq-safe: the only place that requires it is the QP event handler in
ipoib_cm.c, and that might be a little dicy to fix. Need to think about that.
However with this patch applied I don't see any further lockdep reports
here. It would be great if you could retest yet again with this applied
(on top of my earlier patch to make priv->lock hardirq-safe as early as
possible).
Thanks,
Roland
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c
index e319d91..4d53011 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
@@ -604,8 +604,11 @@ static void neigh_add_path(struct sk_buff *skb, struct net_device *dev)
skb_queue_len(&neigh->queue));
goto err_drop;
}
- } else
+ } else {
ipoib_send(dev, skb, path->ah, IPOIB_QPN(skb_dst(skb)->neighbour->ha));
+ spin_unlock_irqrestore(&priv->lock, flags);
+ return;
+ }
} else {
neigh->ah = NULL;
@@ -689,6 +692,8 @@ static void unicast_arp_send(struct sk_buff *skb, struct net_device *dev,
be16_to_cpu(path->pathrec.dlid));
ipoib_send(dev, skb, path->ah, IPOIB_QPN(phdr->hwaddr));
+ spin_unlock_irqrestore(&priv->lock, flags);
+ return;
} else if ((path->query || !path_rec_start(dev, path)) &&
skb_queue_len(&path->queue) < IPOIB_MAX_PATH_REC_QUEUE) {
/* put pseudoheader back on for next time */
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
index a0e9753..a0825fe 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
@@ -720,7 +720,9 @@ out:
}
}
+ spin_unlock_irqrestore(&priv->lock, flags);
ipoib_send(dev, skb, mcast->ah, IB_MULTICAST_QPN);
+ return;
}
unlock:
More information about the general
mailing list