When snooping a portinfo MAD, it's client_reregister bit is checked. 
If the bit is ON then a CLIENT_REREGISTER event is dispatched, otherwise
a LID_CHANGE event is dispatched. This way of decision ignores the cases
where the MAD changes the LID along with an instruction to reregister (so a
necessary LID_CHANGE event won't be dispatched) or the MAD is neither of
these (and an unnecessary LID_CHANGE event will be dispatched). 
This patch compares the LID in the MAD to the current LID. If and only if
they are not identical then a LID_CHANGE event will be dispatched.

Signed-off-by: Moni Shoua <[EMAIL PROTECTED]>
---
 drivers/infiniband/hw/mlx4/mad.c        |   21 +++++++++++++++------
 drivers/infiniband/hw/mthca/mthca_mad.c |   20 +++++++++++++++-----
 2 files changed, 30 insertions(+), 11 deletions(-)

diff --git a/drivers/infiniband/hw/mlx4/mad.c b/drivers/infiniband/hw/mlx4/mad.c
index 606f1e2..ca5fa9e 100644
--- a/drivers/infiniband/hw/mlx4/mad.c
+++ b/drivers/infiniband/hw/mlx4/mad.c
@@ -147,7 +147,8 @@ static void update_sm_ah(struct mlx4_ib_dev *dev, u8 
port_num, u16 lid, u8 sl)
  * Snoop SM MADs for port info and P_Key table sets, so we can
  * synthesize LID change and P_Key change events.
  */
-static void smp_snoop(struct ib_device *ibdev, u8 port_num, struct ib_mad *mad)
+static void smp_snoop(struct ib_device *ibdev, u8 port_num, struct ib_mad *mad,
+                               u16 prev_lid)
 {
        struct ib_event event;
 
@@ -157,6 +158,7 @@ static void smp_snoop(struct ib_device *ibdev, u8 port_num, 
struct ib_mad *mad)
                if (mad->mad_hdr.attr_id == IB_SMP_ATTR_PORT_INFO) {
                        struct ib_port_info *pinfo =
                                (struct ib_port_info *) ((struct ib_smp *) 
mad)->data;
+                       u16 lid = be16_to_cpu(pinfo->lid);
 
                        update_sm_ah(to_mdev(ibdev), port_num,
                                     be16_to_cpu(pinfo->sm_lid),
@@ -165,12 +167,15 @@ static void smp_snoop(struct ib_device *ibdev, u8 
port_num, struct ib_mad *mad)
                        event.device           = ibdev;
                        event.element.port_num = port_num;
 
-                       if (pinfo->clientrereg_resv_subnetto & 0x80)
+                       if (pinfo->clientrereg_resv_subnetto & 0x80) {
                                event.event    = IB_EVENT_CLIENT_REREGISTER;
-                       else
+                               ib_dispatch_event(&event);
+                       }
+                       if ((prev_lid != 0) && (prev_lid != lid)) {
                                event.event    = IB_EVENT_LID_CHANGE;
+                               ib_dispatch_event(&event);
+                       }
 
-                       ib_dispatch_event(&event);
                }
 
                if (mad->mad_hdr.attr_id == IB_SMP_ATTR_PKEY_TABLE) {
@@ -228,8 +233,9 @@ int mlx4_ib_process_mad(struct ib_device *ibdev, int 
mad_flags,     u8 port_num,
                        struct ib_wc *in_wc, struct ib_grh *in_grh,
                        struct ib_mad *in_mad, struct ib_mad *out_mad)
 {
-       u16 slid;
+       u16 slid, prev_lid = 0;
        int err;
+       struct ib_port_attr pattr;
 
        slid = in_wc ? in_wc->slid : be16_to_cpu(IB_LID_PERMISSIVE);
 
@@ -263,6 +269,9 @@ int mlx4_ib_process_mad(struct ib_device *ibdev, int 
mad_flags,     u8 port_num,
        } else
                return IB_MAD_RESULT_SUCCESS;
 
+       if (!ib_query_port(ibdev, port_num, &pattr))
+               prev_lid = pattr.lid;
+
        err = mlx4_MAD_IFC(to_mdev(ibdev),
                           mad_flags & IB_MAD_IGNORE_MKEY,
                           mad_flags & IB_MAD_IGNORE_BKEY,
@@ -271,7 +280,7 @@ int mlx4_ib_process_mad(struct ib_device *ibdev, int 
mad_flags,     u8 port_num,
                return IB_MAD_RESULT_FAILURE;
 
        if (!out_mad->mad_hdr.status) {
-               smp_snoop(ibdev, port_num, in_mad);
+               smp_snoop(ibdev, port_num, in_mad, prev_lid);
                node_desc_override(ibdev, out_mad);
        }
 
diff --git a/drivers/infiniband/hw/mthca/mthca_mad.c 
b/drivers/infiniband/hw/mthca/mthca_mad.c
index 6404495..6ac114a 100644
--- a/drivers/infiniband/hw/mthca/mthca_mad.c
+++ b/drivers/infiniband/hw/mthca/mthca_mad.c
@@ -104,7 +104,8 @@ static void update_sm_ah(struct mthca_dev *dev,
  */
 static void smp_snoop(struct ib_device *ibdev,
                      u8 port_num,
-                     struct ib_mad *mad)
+                     struct ib_mad *mad,
+                     u16 prev_lid)
 {
        struct ib_event event;
 
@@ -114,6 +115,7 @@ static void smp_snoop(struct ib_device *ibdev,
                if (mad->mad_hdr.attr_id == IB_SMP_ATTR_PORT_INFO) {
                        struct ib_port_info *pinfo =
                                (struct ib_port_info *) ((struct ib_smp *) 
mad)->data;
+                       u16 lid = be16_to_cpu(pinfo->lid);
 
                        mthca_update_rate(to_mdev(ibdev), port_num);
                        update_sm_ah(to_mdev(ibdev), port_num,
@@ -123,12 +125,15 @@ static void smp_snoop(struct ib_device *ibdev,
                        event.device           = ibdev;
                        event.element.port_num = port_num;
 
-                       if (pinfo->clientrereg_resv_subnetto & 0x80)
+                       if (pinfo->clientrereg_resv_subnetto & 0x80) {
                                event.event    = IB_EVENT_CLIENT_REREGISTER;
-                       else
+                               ib_dispatch_event(&event);
+                       }
+                       if ((prev_lid != 0) && (prev_lid != lid)) {
                                event.event    = IB_EVENT_LID_CHANGE;
+                               ib_dispatch_event(&event);
+                       }
 
-                       ib_dispatch_event(&event);
                }
 
                if (mad->mad_hdr.attr_id == IB_SMP_ATTR_PKEY_TABLE) {
@@ -196,6 +201,8 @@ int mthca_process_mad(struct ib_device *ibdev,
        int err;
        u8 status;
        u16 slid = in_wc ? in_wc->slid : be16_to_cpu(IB_LID_PERMISSIVE);
+       u16 prev_lid = 0;
+       struct ib_port_attr pattr;
 
        /* Forward locally generated traps to the SM */
        if (in_mad->mad_hdr.method == IB_MGMT_METHOD_TRAP &&
@@ -234,6 +241,9 @@ int mthca_process_mad(struct ib_device *ibdev,
        } else
                return IB_MAD_RESULT_SUCCESS;
 
+       if (!ib_query_port(ibdev, port_num, &pattr))
+               prev_lid = pattr.lid;
+
        err = mthca_MAD_IFC(to_mdev(ibdev),
                            mad_flags & IB_MAD_IGNORE_MKEY,
                            mad_flags & IB_MAD_IGNORE_BKEY,
@@ -252,7 +262,7 @@ int mthca_process_mad(struct ib_device *ibdev,
        }
 
        if (!out_mad->mad_hdr.status) {
-               smp_snoop(ibdev, port_num, in_mad);
+               smp_snoop(ibdev, port_num, in_mad, prev_lid);
                node_desc_override(ibdev, out_mad);
        }
 
_______________________________________________
general mailing list
[email protected]
http://lists.openfabrics.org/cgi-bin/mailman/listinfo/general

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

Reply via email to