Skip to content

Commit f0f6f34

Browse files
Moni ShouaRoland Dreier
authored andcommitted
IB/mlx4: Fix dispatch of IB_EVENT_LID_CHANGE event
When snooping a PortInfo MAD, its 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 causes problems at least with IPoIB, which will do a "light" flush on reregister, rather than the "heavy" flush required due to a LID change. Fix this by dispatching a CLIENT_REREGISTER event if the client_reregister bit is set, but also compare the LID in the MAD to the current LID. If and only if they are not identical then a LID_CHANGE event is dispatched. Signed-off-by: Moni Shoua <[email protected]> Signed-off-by: Jack Morgenstein <[email protected]> Signed-off-by: Yossi Etigin <[email protected]> Signed-off-by: Roland Dreier <[email protected]>
1 parent f3b8436 commit f0f6f34

File tree

1 file changed

+20
-7
lines changed
  • drivers/infiniband/hw/mlx4

1 file changed

+20
-7
lines changed

drivers/infiniband/hw/mlx4/mad.c

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,8 @@ static void update_sm_ah(struct mlx4_ib_dev *dev, u8 port_num, u16 lid, u8 sl)
147147
* Snoop SM MADs for port info and P_Key table sets, so we can
148148
* synthesize LID change and P_Key change events.
149149
*/
150-
static void smp_snoop(struct ib_device *ibdev, u8 port_num, struct ib_mad *mad)
150+
static void smp_snoop(struct ib_device *ibdev, u8 port_num, struct ib_mad *mad,
151+
u16 prev_lid)
151152
{
152153
struct ib_event event;
153154

@@ -157,6 +158,7 @@ static void smp_snoop(struct ib_device *ibdev, u8 port_num, struct ib_mad *mad)
157158
if (mad->mad_hdr.attr_id == IB_SMP_ATTR_PORT_INFO) {
158159
struct ib_port_info *pinfo =
159160
(struct ib_port_info *) ((struct ib_smp *) mad)->data;
161+
u16 lid = be16_to_cpu(pinfo->lid);
160162

161163
update_sm_ah(to_mdev(ibdev), port_num,
162164
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)
165167
event.device = ibdev;
166168
event.element.port_num = port_num;
167169

168-
if (pinfo->clientrereg_resv_subnetto & 0x80)
170+
if (pinfo->clientrereg_resv_subnetto & 0x80) {
169171
event.event = IB_EVENT_CLIENT_REREGISTER;
170-
else
171-
event.event = IB_EVENT_LID_CHANGE;
172+
ib_dispatch_event(&event);
173+
}
172174

173-
ib_dispatch_event(&event);
175+
if (prev_lid != lid) {
176+
event.event = IB_EVENT_LID_CHANGE;
177+
ib_dispatch_event(&event);
178+
}
174179
}
175180

176181
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,
228233
struct ib_wc *in_wc, struct ib_grh *in_grh,
229234
struct ib_mad *in_mad, struct ib_mad *out_mad)
230235
{
231-
u16 slid;
236+
u16 slid, prev_lid = 0;
232237
int err;
238+
struct ib_port_attr pattr;
233239

234240
slid = in_wc ? in_wc->slid : be16_to_cpu(IB_LID_PERMISSIVE);
235241

@@ -263,6 +269,13 @@ int mlx4_ib_process_mad(struct ib_device *ibdev, int mad_flags, u8 port_num,
263269
} else
264270
return IB_MAD_RESULT_SUCCESS;
265271

272+
if ((in_mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_SUBN_LID_ROUTED ||
273+
in_mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE) &&
274+
in_mad->mad_hdr.method == IB_MGMT_METHOD_SET &&
275+
in_mad->mad_hdr.attr_id == IB_SMP_ATTR_PORT_INFO &&
276+
!ib_query_port(ibdev, port_num, &pattr))
277+
prev_lid = pattr.lid;
278+
266279
err = mlx4_MAD_IFC(to_mdev(ibdev),
267280
mad_flags & IB_MAD_IGNORE_MKEY,
268281
mad_flags & IB_MAD_IGNORE_BKEY,
@@ -271,7 +284,7 @@ int mlx4_ib_process_mad(struct ib_device *ibdev, int mad_flags, u8 port_num,
271284
return IB_MAD_RESULT_FAILURE;
272285

273286
if (!out_mad->mad_hdr.status) {
274-
smp_snoop(ibdev, port_num, in_mad);
287+
smp_snoop(ibdev, port_num, in_mad, prev_lid);
275288
node_desc_override(ibdev, out_mad);
276289
}
277290

0 commit comments

Comments
 (0)