[openib-general] IPoIB descructor for 2.6.16-stable?
Michael S. Tsirkin
mst at mellanox.co.il
Wed Apr 5 04:52:32 PDT 2006
Roland,
given that the cleaner backport from 2.6.17 got voted down from 2.6.16,
how about pushing a work-around from subversion in there?
Something along the lines of the patch below?
Is this small/obvious enough to be considered for stable? What do you think?
Signed-off-by: Michael S. Tsirkin <mst at mellanox.co.il>
Index: linux-2.6.16.1/drivers/infiniband/ulp/ipoib/ipoib_main.c
===================================================================
--- linux-2.6.16.1.orig/drivers/infiniband/ulp/ipoib/ipoib_main.c 2006-03-28 08:49:02.000000000 +0200
+++ linux-2.6.16.1/drivers/infiniband/ulp/ipoib/ipoib_main.c 2006-04-05 11:30:35.000000000 +0300
@@ -73,6 +73,9 @@ static const u8 ipv4_bcast_addr[] = {
struct workqueue_struct *ipoib_workqueue;
+static DEFINE_SPINLOCK(ipoib_all_neigh_list_lock);
+static LIST_HEAD(ipoib_all_neigh_list);
+
static void ipoib_add_one(struct ib_device *device);
static void ipoib_remove_one(struct ib_device *device);
@@ -246,8 +249,8 @@ static void path_free(struct net_device
*/
if (neigh->ah)
ipoib_put_ah(neigh->ah);
+ ipoib_neigh_cleanup(neigh);
*to_ipoib_neigh(neigh->neighbour) = NULL;
- neigh->neighbour->ops->destructor = NULL;
kfree(neigh);
}
@@ -486,6 +489,7 @@ static void neigh_add_path(struct sk_buf
skb_queue_head_init(&neigh->queue);
neigh->neighbour = skb->dst->neighbour;
*to_ipoib_neigh(skb->dst->neighbour) = neigh;
+ ipoib_neigh_setup(neigh)
/*
* We can only be called from ipoib_start_xmit, so we're
@@ -528,9 +532,9 @@ static void neigh_add_path(struct sk_buf
return;
err:
+ ipoib_neigh_cleanup(neigh);
*to_ipoib_neigh(skb->dst->neighbour) = NULL;
list_del(&neigh->list);
- neigh->neighbour->ops->destructor = NULL;
kfree(neigh);
++priv->stats.tx_dropped;
@@ -747,6 +751,17 @@ static void ipoib_neigh_destructor(struc
unsigned long flags;
struct ipoib_ah *ah = NULL;
+ struct ipoib_neigh *tn, *nn = NULL;
+ spin_lock(&ipoib_all_neigh_list_lock);
+ list_for_each_entry(tn, &ipoib_all_neigh_list, all_neigh_list)
+ if (tn->neighbour == n) {
+ nn = tn;
+ break;
+ }
+ spin_unlock(&ipoib_all_neigh_list_lock);
+ if (!nn)
+ return;
+
ipoib_dbg(priv,
"neigh_destructor for %06x " IPOIB_GID_FMT "\n",
be32_to_cpup((__be32 *) n->ha),
@@ -759,6 +774,7 @@ static void ipoib_neigh_destructor(struc
if (neigh->ah)
ah = neigh->ah;
list_del(&neigh->list);
+ ipoib_neigh_cleanup(neigh);
*to_ipoib_neigh(n) = NULL;
kfree(neigh);
}
@@ -769,23 +785,31 @@ static void ipoib_neigh_destructor(struc
ipoib_put_ah(ah);
}
-static int ipoib_neigh_setup(struct neighbour *neigh)
+void ipoib_neigh_setup(struct ipoib_neigh *neigh)
{
/*
* Is this kosher? I can't find anybody in the kernel that
* sets neigh->destructor, so we should be able to set it here
* without trouble.
*/
- neigh->ops->destructor = ipoib_neigh_destructor;
-
- return 0;
+ spin_lock(&ipoib_all_neigh_list_lock);
+ list_add_tail(&neigh->all_neigh_list, &ipoib_all_neigh_list);
+ neigh->neighbour->ops->destructor = ipoib_neigh_destructor;
+ spin_unlock(&ipoib_all_neigh_list_lock);
}
-static int ipoib_neigh_setup_dev(struct net_device *dev, struct neigh_parms *parms)
-{
- parms->neigh_setup = ipoib_neigh_setup;
+int ipoib_neigh_cleanup(struct ipoib_neigh *neigh)
+{
+ struct ipoib_neigh *nn;
+ spin_lock(&ipoib_all_neigh_list_lock);
+ list_del(&neigh->all_neigh_list);
+ list_for_each_entry(nn, &ipoib_all_neigh_list, all_neigh_list)
+ if (nn->neighbour->ops == neigh->neighbour->ops)
+ goto found;
- return 0;
+ neigh->neighbour->ops->destructor = NULL;
+found:
+ spin_unlock(&ipoib_all_neigh_list_lock);
}
int ipoib_dev_init(struct net_device *dev, struct ib_device *ca, int port)
@@ -861,7 +885,6 @@ static void ipoib_setup(struct net_devic
dev->tx_timeout = ipoib_timeout;
dev->hard_header = ipoib_hard_header;
dev->set_multicast_list = ipoib_set_mcast_list;
- dev->neigh_setup = ipoib_neigh_setup_dev;
dev->watchdog_timeo = HZ;
Index: linux-2.6.16.1/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
===================================================================
--- linux-2.6.16.1.orig/drivers/infiniband/ulp/ipoib/ipoib_multicast.c 2006-03-28 08:49:02.000000000 +0200
+++ linux-2.6.16.1/drivers/infiniband/ulp/ipoib/ipoib_multicast.c 2006-04-05 11:30:57.000000000 +0300
@@ -114,8 +114,8 @@ static void ipoib_mcast_free(struct ipoi
*/
if (neigh->ah)
ipoib_put_ah(neigh->ah);
+ ipoib_neigh_cleanup(neigh)
*to_ipoib_neigh(neigh->neighbour) = NULL;
- neigh->neighbour->ops->destructor = NULL;
kfree(neigh);
}
@@ -766,6 +766,7 @@ out:
neigh->ah = mcast->ah;
neigh->neighbour = skb->dst->neighbour;
*to_ipoib_neigh(skb->dst->neighbour) = neigh;
+ ipoib_neigh_setup(neigh)
list_add_tail(&neigh->list, &mcast->neigh_list);
}
}
--
MST
More information about the general
mailing list