Skip to content

Commit f59fb9e

Browse files
mmarcinidledford
authored andcommitted
IB/hfi1: Fix handling of FECN marked multicast packet
The code for handling a marked UD packet unconditionally returns the dlid in the header of the FECN marked packet. This is not correct for multicast packets where the DLID is in the multicast range. The subsequent attempt to send the CNP with the multicast lid will cause the chip to halt the ack send context because the source lid doesn't match the chip programming. The send context will be halted and flush any other pending packets in the pio ring causing the CNP to not be sent. A part of investigating the fix, it was determined that the 16B work broke the FECN routine badly with inconsistent use of 16 bit and 32 bits types for lids and pkeys. Since the port's source lid was correctly 32 bits the type mixmatches need to be dealt with at the same time as fixing the CNP header issue. Fix these issues by: - Using the ports lid for as the SLID for responding to FECN marked UD packets - Insure pkey is always 16 bit in this and subordinate routines - Insure lids are 32 bits in this and subordinate routines Cc: <[email protected]> # 4.14.x Fixes: 88733e3 ("IB/hfi1: Add 16B UD support") Reviewed-by: Don Hiatt <[email protected]> Reviewed-by: Michael J. Ruhl <[email protected]> Signed-off-by: Mike Marciniszyn <[email protected]> Signed-off-by: Dennis Dalessandro <[email protected]> Signed-off-by: Doug Ledford <[email protected]>
1 parent db82476 commit f59fb9e

File tree

3 files changed

+21
-10
lines changed

3 files changed

+21
-10
lines changed

drivers/infiniband/hw/hfi1/driver.c

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -433,31 +433,43 @@ void hfi1_process_ecn_slowpath(struct rvt_qp *qp, struct hfi1_packet *pkt,
433433
bool do_cnp)
434434
{
435435
struct hfi1_ibport *ibp = to_iport(qp->ibqp.device, qp->port_num);
436+
struct hfi1_pportdata *ppd = ppd_from_ibp(ibp);
436437
struct ib_other_headers *ohdr = pkt->ohdr;
437438
struct ib_grh *grh = pkt->grh;
438439
u32 rqpn = 0, bth1;
439-
u16 pkey, rlid, dlid = ib_get_dlid(pkt->hdr);
440+
u16 pkey;
441+
u32 rlid, slid, dlid = 0;
440442
u8 hdr_type, sc, svc_type;
441443
bool is_mcast = false;
442444

445+
/* can be called from prescan */
443446
if (pkt->etype == RHF_RCV_TYPE_BYPASS) {
444447
is_mcast = hfi1_is_16B_mcast(dlid);
445448
pkey = hfi1_16B_get_pkey(pkt->hdr);
446449
sc = hfi1_16B_get_sc(pkt->hdr);
450+
dlid = hfi1_16B_get_dlid(pkt->hdr);
451+
slid = hfi1_16B_get_slid(pkt->hdr);
447452
hdr_type = HFI1_PKT_TYPE_16B;
448453
} else {
449454
is_mcast = (dlid > be16_to_cpu(IB_MULTICAST_LID_BASE)) &&
450455
(dlid != be16_to_cpu(IB_LID_PERMISSIVE));
451456
pkey = ib_bth_get_pkey(ohdr);
452457
sc = hfi1_9B_get_sc5(pkt->hdr, pkt->rhf);
458+
dlid = ib_get_dlid(pkt->hdr);
459+
slid = ib_get_slid(pkt->hdr);
453460
hdr_type = HFI1_PKT_TYPE_9B;
454461
}
455462

456463
switch (qp->ibqp.qp_type) {
464+
case IB_QPT_UD:
465+
dlid = ppd->lid;
466+
rlid = slid;
467+
rqpn = ib_get_sqpn(pkt->ohdr);
468+
svc_type = IB_CC_SVCTYPE_UD;
469+
break;
457470
case IB_QPT_SMI:
458471
case IB_QPT_GSI:
459-
case IB_QPT_UD:
460-
rlid = ib_get_slid(pkt->hdr);
472+
rlid = slid;
461473
rqpn = ib_get_sqpn(pkt->ohdr);
462474
svc_type = IB_CC_SVCTYPE_UD;
463475
break;
@@ -482,7 +494,6 @@ void hfi1_process_ecn_slowpath(struct rvt_qp *qp, struct hfi1_packet *pkt,
482494
dlid, rlid, sc, grh);
483495

484496
if (!is_mcast && (bth1 & IB_BECN_SMASK)) {
485-
struct hfi1_pportdata *ppd = ppd_from_ibp(ibp);
486497
u32 lqpn = bth1 & RVT_QPN_MASK;
487498
u8 sl = ibp->sc_to_sl[sc];
488499

drivers/infiniband/hw/hfi1/hfi.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1537,13 +1537,13 @@ void set_link_ipg(struct hfi1_pportdata *ppd);
15371537
void process_becn(struct hfi1_pportdata *ppd, u8 sl, u32 rlid, u32 lqpn,
15381538
u32 rqpn, u8 svc_type);
15391539
void return_cnp(struct hfi1_ibport *ibp, struct rvt_qp *qp, u32 remote_qpn,
1540-
u32 pkey, u32 slid, u32 dlid, u8 sc5,
1540+
u16 pkey, u32 slid, u32 dlid, u8 sc5,
15411541
const struct ib_grh *old_grh);
15421542
void return_cnp_16B(struct hfi1_ibport *ibp, struct rvt_qp *qp,
1543-
u32 remote_qpn, u32 pkey, u32 slid, u32 dlid,
1543+
u32 remote_qpn, u16 pkey, u32 slid, u32 dlid,
15441544
u8 sc5, const struct ib_grh *old_grh);
15451545
typedef void (*hfi1_handle_cnp)(struct hfi1_ibport *ibp, struct rvt_qp *qp,
1546-
u32 remote_qpn, u32 pkey, u32 slid, u32 dlid,
1546+
u32 remote_qpn, u16 pkey, u32 slid, u32 dlid,
15471547
u8 sc5, const struct ib_grh *old_grh);
15481548

15491549
#define PKEY_CHECK_INVALID -1
@@ -2437,7 +2437,7 @@ static inline void hfi1_make_16b_hdr(struct hfi1_16b_header *hdr,
24372437
((slid >> OPA_16B_SLID_SHIFT) << OPA_16B_SLID_HIGH_SHIFT);
24382438
lrh2 = (lrh2 & ~OPA_16B_DLID_MASK) |
24392439
((dlid >> OPA_16B_DLID_SHIFT) << OPA_16B_DLID_HIGH_SHIFT);
2440-
lrh2 = (lrh2 & ~OPA_16B_PKEY_MASK) | (pkey << OPA_16B_PKEY_SHIFT);
2440+
lrh2 = (lrh2 & ~OPA_16B_PKEY_MASK) | ((u32)pkey << OPA_16B_PKEY_SHIFT);
24412441
lrh2 = (lrh2 & ~OPA_16B_L4_MASK) | l4;
24422442

24432443
hdr->lrh[0] = lrh0;

drivers/infiniband/hw/hfi1/ud.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -628,7 +628,7 @@ int hfi1_lookup_pkey_idx(struct hfi1_ibport *ibp, u16 pkey)
628628
}
629629

630630
void return_cnp_16B(struct hfi1_ibport *ibp, struct rvt_qp *qp,
631-
u32 remote_qpn, u32 pkey, u32 slid, u32 dlid,
631+
u32 remote_qpn, u16 pkey, u32 slid, u32 dlid,
632632
u8 sc5, const struct ib_grh *old_grh)
633633
{
634634
u64 pbc, pbc_flags = 0;
@@ -687,7 +687,7 @@ void return_cnp_16B(struct hfi1_ibport *ibp, struct rvt_qp *qp,
687687
}
688688

689689
void return_cnp(struct hfi1_ibport *ibp, struct rvt_qp *qp, u32 remote_qpn,
690-
u32 pkey, u32 slid, u32 dlid, u8 sc5,
690+
u16 pkey, u32 slid, u32 dlid, u8 sc5,
691691
const struct ib_grh *old_grh)
692692
{
693693
u64 pbc, pbc_flags = 0;

0 commit comments

Comments
 (0)