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 <[EMAIL PROTECTED]>
---
 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;

_______________________________________________
general mailing list
general@lists.openfabrics.org
http://lists.openfabrics.org/cgi-bin/mailman/listinfo/general

To unsubscribe, please visit http://openib.org/mailman/listinfo/openib-general

Reply via email to