[ofa-general] [RFC] ipoib: avoid using stale ipoib_neigh* in ipoib_neigh_cleanup()
Yossi Etigin
yossi.openib at gmail.com
Fri May 22 03:24:17 PDT 2009
akepner at sgi.com wrote:
> On Thu, May 21, 2009 at 08:32:22AM +0300, Or Gerlitz wrote:
>> ....
>>> Pid: 0, comm: swapper Tainted: G U 2.6.16.54-0.2.5-smp
>> its very likely that the problem you face in 2.6.16 was fixed by the
>> commit I pointed on in my previous reply on this thread.
>>
>
> Hmmm, it's not obvious to me that that commit
> (ecbb416939da77c0d107409976499724baddce7b) would be relevant
> to the bug that I mentioned earlier.
>
So, ipoib tries to list_del(neigh) twice because the second time
the condition (neigh != NULL) is not protected with a lock.
How about this:
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c
index ab2c192..993b5a7 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
@@ -845,23 +845,24 @@ static void ipoib_neigh_cleanup(struct neighbour *n)
unsigned long flags;
struct ipoib_ah *ah = NULL;
+ spin_lock_irqsave(&priv->lock, flags);
+
neigh = *to_ipoib_neigh(n);
if (neigh)
priv = netdev_priv(neigh->dev);
else
- return;
+ goto out;
ipoib_dbg(priv,
"neigh_cleanup for %06x %pI6\n",
IPOIB_QPN(n->ha),
n->ha + 4);
- spin_lock_irqsave(&priv->lock, flags);
-
if (neigh->ah)
ah = neigh->ah;
list_del(&neigh->list);
ipoib_neigh_free(n->dev, neigh);
+out:
spin_unlock_irqrestore(&priv->lock, flags);
if (ah)
More information about the general
mailing list