diff -Naur orig/drivers/infiniband/ulp/ipoib/ipoib_main.c linux-2.6.18.x86_64/drivers/infiniband/ulp/ipoib/ipoib_main.c
--- orig/drivers/infiniband/ulp/ipoib/ipoib_main.c	2010-08-27 12:11:44.000000000 -0700
+++ linux-2.6.18.x86_64/drivers/infiniband/ulp/ipoib/ipoib_main.c	2010-08-27 15:20:33.000000000 -0700
@@ -915,6 +915,7 @@
 	if (!neigh)
 		return NULL;
 
+	neigh_hold(neighbour);
 	neigh->neighbour = neighbour;
 	neigh->dev = dev;
 	memset(&neigh->dgid.raw, 0, sizeof(union ib_gid));
@@ -928,6 +929,7 @@
 void ipoib_neigh_free(struct net_device *dev, struct ipoib_neigh *neigh)
 {
 	struct sk_buff *skb;
+	struct neighbour *neighbour = neigh->neighbour;
 	struct ipoib_dev_priv *priv = netdev_priv(dev);
 	*to_ipoib_neigh(neigh->neighbour) = NULL;
 	while ((skb = __skb_dequeue(&neigh->queue))) {
@@ -937,6 +939,7 @@
 	if (ipoib_cm_get(neigh))
 		ipoib_cm_destroy_tx(ipoib_cm_get(neigh));
 	kfree(neigh);
+	neigh_release(neighbour);
 }
 
 static int ipoib_neigh_setup_dev(struct net_device *dev, struct neigh_parms *parms)
@@ -1466,6 +1469,8 @@
 		goto err_sa;
 	}
 
+	/* we explode on rmmod */
+	__module_get(THIS_MODULE);
 	return 0;
 
 err_sa:
