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