[openib-general] [PATCH] ib_mad.c: On completion, use first entry rather than walking send/receive lists

Hal Rosenstock halr at voltaire.com
Mon Sep 13 05:43:14 PDT 2004


ib_mad.c: On completion, use first entry rather than walking
send/receive lists

Index: ib_mad.c
===================================================================
--- ib_mad.c	(revision 795)
+++ ib_mad.c	(working copy)
@@ -144,7 +144,10 @@
 				goto error1;
 			}
 		} else if (mad_reg_req->mgmt_class == 0) {
-			/* Class 0 is reserved and used for aliasing
IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE */
+			/* 
+			 * Class 0 is reserved in IBA and is used here for 
+			 * aliasing of IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE
+			 */
 			ret = ERR_PTR(-EINVAL);
 			goto error1;
 		}
@@ -564,31 +567,31 @@
 				     struct ib_wc *wc)
 {
 	struct ib_mad_recv_wc recv_wc;
-	struct ib_mad_private_header *entry, *temp;
-	struct ib_mad_private *recv = NULL;
+	struct ib_mad_private *recv;
 	unsigned long flags;
 	u32 qp_num;
 
 	/* WC WRID is the QP number */
 	qp_num = wc->wr_id;
 
-	/* Find entry on posted MAD receive list which corresponds to this
completion */
+	/* 
+	 * Completion corresponds to first entry on 
+	 * posted MAD receive list based on WRID in completion
+	 */
 	spin_lock_irqsave(&priv->recv_list_lock, flags);
-	list_for_each_entry_safe(entry, temp,
-				 &priv->recv_posted_mad_list[convert_qpnum(qp_num)],
-				 mad_list) {
-		if ((unsigned long)entry == wc->wr_id) {
-			recv = (struct ib_mad_private *)entry;	
-			/* Remove from posted receive MAD list */
-			list_del(&entry->mad_list);
-			priv->recv_posted_mad_count[convert_qpnum(qp_num)]--;
-			break;
-		}
+	if (!list_empty(&priv->recv_posted_mad_list[convert_qpnum(qp_num)])) {
+		recv = list_entry(&priv->recv_posted_mad_list[convert_qpnum(qp_num)],
+				  struct ib_mad_private,
+				  header.mad_list);
+		/* Remove from posted receive MAD list */
+		list_del(&recv->header.mad_list);
+		priv->recv_posted_mad_count[convert_qpnum(qp_num)]--;
+	} else {
+		printk(KERN_ERR "Receive completion WR ID 0x%Lx on QP %d with no
posted receive\n", wc->wr_id, qp_num); 
+		spin_unlock_irqrestore(&priv->recv_list_lock, flags);
+		return;
 	}
 	spin_unlock_irqrestore(&priv->recv_list_lock, flags);
-	if (!recv) {
-		printk(KERN_ERR "No matching posted receive WR 0x%Lx\n", wc->wr_id);
-	}
 
 	/* Setup MAD receive work completion from normal one */
 	recv_wc.wr_id = wc->wr_id;
@@ -609,43 +612,51 @@
 	recv_wc.sl = wc->sl;
 	recv_wc.dlid_path_bits = wc->dlid_path_bits;
 
-	/* Need to figure out MAD agent !!! */
+	/* Determine corresponding MAD agent for incoming receive MAD */
 
 	/* Invoke client receive callback */
 
-	/* Receive reposting ?  !!! */
+	/* When to repost receive request ?  !!! */
 }
 
 static void ib_mad_send_done_handler(struct ib_mad_port_private *priv,
 				     struct ib_wc *wc)
 {
-	struct ib_mad_send_wr_private *entry, *temp, *send_wr = NULL;
+	struct ib_mad_send_wr_private *send_wr;
 	unsigned long flags;
 
-	/* Find entry on posted MAD send list which corresponds to this
completion */
+	/* Completion corresponds to first entry on posted MAD send list */
 	spin_lock_irqsave(&priv->send_list_lock, flags);
-	list_for_each_entry_safe(entry, temp,
-				 &priv->send_posted_mad_list, send_list) {
-		if (entry->wr_id == wc->wr_id) {
-			send_wr = entry;
-			/* Remove from posted send MAD list */
-			list_del(&entry->send_list);
-			priv->send_posted_mad_count--;	
-			break;
+	if (!list_empty(&priv->send_posted_mad_list)) {
+		send_wr = list_entry(&priv->send_posted_mad_list,
+				     struct ib_mad_send_wr_private,
+				     send_list);
+		if (send_wr->wr_id != wc->wr_id) {
+			printk(KERN_ERR "Send completion WR ID 0x%Lx doesn't match posted
send WR ID 0x%Lx\n", wc->wr_id, send_wr->wr_id);
+			
+			goto error;
 		}
+		/* Remove from posted send MAD list */
+		list_del(&send_wr->send_list);
+		priv->send_posted_mad_count--;
+	} else {
+		printk(KERN_ERR "Send completion  WR ID 0x%Lx but send list is
empty\n", wc->wr_id);
+		goto error;
 	}
 	spin_unlock_irqrestore(&priv->send_list_lock, flags);
-	if (!send_wr) {
-		printk(KERN_ERR "No matching posted send WR 0x%Lx\n", wc->wr_id);
-	} else {
-		/* Restore client wr_id in WC */
-		wc->wr_id = send_wr->wr_id;
-		/* Invoke client send callback */
-		send_wr->agent->send_handler(send_wr->agent,
-					     (struct ib_mad_send_wc *)wc);	
-		/* Release send MAD WR tracking structure */
-		kfree(send_wr);
-	}
+
+	/* Restore client wr_id in WC */
+	wc->wr_id = send_wr->wr_id;
+	/* Invoke client send callback */
+	send_wr->agent->send_handler(send_wr->agent,
+				     (struct ib_mad_send_wc *)wc);	
+	/* Release send MAD WR tracking structure */
+	kfree(send_wr);
+	return;
+
+error:
+	spin_unlock_irqrestore(&priv->send_list_lock, flags);
+	return;
 }
 
 /*





More information about the general mailing list