[ofa-general] [PATCH 5/6 v2] fix pkey change handling and remove the cahce

Yosef Etigin yosefe at voltaire.com
Mon May 7 05:59:23 PDT 2007


mad: cache port lmc

* Instead of using the ib cache, mad core will keep the up-to-date
  lmc of each port inside port_priv struct. It will be updated by
  incoming PORT_INFO mads.
* use the uncached version of "query gid".
  This query will be cache-optimized in the provider level. 

Signed-off-by: Yosef Etigin <yosefe at voltaire.com>
---
 drivers/infiniband/core/mad.c      |   31 +++++++++++++++++++++++++++----
 drivers/infiniband/core/mad_priv.h |    1 +
 2 files changed, 28 insertions(+), 4 deletions(-)

Index: b/drivers/infiniband/core/mad.c
===================================================================
--- a/drivers/infiniband/core/mad.c	2007-05-07 14:31:49.304874864 +0300
+++ b/drivers/infiniband/core/mad.c	2007-05-07 14:31:59.320086832 +0300
@@ -34,7 +34,6 @@
  * $Id: mad.c 5596 2006-03-03 01:00:07Z sean.hefty $
  */
 #include <linux/dma-mapping.h>
-#include <rdma/ib_cache.h>
 
 #include "mad_priv.h"
 #include "mad_rmpp.h"
@@ -1707,13 +1706,12 @@ static inline int rcv_has_same_gid(struc
 	if (!send_resp && rcv_resp) {
 		/* is request/response. */
 		if (!(attr.ah_flags & IB_AH_GRH)) {
-			if (ib_get_cached_lmc(device, port_num, &lmc))
-				return 0;
+			lmc = atomic_read(&mad_agent_priv->qp_info->port_priv->port_lmc);
 			return (!lmc || !((attr.src_path_bits ^
 					   rwc->wc->dlid_path_bits) &
 					  ((1 << lmc) - 1)));
 		} else {
-			if (ib_get_cached_gid(device, port_num,
+			if (ib_query_gid(device, port_num,
 					      attr.grh.sgid_index, &sgid))
 				return 0;
 			return !memcmp(sgid.raw, rwc->recv_buf.grh->dgid.raw,
@@ -1865,6 +1863,15 @@ static void ib_mad_recv_done_handler(str
 	recv->header.recv_wc.recv_buf.mad = &recv->mad.mad;
 	recv->header.recv_wc.recv_buf.grh = &recv->grh;
 
+	/* update our lmc cache with port info smps */
+	if ((recv->mad.mad.mad_hdr.mgmt_class == IB_MGMT_CLASS_SUBN_LID_ROUTED ||
+	     recv->mad.mad.mad_hdr.mgmt_class == IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE)
+	    && (recv->mad.mad.mad_hdr.attr_id == IB_SMP_ATTR_PORT_INFO)
+		&& (recv->mad.mad.mad_hdr.method == IB_MGMT_METHOD_SET))
+	{
+		atomic_set(&port_priv->port_lmc, recv->mad.smp.data[34] & 0x7);
+	}
+
 	if (atomic_read(&qp_info->snoop_count))
 		snoop_recv(qp_info, &recv->header.recv_wc, IB_MAD_SNOOP_RECVS);
 
@@ -2747,6 +2754,7 @@ static int ib_mad_port_open(struct ib_de
 {
 	int ret, cq_size;
 	struct ib_mad_port_private *port_priv;
+	struct ib_port_attr *port_attr;
 	unsigned long flags;
 	char name[sizeof "ib_mad123"];
 
@@ -2764,6 +2772,19 @@ static int ib_mad_port_open(struct ib_de
 	init_mad_qp(port_priv, &port_priv->qp_info[0]);
 	init_mad_qp(port_priv, &port_priv->qp_info[1]);
 
+	port_attr = kmalloc(sizeof *port_attr, GFP_KERNEL);
+	if (!port_attr) {
+		printk(KERN_ERR PFX "No memory for ib_port_attr\n");
+		return -ENOMEM;
+	}
+
+	if (ib_query_port(device, port_num, port_attr)) {
+		printk(KERN_ERR PFX "Couldn't query port %d\n", port_num);
+		ret = -EINVAL;
+		goto error2;
+	}
+	atomic_set(&port_priv->port_lmc, port_attr->lmc);
+
 	cq_size = (IB_MAD_QP_SEND_SIZE + IB_MAD_QP_RECV_SIZE) * 2;
 	port_priv->cq = ib_create_cq(port_priv->device,
 				     ib_mad_thread_completion_handler,
@@ -2834,6 +2855,8 @@ error4:
 	cleanup_recv_queue(&port_priv->qp_info[1]);
 	cleanup_recv_queue(&port_priv->qp_info[0]);
 error3:
+	kfree(port_attr);
+error2:
 	kfree(port_priv);
 
 	return ret;
Index: b/drivers/infiniband/core/mad_priv.h
===================================================================
--- a/drivers/infiniband/core/mad_priv.h	2007-05-07 14:32:34.000000000 +0300
+++ b/drivers/infiniband/core/mad_priv.h	2007-05-07 14:33:28.856102158 +0300
@@ -200,6 +200,7 @@ struct ib_mad_port_private {
 	struct list_head port_list;
 	struct ib_device *device;
 	int port_num;
+	atomic_t port_lmc;
 	struct ib_cq *cq;
 	struct ib_pd *pd;
 	struct ib_mr *mr;




More information about the general mailing list