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