[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