Skip to content

Commit f4d4611

Browse files
kwan-intcjgunthorpe
authored andcommitted
IB/hfi1: Drop all TID RDMA READ RESP packets after r_next_psn
When a TID sequence error occurs while receiving TID RDMA READ RESP packets, all packets after flow->flow_state.r_next_psn should be dropped, including those response packets for subsequent segments. The current implementation will drop the subsequent response packets for the segment to complete next, but may accept packets for subsequent segments and therefore mistakenly advance the r_next_psn fields for the corresponding software flows. This may result in failures to complete subsequent segments after the current segment is completed. The fix is to only use the flow pointed by req->clear_tail for checking KDETH PSN instead of finding a flow from the request's flow array. Fixes: b885d5b ("IB/hfi1: Unify the software PSN check for TID RDMA READ/WRITE") Cc: <[email protected]> Link: https://lore.kernel.org/r/[email protected] Reviewed-by: Mike Marciniszyn <[email protected]> Signed-off-by: Kaike Wan <[email protected]> Signed-off-by: Mike Marciniszyn <[email protected]> Signed-off-by: Jason Gunthorpe <[email protected]>
1 parent dc25b23 commit f4d4611

File tree

1 file changed

+1
-41
lines changed

1 file changed

+1
-41
lines changed

drivers/infiniband/hw/hfi1/tid_rdma.c

Lines changed: 1 addition & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1674,34 +1674,6 @@ static struct tid_rdma_flow *find_flow_ib(struct tid_rdma_request *req,
16741674
return NULL;
16751675
}
16761676

1677-
static struct tid_rdma_flow *
1678-
__find_flow_ranged(struct tid_rdma_request *req, u16 head, u16 tail,
1679-
u32 psn, u16 *fidx)
1680-
{
1681-
for ( ; CIRC_CNT(head, tail, MAX_FLOWS);
1682-
tail = CIRC_NEXT(tail, MAX_FLOWS)) {
1683-
struct tid_rdma_flow *flow = &req->flows[tail];
1684-
u32 spsn, lpsn;
1685-
1686-
spsn = full_flow_psn(flow, flow->flow_state.spsn);
1687-
lpsn = full_flow_psn(flow, flow->flow_state.lpsn);
1688-
1689-
if (cmp_psn(psn, spsn) >= 0 && cmp_psn(psn, lpsn) <= 0) {
1690-
if (fidx)
1691-
*fidx = tail;
1692-
return flow;
1693-
}
1694-
}
1695-
return NULL;
1696-
}
1697-
1698-
static struct tid_rdma_flow *find_flow(struct tid_rdma_request *req,
1699-
u32 psn, u16 *fidx)
1700-
{
1701-
return __find_flow_ranged(req, req->setup_head, req->clear_tail, psn,
1702-
fidx);
1703-
}
1704-
17051677
/* TID RDMA READ functions */
17061678
u32 hfi1_build_tid_rdma_read_packet(struct rvt_swqe *wqe,
17071679
struct ib_other_headers *ohdr, u32 *bth1,
@@ -2789,19 +2761,7 @@ static bool handle_read_kdeth_eflags(struct hfi1_ctxtdata *rcd,
27892761
* to prevent continuous Flow Sequence errors for any
27902762
* packets that could be still in the fabric.
27912763
*/
2792-
flow = find_flow(req, psn, NULL);
2793-
if (!flow) {
2794-
/*
2795-
* We can't find the IB PSN matching the
2796-
* received KDETH PSN. The only thing we can
2797-
* do at this point is report the error to
2798-
* the QP.
2799-
*/
2800-
hfi1_kern_read_tid_flow_free(qp);
2801-
spin_unlock(&qp->s_lock);
2802-
rvt_rc_error(qp, IB_WC_LOC_QP_OP_ERR);
2803-
return ret;
2804-
}
2764+
flow = &req->flows[req->clear_tail];
28052765
if (priv->s_flags & HFI1_R_TID_SW_PSN) {
28062766
diff = cmp_psn(psn,
28072767
flow->flow_state.r_next_psn);

0 commit comments

Comments
 (0)