[ofa-general] Re: [openib-general] [RFC] [PATCH v2] IB/ipoib: Add bonding support to IPoIB
Moni Shoua
monisonlists at gmail.com
Sun Mar 4 02:32:15 PST 2007
This version of the patch tracks the allocs and releases of ipoib_neigh and
keeps a list of them. Before IPoIB net device unregisters the list is passed
to destroy ipoib_neighs that ride on on a bond neighbour.
This is a replacement to the method of scanning the arp and ndisc
tables.
Index: linux-2.6/drivers/infiniband/ulp/ipoib/ipoib.h
===================================================================
--- linux-2.6.orig/drivers/infiniband/ulp/ipoib/ipoib.h 2007-03-04 12:20:54.749932751 +0200
+++ linux-2.6/drivers/infiniband/ulp/ipoib/ipoib.h 2007-03-04 12:21:58.547593677 +0200
@@ -218,6 +218,7 @@ struct ipoib_neigh {
struct neighbour *neighbour;
struct net_device *dev;
+ struct list_head all_neigh_list;
struct list_head list;
};
Index: linux-2.6/drivers/infiniband/ulp/ipoib/ipoib_main.c
===================================================================
--- linux-2.6.orig/drivers/infiniband/ulp/ipoib/ipoib_main.c 2007-03-04 12:21:52.720629356 +0200
+++ linux-2.6/drivers/infiniband/ulp/ipoib/ipoib_main.c 2007-03-04 12:21:58.548593499 +0200
@@ -66,6 +66,7 @@ MODULE_PARM_DESC(recv_queue_size, "Numbe
#ifdef CONFIG_INFINIBAND_IPOIB_DEBUG
int ipoib_debug_level;
+static int ipoib_at_exit = 0;
module_param_named(debug_level, ipoib_debug_level, int, 0644);
MODULE_PARM_DESC(debug_level, "Enable debug tracing if > 0");
#endif
@@ -85,6 +86,9 @@ struct workqueue_struct *ipoib_workqueue
struct ib_sa_client ipoib_sa_client;
+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);
@@ -792,6 +796,24 @@ static void ipoib_neigh_destructor(struc
ipoib_put_ah(ah);
}
+static void ipoib_neigh_cleanup_bond(struct net_device* master,
+ struct net_device* slave)
+{
+ struct ipoib_neigh *nn, *tn;
+
+ spin_lock(&ipoib_all_neigh_list_lock);
+ list_for_each_entry_safe(nn, tn, &ipoib_all_neigh_list, all_neigh_list){
+ if ((nn->neighbour->dev == master) && (nn->dev == slave)) {
+ if (ipoib_at_exit)
+ nn->neighbour->parms->neigh_destructor = NULL;
+ spin_unlock(&ipoib_all_neigh_list_lock);
+ ipoib_neigh_destructor(nn->neighbour);
+ spin_lock(&ipoib_all_neigh_list_lock);
+ }
+ }
+ spin_unlock(&ipoib_all_neigh_list_lock);
+}
+
struct ipoib_neigh *ipoib_neigh_alloc(struct neighbour *neighbour,
struct net_device *dev)
{
@@ -806,6 +828,9 @@ struct ipoib_neigh *ipoib_neigh_alloc(st
*to_ipoib_neigh(neighbour) = neigh;
skb_queue_head_init(&neigh->queue);
+ spin_lock(&ipoib_all_neigh_list_lock);
+ list_add_tail(&neigh->all_neigh_list, &ipoib_all_neigh_list);
+ spin_unlock(&ipoib_all_neigh_list_lock);
return neigh;
}
@@ -818,6 +843,9 @@ void ipoib_neigh_free(struct net_device
++priv->stats.tx_dropped;
dev_kfree_skb_any(skb);
}
+ spin_lock(&ipoib_all_neigh_list_lock);
+ list_del(&neigh->all_neigh_list);
+ spin_unlock(&ipoib_all_neigh_list_lock);
kfree(neigh);
}
@@ -874,6 +902,8 @@ void ipoib_dev_cleanup(struct net_device
/* Delete any child interfaces first */
list_for_each_entry_safe(cpriv, tcpriv, &priv->child_intfs, list) {
+ if (cpriv->dev->master)
+ ipoib_neigh_cleanup_bond(cpriv->dev->master,priv->dev);
unregister_netdev(cpriv->dev);
ipoib_dev_cleanup(cpriv->dev);
free_netdev(cpriv->dev);
@@ -1158,6 +1188,8 @@ static void ipoib_remove_one(struct ib_d
list_for_each_entry_safe(priv, tmp, dev_list, list) {
ib_unregister_event_handler(&priv->event_handler);
flush_scheduled_work();
+ if (priv->dev->master)
+ ipoib_neigh_cleanup_bond(priv->dev->master,priv->dev);
unregister_netdev(priv->dev);
ipoib_dev_cleanup(priv->dev);
@@ -1217,6 +1249,7 @@ err_fs:
static void __exit ipoib_cleanup_module(void)
{
+ ipoib_at_exit = 1;
ib_unregister_client(&ipoib_client);
ib_sa_unregister_client(&ipoib_sa_client);
ipoib_unregister_debugfs();
More information about the general
mailing list