[openib-general] Re: PD dealloc and AH busy problems remain

Roland Dreier roland at topspin.com
Thu Nov 11 20:41:23 PST 2004


    Hal> but they are not (just in case you thought they should). The
    Hal> PD alloc problem is now intermittent on IPoIB module removal
    Hal> (an improvement). AH busy on mthca module removal is still
    Hal> regular.

Thanks for pointing this out, it was the kick in the rear I needed to
really investigate this.  It turns out there were two bugs (I think).
In any case my logs are clean with these changes.

 - R.

Index: infiniband/core/sa_query.c
===================================================================
--- infiniband/core/sa_query.c	(revision 1212)
+++ infiniband/core/sa_query.c	(working copy)
@@ -632,7 +632,7 @@
 }
 EXPORT_SYMBOL(ib_sa_mcmember_rec_query);
 
-static void send_handler(struct ib_mad_agent *mad_agent,
+static void send_handler(struct ib_mad_agent *agent,
 			 struct ib_mad_send_wc *mad_send_wc)
 {
 	struct ib_sa_query *query;
@@ -660,6 +660,12 @@
 		break;
 	}
 
+	pci_unmap_single(agent->device->dma_device,
+			 pci_unmap_addr(query, mapping),
+			 sizeof (struct ib_sa_mad),
+			 PCI_DMA_TODEVICE);
+	kref_put(&query->sm_ah->ref, free_sm_ah);
+
 	query->release(query);
 
 	spin_lock_irqsave(&idr_lock, flags);



Index: infiniband/ulp/ipoib/ipoib_verbs.c
===================================================================
--- infiniband/ulp/ipoib/ipoib_verbs.c	(revision 1217)
+++ infiniband/ulp/ipoib/ipoib_verbs.c	(working copy)
@@ -210,7 +210,7 @@
 {
 	struct ipoib_dev_priv *priv = netdev_priv(dev);
 
-	if (priv->qp != NULL) {
+	if (priv->qp) {
 		if (ib_destroy_qp(priv->qp))
 			ipoib_warn(priv, "ib_qp_destroy failed\n");
 
Index: infiniband/ulp/ipoib/ipoib_main.c
===================================================================
--- infiniband/ulp/ipoib/ipoib_main.c	(revision 1212)
+++ infiniband/ulp/ipoib/ipoib_main.c	(working copy)
@@ -306,10 +306,6 @@
 	if (status)
 		goto err;
 
-	ah = kmalloc(sizeof *ah, GFP_KERNEL);
-	if (!ah)
-		goto err;
-
 	{
 		struct ib_ah_attr av = {
 			.dlid 	       = be16_to_cpu(pathrec->dlid),
@@ -320,13 +316,11 @@
 			.port_num      = priv->port
 		};
 
-		ah->ah = ib_create_ah(priv->pd, &av);
+		ah = ipoib_create_ah(skb->dev, priv->pd, &av);
 	}
 
-	if (IS_ERR(ah->ah)) {
-		kfree(ah);
+	if (!ah)
 		goto err;
-	}
 
 	*(struct ipoib_ah **) skb->cb = ah;
 
@@ -459,13 +453,17 @@
 				return 0;
 			}
 
-			if (be16_to_cpup((u16 *) skb->data) != ETH_P_ARP)
+			if (be16_to_cpup((u16 *) skb->data) != ETH_P_ARP) {
 				ipoib_warn(priv, "Unicast, no %s: type %04x, QPN %06x "
 					   IPOIB_GID_FMT "\n",
 					   skb->dst ? "neigh" : "dst",
 					   be16_to_cpup((u16 *) skb->data),
 					   be32_to_cpup((u32 *) phdr->hwaddr),
 					   IPOIB_GID_ARG(*(union ib_gid *) (phdr->hwaddr + 4)));
+				dev_kfree_skb_any(skb);
+				++priv->stats.tx_dropped;
+				return 0;
+			}
 
 			/* put the pseudoheader back on */			  
 			skb_push(skb, sizeof *phdr);
Index: infiniband/ulp/ipoib/ipoib_ib.c
===================================================================
--- infiniband/ulp/ipoib/ipoib_ib.c	(revision 1216)
+++ infiniband/ulp/ipoib/ipoib_ib.c	(working copy)
@@ -48,7 +48,8 @@
 	if (IS_ERR(ah->ah)) {
 		kfree(ah);
 		ah = NULL;
-	}
+	} else
+		ipoib_dbg(netdev_priv(dev), "Created ah %p\n", ah->ah);
 
 	return ah;
 }
@@ -61,7 +62,12 @@
 	unsigned long flags;
 
 	spin_lock_irqsave(&priv->lock, flags);
-	list_add_tail(&ah->list, &priv->dead_ahs);
+	if (ah->last_send <= priv->tx_tail) {
+		ipoib_dbg(priv, "Freeing ah %p\n", ah->ah);
+		ib_destroy_ah(ah->ah);
+		kfree(ah);
+	} else
+		list_add_tail(&ah->list, &priv->dead_ahs);
 	spin_unlock_irqrestore(&priv->lock, flags);
 }
 



More information about the general mailing list