[openib-general] [PATCH] [MAD] expand retry ability to all MADs

Sean Hefty sean.hefty at intel.com
Wed May 11 12:28:47 PDT 2005


The following patch expands the automatic retry ability in the MAD
layer to be usable by all clients, not just RMPP.  Retries are done
using a linear timeout.

Signed-off-by: Sean Hefty <sean.hefty at intel.com>


Index: core/user_mad.c
===================================================================
--- core/user_mad.c	(revision 2306)
+++ core/user_mad.c	(working copy)
@@ -322,6 +322,7 @@ static ssize_t ib_umad_write(struct file
 	wr.wr.ud.remote_qpn  = be32_to_cpu(packet->mad.qpn);
 	wr.wr.ud.remote_qkey = be32_to_cpu(packet->mad.qkey);
 	wr.wr.ud.timeout_ms  = packet->mad.timeout_ms;
+	wr.wr.ud.retries     = 0;
 
 	wr.wr_id            = (unsigned long) packet;
 
Index: core/mad_rmpp.c
===================================================================
--- core/mad_rmpp.c	(revision 2306)
+++ core/mad_rmpp.c	(working copy)
@@ -594,11 +594,9 @@ static int send_next_seg(struct ib_mad_s
 				    mad_send_wr->pad);
 	}
 
-	/* 5 seconds until we can find the packet lifetime */
+	/* 5 seconds for an ACK until we can find the packet lifetime */
 	timeout = mad_send_wr->send_wr.wr.ud.timeout_ms;
-	if (timeout && timeout < 5000)
-		mad_send_wr->timeout = msecs_to_jiffies(timeout);
-	else
+	if (!timeout || timeout > 5000)
 		mad_send_wr->timeout = msecs_to_jiffies(5000);
 	mad_send_wr->seg_num++;
 	return ib_send_mad(mad_send_wr);
@@ -734,7 +732,6 @@ int ib_send_rmpp_mad(struct ib_mad_send_
 			(sizeof(struct ib_rmpp_mad) - mad_send_wr->data_offset);
 	mad_send_wr->pad = total_len - offsetof(struct ib_rmpp_mad, data) -
 			   be32_to_cpu(rmpp_mad->rmpp_hdr.paylen_newwin);
-	mad_send_wr->retries = mad_send_wr->send_wr.wr.ud.retries;
 
 	/* We need to wait for the final ACK even if there isn't a response */
 	mad_send_wr->refcount += (mad_send_wr->timeout == 0);
@@ -787,7 +784,7 @@ int ib_process_rmpp_send_wc(struct ib_ma
 	return IB_RMPP_RESULT_CONSUMED;
 }
 
-int ib_timeout_rmpp(struct ib_mad_send_wr_private *mad_send_wr)
+int ib_retry_rmpp(struct ib_mad_send_wr_private *mad_send_wr)
 {
 	struct ib_rmpp_mad *rmpp_mad;
 	int ret;
@@ -797,8 +794,7 @@ int ib_timeout_rmpp(struct ib_mad_send_w
 	      IB_MGMT_RMPP_FLAG_ACTIVE))
 		return IB_RMPP_RESULT_UNHANDLED; /* RMPP not active */
 
-	if (mad_send_wr->last_ack == mad_send_wr->total_seg ||
-	    !mad_send_wr->retries--)
+	if (mad_send_wr->last_ack == mad_send_wr->total_seg)
 		return IB_RMPP_RESULT_PROCESSED;
 
 	mad_send_wr->seg_num = mad_send_wr->last_ack + 1;
@@ -806,9 +802,5 @@ int ib_timeout_rmpp(struct ib_mad_send_w
 	if (ret)
 		return IB_RMPP_RESULT_PROCESSED;
 
-	mad_send_wr->refcount++;
-	list_del(&mad_send_wr->agent_list);
-	list_add_tail(&mad_send_wr->agent_list,
-		      &mad_send_wr->mad_agent_priv->send_list);
 	return IB_RMPP_RESULT_CONSUMED;
 }
Index: core/mad.c
===================================================================
--- core/mad.c	(revision 2306)
+++ core/mad.c	(working copy)
@@ -971,6 +971,7 @@ int ib_post_send_mad(struct ib_mad_agent
 		/* Timeout will be updated after send completes */
 		mad_send_wr->timeout = msecs_to_jiffies(send_wr->wr.
 							ud.timeout_ms);
+		mad_send_wr->retries = mad_send_wr->send_wr.wr.ud.retries;
 		/* One reference for each work request to QP + response */
 		mad_send_wr->refcount = 1 + (mad_send_wr->timeout > 0);
 		mad_send_wr->status = IB_WC_SUCCESS;
@@ -2233,6 +2234,41 @@ local_send_completion:
 	spin_unlock_irqrestore(&mad_agent_priv->lock, flags);
 }
 
+static int retry_send(struct ib_mad_send_wr_private *mad_send_wr)
+{
+	int ret;
+
+	if (!mad_send_wr->retries--)
+		return -ETIMEDOUT;
+
+	mad_send_wr->timeout = msecs_to_jiffies(mad_send_wr->send_wr.
+						wr.ud.timeout_ms);
+
+	if (mad_send_wr->mad_agent_priv->agent.rmpp_version) {
+		ret = ib_retry_rmpp(mad_send_wr);
+		switch (ret) {
+		case IB_RMPP_RESULT_UNHANDLED:
+			ret = ib_send_mad(mad_send_wr);
+			break;
+		case IB_RMPP_RESULT_CONSUMED:
+			ret = 0;
+			break;
+		default:
+			ret = -ECOMM;
+			break;
+		}
+	} else
+		ret = ib_send_mad(mad_send_wr);
+
+	if (!ret) {
+		mad_send_wr->refcount++;
+		list_del(&mad_send_wr->agent_list);
+		list_add_tail(&mad_send_wr->agent_list,
+			      &mad_send_wr->mad_agent_priv->send_list);
+	}
+	return ret;
+}
+
 static void timeout_sends(void *data)
 {
 	struct ib_mad_agent_private *mad_agent_priv;
@@ -2261,9 +2297,8 @@ static void timeout_sends(void *data)
 			break;
 		}
 
-		if (mad_agent_priv->agent.rmpp_version &&
-		    ib_timeout_rmpp(mad_send_wr) == IB_RMPP_RESULT_CONSUMED)
-				continue;
+		if (!retry_send(mad_send_wr))
+			continue;
 
 		list_del(&mad_send_wr->agent_list);
 		spin_unlock_irqrestore(&mad_agent_priv->lock, flags);
Index: core/mad_rmpp.h
===================================================================
--- core/mad_rmpp.h	(revision 2306)
+++ core/mad_rmpp.h	(working copy)
@@ -55,6 +55,6 @@ int ib_process_rmpp_send_wc(struct ib_ma
 
 void ib_cancel_rmpp_recvs(struct ib_mad_agent_private *agent);
 
-int ib_timeout_rmpp(struct ib_mad_send_wr_private *mad_send_wr);
+int ib_retry_rmpp(struct ib_mad_send_wr_private *mad_send_wr);
 
 #endif	/* __MAD_RMPP_H__ */
Index: core/mad_priv.h
===================================================================
--- core/mad_priv.h	(revision 2306)
+++ core/mad_priv.h	(working copy)
@@ -123,6 +123,7 @@ struct ib_mad_send_wr_private {
 	u64 wr_id;			/* client WR ID */
 	u64 tid;
 	unsigned long timeout;
+	int retries;
 	int retry;
 	int refcount;
 	enum ib_wc_status status;
@@ -134,7 +135,6 @@ struct ib_mad_send_wr_private {
 	int total_seg;
 	int data_offset;
 	int pad;
-	int retries;
 };
 
 struct ib_mad_local_private {
Index: core/sa_query.c
===================================================================
--- core/sa_query.c	(revision 2306)
+++ core/sa_query.c	(working copy)
@@ -442,7 +442,8 @@ static int send_mad(struct ib_sa_query *
 				 .mad_hdr     = &query->mad->mad_hdr,
 				 .remote_qpn  = 1,
 				 .remote_qkey = IB_QP1_QKEY,
-				 .timeout_ms  = timeout_ms
+				 .timeout_ms  = timeout_ms,
+				 .retries     = 0 
 			 }
 		 }
 	};






More information about the general mailing list