mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Roland Dreier <roland@topspin.com>
To: akpm@osdl.org
Cc: linux-kernel@vger.kernel.org, openib-general@openib.org
Subject: [PATCH][12/18] InfiniBand/core: fix handling of 0-hop directed route MADs
Date: Wed, 12 Jan 2005 13:48:07 -0800	[thread overview]
Message-ID: <20051121348.Xc0vsayRkBF6BIqu@topspin.com> (raw)
In-Reply-To: <20051121348.wTtIj6K84YZQwY0U@topspin.com>

Handle outgoing DR 0 hop SMPs properly when provider returns just
SUCCESS to process_mad.

Signed-off-by: Hal Rosenstock <halr@voltaire.com>
Signed-off-by: Roland Dreier <roland@topspin.com>

--- linux/drivers/infiniband/core/mad.c	(revision 1501)
+++ linux/drivers/infiniband/core/mad.c	(revision 1502)
@@ -60,6 +60,9 @@
 static int method_in_use(struct ib_mad_mgmt_method_table **method,
 			 struct ib_mad_reg_req *mad_reg_req);
 static void remove_mad_reg_req(struct ib_mad_agent_private *priv);
+static struct ib_mad_agent_private *find_mad_agent(
+					struct ib_mad_port_private *port_priv,
+					struct ib_mad *mad, int solicited);
 static int ib_mad_post_receive_mads(struct ib_mad_qp_info *qp_info,
 				    struct ib_mad_private *mad);
 static void cancel_mads(struct ib_mad_agent_private *mad_agent_priv);
@@ -623,10 +626,12 @@
 				  struct ib_smp *smp,
 				  struct ib_send_wr *send_wr)
 {
-	int ret, alloc_flags;
+	int ret, alloc_flags, solicited;
 	unsigned long flags;
 	struct ib_mad_local_private *local;
 	struct ib_mad_private *mad_priv;
+	struct ib_mad_port_private *port_priv;
+	struct ib_mad_agent_private *recv_mad_agent = NULL;
 	struct ib_device *device = mad_agent_priv->agent.device;
 	u8 port_num = mad_agent_priv->agent.port_num;
 
@@ -651,6 +656,7 @@
 		goto out;
 	}
 	local->mad_priv = NULL;
+	local->recv_mad_agent = NULL;
 	mad_priv = kmem_cache_alloc(ib_mad_cache, alloc_flags);
 	if (!mad_priv) {
 		ret = -ENOMEM;
@@ -669,19 +675,41 @@
 		 * there is a recv handler
 		 */
 		if (solicited_mad(&mad_priv->mad.mad) &&
-		    mad_agent_priv->agent.recv_handler)
+		    mad_agent_priv->agent.recv_handler) {
 			local->mad_priv = mad_priv;
-		else
+			local->recv_mad_agent = mad_agent_priv;
+			/*
+			 * Reference MAD agent until receive 
+			 * side of local completion handled
+			 */
+			atomic_inc(&mad_agent_priv->refcount);
+		} else
 			kmem_cache_free(ib_mad_cache, mad_priv);
 		break;
 	case IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_CONSUMED:
 		kmem_cache_free(ib_mad_cache, mad_priv);
 		break;
 	case IB_MAD_RESULT_SUCCESS:
-		kmem_cache_free(ib_mad_cache, mad_priv);
-		kfree(local);
-		ret = 0;
-		goto out;
+		/* Treat like an incoming receive MAD */
+		solicited = solicited_mad(&mad_priv->mad.mad);
+		port_priv = ib_get_mad_port(mad_agent_priv->agent.device,
+					    mad_agent_priv->agent.port_num);
+		if (port_priv) {
+			mad_priv->mad.mad.mad_hdr.tid =
+				((struct ib_mad *)smp)->mad_hdr.tid;
+			recv_mad_agent = find_mad_agent(port_priv,
+						       &mad_priv->mad.mad,
+							solicited);
+		}
+		if (!port_priv || !recv_mad_agent) {
+			kmem_cache_free(ib_mad_cache, mad_priv);
+			kfree(local);
+			ret = 0;
+			goto out;
+		}
+		local->mad_priv = mad_priv;
+		local->recv_mad_agent = recv_mad_agent;
+		break;
 	default:
 		kmem_cache_free(ib_mad_cache, mad_priv);
 		kfree(local);
@@ -696,7 +724,7 @@
 	local->send_wr.next = NULL;
 	local->tid = send_wr->wr.ud.mad_hdr->tid;
 	local->wr_id = send_wr->wr_id;
-	/* Reference MAD agent until local completion handled */
+	/* Reference MAD agent until send side of local completion handled */
 	atomic_inc(&mad_agent_priv->refcount);
 	/* Queue local completion to local list */
 	spin_lock_irqsave(&mad_agent_priv->lock, flags);
@@ -1997,6 +2025,7 @@
 {
 	struct ib_mad_agent_private *mad_agent_priv;
 	struct ib_mad_local_private *local;
+	struct ib_mad_agent_private *recv_mad_agent;
 	unsigned long flags;
 	struct ib_wc wc;
 	struct ib_mad_send_wc mad_send_wc;
@@ -2010,6 +2039,13 @@
 				   completion_list);
 		spin_unlock_irqrestore(&mad_agent_priv->lock, flags);
 		if (local->mad_priv) {
+			recv_mad_agent = local->recv_mad_agent;
+			if (!recv_mad_agent) {
+				printk(KERN_ERR PFX "No receive MAD agent for local completion\n");
+				kmem_cache_free(ib_mad_cache, local->mad_priv);
+				goto local_send_completion;
+			}
+
 			/*
 			 * Defined behavior is to complete response
 			 * before request
@@ -2034,15 +2070,19 @@
 			local->mad_priv->header.recv_wc.recv_buf.grh = NULL;
 			local->mad_priv->header.recv_wc.recv_buf.mad =
 						&local->mad_priv->mad.mad;
-			if (atomic_read(&mad_agent_priv->qp_info->snoop_count))
-				snoop_recv(mad_agent_priv->qp_info,
+			if (atomic_read(&recv_mad_agent->qp_info->snoop_count))
+				snoop_recv(recv_mad_agent->qp_info,
 					  &local->mad_priv->header.recv_wc,
 					   IB_MAD_SNOOP_RECVS);
-			mad_agent_priv->agent.recv_handler(
-						&mad_agent_priv->agent,
+			recv_mad_agent->agent.recv_handler(
+						&recv_mad_agent->agent,
 						&local->mad_priv->header.recv_wc);
+			spin_lock_irqsave(&recv_mad_agent->lock, flags);
+			atomic_dec(&recv_mad_agent->refcount);
+			spin_unlock_irqrestore(&recv_mad_agent->lock, flags);
 		}
 
+local_send_completion:
 		/* Complete send */
 		mad_send_wc.status = IB_WC_SUCCESS;
 		mad_send_wc.vendor_err = 0;
--- linux/drivers/infiniband/core/mad_priv.h	(revision 1501)
+++ linux/drivers/infiniband/core/mad_priv.h	(revision 1502)
@@ -127,6 +127,7 @@
 struct ib_mad_local_private {
 	struct list_head completion_list;
 	struct ib_mad_private *mad_priv;
+	struct ib_mad_agent_private *recv_mad_agent;
 	struct ib_send_wr send_wr;
 	struct ib_sge sg_list[IB_MAD_SEND_REQ_MAX_SG];
 	u64 wr_id;			/* client WR ID */


  reply	other threads:[~2005-01-12 21:59 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-01-12 21:47 [PATCH][0/18] InfiniBand: updates for 2.6.11-rc1 Roland Dreier
2005-01-12 21:47 ` [PATCH][1/18] InfiniBand/IPoIB: use correct static rate in IpoIB Roland Dreier
2005-01-12 21:47   ` [PATCH][2/18] InfiniBand/mthca: trivial formatting fix Roland Dreier
2005-01-12 21:47     ` [PATCH][3/18] InfiniBand/mthca: support RDMA/atomic attributes in QP modify Roland Dreier
2005-01-12 21:47       ` [PATCH][4/18] InfiniBand/mthca: clean up allocation mapping of HCA context memory Roland Dreier
2005-01-12 21:47         ` [PATCH][5/18] InfiniBand/mthca: add needed rmb() in event queue poll Roland Dreier
2005-01-12 21:47           ` [PATCH][6/18] InfiniBand/core: remove debug printk Roland Dreier
2005-01-12 21:47             ` [PATCH][7/18] InfiniBand: make more code static Roland Dreier
2005-01-12 21:47               ` [PATCH][8/18] InfiniBand/core: set byte_cnt correctly in MAD completion Roland Dreier
2005-01-12 21:47                 ` [PATCH][9/18] InfiniBand/core: add QP number to work completion struct Roland Dreier
2005-01-12 21:47                   ` [PATCH][10/18] InfiniBand/core: add node_type and phys_state sysfs attrs Roland Dreier
2005-01-12 21:48                     ` [PATCH][11/18] InfiniBand/mthca: clean up computation of HCA memory map Roland Dreier
2005-01-12 21:48                       ` Roland Dreier [this message]
2005-01-12 21:48                         ` [PATCH][13/18] InfiniBand/core: add more parameters to process_mad Roland Dreier
2005-01-12 21:48                           ` [PATCH][14/18] InfiniBand/core: add qp_type to struct ib_qp Roland Dreier
2005-01-12 21:48                             ` [PATCH][15/18] InfiniBand/core: add ib_find_cached_gid function Roland Dreier
2005-01-12 21:48                               ` [PATCH][16/18] InfiniBand: update copyrights for new year Roland Dreier
2005-01-12 21:48                                 ` [PATCH][17/18] InfiniBand/ipoib: move structs from stack to device private struct Roland Dreier
2005-01-12 21:48                                   ` [PATCH][18/18] InfiniBand/core: rename handle_outgoing_smp Roland Dreier
2005-01-13  9:45           ` [openib-general] [PATCH][5/18] InfiniBand/mthca: add needed rmb() in event queue poll Michael S. Tsirkin
2005-01-13 15:32             ` Roland Dreier

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20051121348.Xc0vsayRkBF6BIqu@topspin.com \
    --to=roland@topspin.com \
    --cc=akpm@osdl.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=openib-general@openib.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®