[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20070319093632.GB8386@mellanox.co.il>
Date: Mon, 19 Mar 2007 11:36:32 +0200
From: "Michael S. Tsirkin" <mst@....mellanox.co.il>
To: Alexey Kuznetsov <kuznet@....inr.ac.ru>
Cc: "Michael S. Tsirkin" <mst@....mellanox.co.il>,
Linux Kernel Mailing List <linux-kernel@...r.kernel.org>,
netdev@...r.kernel.org, general@...ts.openfabrics.org,
Roland Dreier <rolandd@...co.com>,
David Miller <davem@...emloft.net>
Subject: Re: dst_ifdown breaks infiniband?
> > Any simpler ideas?
>
> Well, if inifiniband destructor really needs to take that lock... no.
> Right now I do not see.
OK, this is actually not hard to fix - for infiniband, we can just look at
neighbour->dev->type or compare neighbour->dev and
neighbour->parms->dev - if they are different, device is being unregistered,
so we do not need to do anything in the destructor.
I'll send a patch to openfabrics, shortly.
However, after implementing this fix, I hit what could be use after
free at module unloading. Dave, Alexey, Roland, could you take a look at
the following please?
Works fine for me (survived a couple of hours of crazy device
loading/unloading/up/down/hotplug + link data and state activity)
and seems to fix the issue.
---------
If a device driver sets neigh_destructor in neigh_params, this could
get called after the device has been unregistered and the driver module
removed.
This is an old bug, but apparently, started to get triggered more infiniband
after recent multicast and connected mode changes.
Fix this by delaying dev_put until the neigh_params object is removed.
Signed-off-by: Michael S. Tsirkin <mst@....mellanox.co.il>
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index 3183142..cb34f1a 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -1313,8 +1313,6 @@ void neigh_parms_release(struct neigh_table *tbl, struct neigh_parms *parms)
*p = parms->next;
parms->dead = 1;
write_unlock_bh(&tbl->lock);
- if (parms->dev)
- dev_put(parms->dev);
call_rcu(&parms->rcu_head, neigh_rcu_free_parms);
return;
}
@@ -1325,6 +1323,8 @@ void neigh_parms_release(struct neigh_table *tbl, struct neigh_parms *parms)
void neigh_parms_destroy(struct neigh_parms *parms)
{
+ if (parms->dev)
+ dev_put(parms->dev);
kfree(parms);
}
--
MST
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists