[ofa-general] [RFC] ipoib: avoid using stale ipoib_neigh* in ipoib_neigh_cleanup()
akepner at sgi.com
akepner at sgi.com
Fri May 22 08:52:08 PDT 2009
On Fri, May 22, 2009 at 01:24:17PM +0300, Yossi Etigin wrote:
> ...
> 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); <-- deadlock here
> +
> 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)
>
This is essentially what I did first time around, but a deadlock on
the line marked above was quickly found.
Instead what we've been doing is:
--- e/ofa_kernel-1.3.1/drivers/infiniband/ulp/ipoib/ipoib_main.c 2008-06-06 12:04:20.791744390 -0700
+++ f/ofa_kernel-1.3.1/drivers/infiniband/ulp/ipoib/ipoib_main.c 2008-06-06 12:10:14.129143660 -0700
@@ -835,11 +835,14 @@ static void ipoib_neigh_cleanup(struct n
IPOIB_GID_RAW_ARG(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);
+
+ neigh = *to_ipoib_neigh(n);
+ if (neigh) {
+ if (neigh->ah)
+ ah = neigh->ah;
+ list_del(&neigh->list);
+ ipoib_neigh_free(n->dev, neigh);
+ }
spin_unlock_irqrestore(&priv->lock, flags);
This has worked in practice, but it obviously leaves a small hole
open.
--
Arthur
More information about the general
mailing list