diff -urpN infiniband-split-cq/ulp/ipoib/ipoib.h infiniband-ah/ulp/ipoib/ipoib.h
--- infiniband-split-cq/ulp/ipoib/ipoib.h	2006-05-23 10:07:15.000000000 -0700
+++ infiniband-ah/ulp/ipoib/ipoib.h	2006-05-23 10:09:05.000000000 -0700
@@ -86,7 +86,6 @@ enum {
 	IPOIB_PKEY_STOP 	  = 4,
 	IPOIB_FLAG_SUBINTERFACE   = 5,
 	IPOIB_MCAST_RUN 	  = 6,
-	IPOIB_STOP_REAPER         = 7,
 	IPOIB_MCAST_STARTED       = 8,
 
 	IPOIB_MAX_BACKOFF_SECONDS = 16,
@@ -147,7 +146,6 @@ struct ipoib_dev_priv {
 	struct work_struct mcast_task;
 	struct work_struct flush_task;
 	struct work_struct restart_task;
-	struct work_struct ah_reap_task;
 
 	struct ib_device *ca;
 	u8            	  port;
@@ -197,7 +195,6 @@ struct ipoib_ah {
 	struct ib_ah      *ah;
 	struct list_head   list;
 	struct kref        ref;
-	unsigned           last_send;
 };
 
 struct ipoib_path {
@@ -263,7 +260,6 @@ int ipoib_add_pkey_attr(struct net_devic
 
 void ipoib_send(struct net_device *dev, struct sk_buff *skb,
 		struct ipoib_ah *address, u32 qpn);
-void ipoib_reap_ah(void *dev_ptr);
 
 void ipoib_flush_paths(struct net_device *dev);
 struct ipoib_dev_priv *ipoib_intf_alloc(const char *format);
diff -urpN infiniband-split-cq/ulp/ipoib/ipoib_ib.c infiniband-ah/ulp/ipoib/ipoib_ib.c
--- infiniband-split-cq/ulp/ipoib/ipoib_ib.c	2006-05-23 10:07:51.000000000 -0700
+++ infiniband-ah/ulp/ipoib/ipoib_ib.c	2006-05-23 10:14:08.000000000 -0700
@@ -65,7 +65,6 @@ struct ipoib_ah *ipoib_create_ah(struct 
 		return NULL;
 
 	ah->dev       = dev;
-	ah->last_send = 0;
 	kref_init(&ah->ref);
 
 	ah->ah = ib_create_ah(pd, attr);
@@ -83,17 +82,9 @@ void ipoib_free_ah(struct kref *kref)
 	struct ipoib_ah *ah = container_of(kref, struct ipoib_ah, ref);
 	struct ipoib_dev_priv *priv = netdev_priv(ah->dev);
 
-	unsigned long flags;
-
-	if ((int) priv->tx_tail - (int) ah->last_send >= 0) {
-		ipoib_dbg(priv, "Freeing ah %p\n", ah->ah);
-		ib_destroy_ah(ah->ah);
-		kfree(ah);
-	} else {
-		spin_lock_irqsave(&priv->lock, flags);
-		list_add_tail(&ah->list, &priv->dead_ahs);
-		spin_unlock_irqrestore(&priv->lock, flags);
-	}
+	ipoib_dbg(priv, "Freeing ah %p\n", ah->ah);
+	ib_destroy_ah(ah->ah);
+	kfree(ah);
 }
 
 static int ipoib_ib_post_receive(struct net_device *dev, int id)
@@ -344,13 +335,16 @@ void ipoib_send(struct net_device *dev, 
 	struct ipoib_dev_priv *priv = netdev_priv(dev);
 	struct ipoib_tx_buf *tx_req;
 	dma_addr_t addr;
+	int err;
 
+	kref_get(&address->ref);
 	if (skb->len > dev->mtu + INFINIBAND_ALEN) {
 		ipoib_warn(priv, "packet len %d (> %d) too long to send, dropping\n",
 			   skb->len, dev->mtu + INFINIBAND_ALEN);
 		++priv->stats.tx_dropped;
 		++priv->stats.tx_errors;
 		dev_kfree_skb_any(skb);
+		kref_put(&address->ref, ipoib_free_ah);
 		return;
 	}
 
@@ -370,8 +364,10 @@ void ipoib_send(struct net_device *dev, 
 			      DMA_TO_DEVICE);
 	pci_unmap_addr_set(tx_req, mapping, addr);
 
-	if (unlikely(post_send(priv, priv->tx_head & (ipoib_sendq_size - 1),
-			       address->ah, qpn, addr, skb->len))) {
+	err = post_send(priv, priv->tx_head & (ipoib_sendq_size - 1),	
+			address->ah, qpn, addr, skb->len); 
+	kref_put(&address->ref, ipoib_free_ah);
+	if (unlikely(err)) {
 		ipoib_warn(priv, "post_send failed\n");
 		++priv->stats.tx_errors;
 		dma_unmap_single(priv->ca->dma_device, addr, skb->len,
@@ -380,7 +376,6 @@ void ipoib_send(struct net_device *dev, 
 	} else {
 		dev->trans_start = jiffies;
 
-		address->last_send = priv->tx_head;
 		++priv->tx_head;
 
 		if (priv->tx_head - priv->tx_tail == ipoib_sendq_size) {
@@ -390,38 +385,6 @@ void ipoib_send(struct net_device *dev, 
 	}
 }
 
-static void __ipoib_reap_ah(struct net_device *dev)
-{
-	struct ipoib_dev_priv *priv = netdev_priv(dev);
-	struct ipoib_ah *ah, *tah;
-	LIST_HEAD(remove_list);
-
-	spin_lock_irq(&priv->lock);
-	list_for_each_entry_safe(ah, tah, &priv->dead_ahs, list)
-		if ((int) priv->tx_tail - (int) ah->last_send >= 0) {
-			list_del(&ah->list);
-			list_add_tail(&ah->list, &remove_list);
-		}
-	spin_unlock_irq(&priv->lock);
-
-	list_for_each_entry_safe(ah, tah, &remove_list, list) {
-		ipoib_dbg(priv, "Reaping ah %p\n", ah->ah);
-		ib_destroy_ah(ah->ah);
-		kfree(ah);
-	}
-}
-
-void ipoib_reap_ah(void *dev_ptr)
-{
-	struct net_device *dev = dev_ptr;
-	struct ipoib_dev_priv *priv = netdev_priv(dev);
-
-	__ipoib_reap_ah(dev);
-
-	if (!test_bit(IPOIB_STOP_REAPER, &priv->flags))
-		queue_delayed_work(ipoib_workqueue, &priv->ah_reap_task, HZ);
-}
-
 int ipoib_ib_dev_open(struct net_device *dev)
 {
 	struct ipoib_dev_priv *priv = netdev_priv(dev);
@@ -440,9 +403,6 @@ int ipoib_ib_dev_open(struct net_device 
 		return -1;
 	}
 
-	clear_bit(IPOIB_STOP_REAPER, &priv->flags);
-	queue_delayed_work(ipoib_workqueue, &priv->ah_reap_task, HZ);
-
 	set_bit(IPOIB_FLAG_INITIALIZED, &priv->flags);
 
 	return 0;
@@ -580,24 +540,6 @@ timeout:
 	if (ib_modify_qp(priv->qp, &qp_attr, IB_QP_STATE))
 		ipoib_warn(priv, "Failed to modify QP to RESET state\n");
 
-	/* Wait for all AHs to be reaped */
-	set_bit(IPOIB_STOP_REAPER, &priv->flags);
-	cancel_delayed_work(&priv->ah_reap_task);
-	flush_workqueue(ipoib_workqueue);
-
-	begin = jiffies;
-
-	while (!list_empty(&priv->dead_ahs)) {
-		__ipoib_reap_ah(dev);
-
-		if (time_after(jiffies, begin + HZ)) {
-			ipoib_warn(priv, "timing out; will leak address handles\n");
-			break;
-		}
-
-		msleep(1);
-	}
-
 	return 0;
 }
 
diff -urpN infiniband-split-cq/ulp/ipoib/ipoib_main.c infiniband-ah/ulp/ipoib/ipoib_main.c
--- infiniband-split-cq/ulp/ipoib/ipoib_main.c	2006-05-22 08:48:47.000000000 -0700
+++ infiniband-ah/ulp/ipoib/ipoib_main.c	2006-05-23 09:31:49.000000000 -0700
@@ -957,7 +957,6 @@ static void ipoib_setup(struct net_devic
 	INIT_WORK(&priv->mcast_task,   ipoib_mcast_join_task,    priv->dev);
 	INIT_WORK(&priv->flush_task,   ipoib_ib_dev_flush,       priv->dev);
 	INIT_WORK(&priv->restart_task, ipoib_mcast_restart_task, priv->dev);
-	INIT_WORK(&priv->ah_reap_task, ipoib_reap_ah,            priv->dev);
 }
 
 struct ipoib_dev_priv *ipoib_intf_alloc(const char *name)
