[ofa-general] [PATCHv5 03/10] ib_core: RDMAoE support only QP1

Eli Cohen eli at mellanox.co.il
Wed Aug 19 07:38:59 PDT 2009


Since RDMAoE is using Ethernet as its link layer, there is no need for QP0. QP1
is still needed since it handles communications between CM agents. This patch
will create only QP1 for RDMAoE ports.

Signed-off-by: Eli Cohen <eli at mellanox.co.il>
---
Changes from previous version:

1. Instead of returning NULL for unsupported ports (which is no
considered an error), now callers of ib_register_mad_agent() must
verify that the port/special QP is supported before calling this
function.
2. Make use of rdma_is_transport_supported() where appropriate.


 drivers/infiniband/core/agent.c |   38 +++++++++++++++++++++++++-------------
 drivers/infiniband/core/mad.c   |   37 +++++++++++++++++++++++++++++--------
 2 files changed, 54 insertions(+), 21 deletions(-)

diff --git a/drivers/infiniband/core/agent.c b/drivers/infiniband/core/agent.c
index ae7c288..c130a4a 100644
--- a/drivers/infiniband/core/agent.c
+++ b/drivers/infiniband/core/agent.c
@@ -48,6 +48,8 @@
 struct ib_agent_port_private {
 	struct list_head port_list;
 	struct ib_mad_agent *agent[2];
+	struct ib_device    *device;
+	u8		     port_num;
 };
 
 static DEFINE_SPINLOCK(ib_agent_port_list_lock);
@@ -58,11 +60,10 @@ __ib_get_agent_port(struct ib_device *device, int port_num)
 {
 	struct ib_agent_port_private *entry;
 
-	list_for_each_entry(entry, &ib_agent_port_list, port_list) {
-		if (entry->agent[0]->device == device &&
-		    entry->agent[0]->port_num == port_num)
+	list_for_each_entry(entry, &ib_agent_port_list, port_list)
+		if (entry->device == device && entry->port_num == port_num)
 			return entry;
-	}
+
 	return NULL;
 }
 
@@ -146,6 +147,7 @@ int ib_agent_port_open(struct ib_device *device, int port_num)
 	struct ib_agent_port_private *port_priv;
 	unsigned long flags;
 	int ret;
+	enum rdma_transport_type tt;
 
 	/* Create new device info */
 	port_priv = kzalloc(sizeof *port_priv, GFP_KERNEL);
@@ -155,14 +157,17 @@ int ib_agent_port_open(struct ib_device *device, int port_num)
 		goto error1;
 	}
 
-	/* Obtain send only MAD agent for SMI QP */
-	port_priv->agent[0] = ib_register_mad_agent(device, port_num,
-						    IB_QPT_SMI, NULL, 0,
-						    &agent_send_handler,
-						    NULL, NULL);
-	if (IS_ERR(port_priv->agent[0])) {
-		ret = PTR_ERR(port_priv->agent[0]);
-		goto error2;
+	tt = rdma_port_get_transport(device, port_num);
+	if (tt == RDMA_TRANSPORT_IB) {
+		/* Obtain send only MAD agent for SMI QP */
+		port_priv->agent[0] = ib_register_mad_agent(device, port_num,
+							    IB_QPT_SMI, NULL, 0,
+							    &agent_send_handler,
+							    NULL, NULL);
+		if (IS_ERR(port_priv->agent[0])) {
+			ret = PTR_ERR(port_priv->agent[0]);
+			goto error2;
+		}
 	}
 
 	/* Obtain send only MAD agent for GSI QP */
@@ -175,6 +180,9 @@ int ib_agent_port_open(struct ib_device *device, int port_num)
 		goto error3;
 	}
 
+	port_priv->device = device;
+	port_priv->port_num = port_num;
+
 	spin_lock_irqsave(&ib_agent_port_list_lock, flags);
 	list_add_tail(&port_priv->port_list, &ib_agent_port_list);
 	spin_unlock_irqrestore(&ib_agent_port_list_lock, flags);
@@ -182,7 +190,8 @@ int ib_agent_port_open(struct ib_device *device, int port_num)
 	return 0;
 
 error3:
-	ib_unregister_mad_agent(port_priv->agent[0]);
+	if (tt == RDMA_TRANSPORT_IB)
+		ib_unregister_mad_agent(port_priv->agent[0]);
 error2:
 	kfree(port_priv);
 error1:
@@ -194,6 +203,9 @@ int ib_agent_port_close(struct ib_device *device, int port_num)
 	struct ib_agent_port_private *port_priv;
 	unsigned long flags;
 
+	if (rdma_port_get_transport(device, port_num) != RDMA_TRANSPORT_IB)
+		return 0;
+
 	spin_lock_irqsave(&ib_agent_port_list_lock, flags);
 	port_priv = __ib_get_agent_port(device, port_num);
 	if (port_priv == NULL) {
diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c
index c06117c..aceae79 100644
--- a/drivers/infiniband/core/mad.c
+++ b/drivers/infiniband/core/mad.c
@@ -2602,6 +2602,9 @@ static void cleanup_recv_queue(struct ib_mad_qp_info *qp_info)
 	struct ib_mad_private *recv;
 	struct ib_mad_list_head *mad_list;
 
+	if (!qp_info->qp)
+		return;
+
 	while (!list_empty(&qp_info->recv_queue.list)) {
 
 		mad_list = list_entry(qp_info->recv_queue.list.next,
@@ -2643,6 +2646,9 @@ static int ib_mad_port_start(struct ib_mad_port_private *port_priv)
 
 	for (i = 0; i < IB_MAD_QPS_CORE; i++) {
 		qp = port_priv->qp_info[i].qp;
+		if (!qp)
+			continue;
+
 		/*
 		 * PKey index for QP1 is irrelevant but
 		 * one is needed for the Reset to Init transition
@@ -2684,6 +2690,9 @@ static int ib_mad_port_start(struct ib_mad_port_private *port_priv)
 	}
 
 	for (i = 0; i < IB_MAD_QPS_CORE; i++) {
+		if (!port_priv->qp_info[i].qp)
+			continue;
+
 		ret = ib_mad_post_receive_mads(&port_priv->qp_info[i], NULL);
 		if (ret) {
 			printk(KERN_ERR PFX "Couldn't post receive WRs\n");
@@ -2762,6 +2771,9 @@ error:
 
 static void destroy_mad_qp(struct ib_mad_qp_info *qp_info)
 {
+	if (!qp_info->qp)
+		return;
+
 	ib_destroy_qp(qp_info->qp);
 	kfree(qp_info->snoop_table);
 }
@@ -2777,6 +2789,7 @@ static int ib_mad_port_open(struct ib_device *device,
 	struct ib_mad_port_private *port_priv;
 	unsigned long flags;
 	char name[sizeof "ib_mad123"];
+	int has_smi;
 
 	/* Create new device info */
 	port_priv = kzalloc(sizeof *port_priv, GFP_KERNEL);
@@ -2792,7 +2805,11 @@ static int ib_mad_port_open(struct ib_device *device,
 	init_mad_qp(port_priv, &port_priv->qp_info[0]);
 	init_mad_qp(port_priv, &port_priv->qp_info[1]);
 
-	cq_size = (IB_MAD_QP_SEND_SIZE + IB_MAD_QP_RECV_SIZE) * 2;
+	cq_size = IB_MAD_QP_SEND_SIZE + IB_MAD_QP_RECV_SIZE;
+	has_smi = rdma_port_get_transport(device, port_num) == RDMA_TRANSPORT_IB;
+	if (has_smi)
+		cq_size *= 2;
+
 	port_priv->cq = ib_create_cq(port_priv->device,
 				     ib_mad_thread_completion_handler,
 				     NULL, port_priv, cq_size, 0);
@@ -2816,9 +2833,11 @@ static int ib_mad_port_open(struct ib_device *device,
 		goto error5;
 	}
 
-	ret = create_mad_qp(&port_priv->qp_info[0], IB_QPT_SMI);
-	if (ret)
-		goto error6;
+	if (has_smi) {
+		ret = create_mad_qp(&port_priv->qp_info[0], IB_QPT_SMI);
+		if (ret)
+			goto error6;
+	}
 	ret = create_mad_qp(&port_priv->qp_info[1], IB_QPT_GSI);
 	if (ret)
 		goto error7;
@@ -2907,7 +2926,8 @@ static void ib_mad_init_device(struct ib_device *device)
 	int start, end, i;
 	enum rdma_transport_type tt;
 
-	if (!rdma_is_transport_supported(device, RDMA_TRANSPORT_IB))
+	if (!rdma_is_transport_supported(device, RDMA_TRANSPORT_IB) &&
+	    !rdma_is_transport_supported(device, RDMA_TRANSPORT_RDMAOE))
 		return;
 
 	if (device->node_type == RDMA_NODE_IB_SWITCH) {
@@ -2920,7 +2940,7 @@ static void ib_mad_init_device(struct ib_device *device)
 
 	for (i = start; i <= end; i++) {
 		tt = rdma_port_get_transport(device, i);
-		if (tt != RDMA_TRANSPORT_IB)
+		if (tt != RDMA_TRANSPORT_IB && tt != RDMA_TRANSPORT_RDMAOE)
 			continue;
 
 		if (ib_mad_port_open(device, i)) {
@@ -2946,7 +2966,8 @@ error:
 	i--;
 
 	while (i >= start) {
-		if (rdma_port_get_transport(device, i) == RDMA_TRANSPORT_IB) {
+		tt = rdma_port_get_transport(device, i);
+		if (tt == RDMA_TRANSPORT_IB || tt == RDMA_TRANSPORT_RDMAOE) {
 			if (ib_agent_port_close(device, i))
 				printk(KERN_ERR PFX "Couldn't close %s port %d "
 				       "for agents\n",
@@ -2973,7 +2994,7 @@ static void ib_mad_remove_device(struct ib_device *device)
 	}
 	for (i = 0; i < num_ports; i++, cur_port++) {
 		tt = rdma_port_get_transport(device, i);
-		if (tt == RDMA_TRANSPORT_IB) {
+		if (tt == RDMA_TRANSPORT_IB || tt == RDMA_TRANSPORT_RDMAOE) {
 			if (ib_agent_port_close(device, cur_port))
 				printk(KERN_ERR PFX "Couldn't close %s port %d "
 				       "for agents\n",
-- 
1.6.4




More information about the general mailing list