[ofa-general] [PATCH] mlx4_ib: Fix dispatch of IB_EVENT_LID_CHANGE
Moni Shoua
monis at Voltaire.COM
Mon Dec 15 01:43:57 PST 2008
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 dispatches an event if the client_reregister bit is set.
In addition, the patch compares the LID in the MAD to the current LID.
If and only if they are not identical then a LID_CHANGE event is dispatched.
From: Moni Shoua <monis at voltaire.com>
Signed-off-by: Moni Shoua <monis at voltaire.com>
Signed-off-by: Jack Morgenstein <jackm at dev.mellanox.co.il>
Signed-off-by: Yossi Etigin <yosefe at voltaire.com>
--
Index: ofed_kernel/drivers/infiniband/hw/mlx4/mad.c
===================================================================
--- ofed_kernel.orig/drivers/infiniband/hw/mlx4/mad.c 2008-11-30 08:34:47.470355000 +0200
+++ ofed_kernel/drivers/infiniband/hw/mlx4/mad.c 2008-11-30 08:55:50.691654000 +0200
@@ -147,7 +147,8 @@ static void update_sm_ah(struct mlx4_ib_
* 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 *
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 *
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 != 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
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,13 @@ int mlx4_ib_process_mad(struct ib_device
} else
return IB_MAD_RESULT_SUCCESS;
+ if ((in_mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_SUBN_LID_ROUTED ||
+ in_mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE) &&
+ in_mad->mad_hdr.method == IB_MGMT_METHOD_SET &&
+ in_mad->mad_hdr.attr_id == IB_SMP_ATTR_PORT_INFO &&
+ !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 +284,7 @@ int mlx4_ib_process_mad(struct ib_device
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);
}
More information about the general
mailing list