Commit f67ac006 authored by Honggang LI's avatar Honggang LI Committed by Leon Romanovsky

RDMA/rxe: Fix responder length checking for UD request packets

According to the IBA specification:
If a UD request packet is detected with an invalid length, the request
shall be an invalid request and it shall be silently dropped by
the responder. The responder then waits for a new request packet.

commit 689c5421 ("RDMA/rxe: Fix incorrect responder length checking")
defers responder length check for UD QPs in function `copy_data`.
But it introduces a regression issue for UD QPs.

When the packet size is too large to fit in the receive buffer.
`copy_data` will return error code -EINVAL. Then `send_data_in`
will return RESPST_ERR_MALFORMED_WQE. UD QP will transfer into
ERROR state.

Fixes: 689c5421 ("RDMA/rxe: Fix incorrect responder length checking")
Signed-off-by: default avatarHonggang LI <honggangli@163.com>
Link: https://lore.kernel.org/r/20240523094617.141148-1-honggangli@163.comReviewed-by: default avatarZhu Yanjun <yanjun.zhu@linux.dev>
Signed-off-by: default avatarLeon Romanovsky <leon@kernel.org>
parent 03fa18a9
...@@ -344,6 +344,19 @@ static enum resp_states rxe_resp_check_length(struct rxe_qp *qp, ...@@ -344,6 +344,19 @@ static enum resp_states rxe_resp_check_length(struct rxe_qp *qp,
* receive buffer later. For rmda operations additional * receive buffer later. For rmda operations additional
* length checks are performed in check_rkey. * length checks are performed in check_rkey.
*/ */
if ((qp_type(qp) == IB_QPT_GSI) || (qp_type(qp) == IB_QPT_UD)) {
unsigned int payload = payload_size(pkt);
unsigned int recv_buffer_len = 0;
int i;
for (i = 0; i < qp->resp.wqe->dma.num_sge; i++)
recv_buffer_len += qp->resp.wqe->dma.sge[i].length;
if (payload + 40 > recv_buffer_len) {
rxe_dbg_qp(qp, "The receive buffer is too small for this UD packet.\n");
return RESPST_ERR_LENGTH;
}
}
if (pkt->mask & RXE_PAYLOAD_MASK && ((qp_type(qp) == IB_QPT_RC) || if (pkt->mask & RXE_PAYLOAD_MASK && ((qp_type(qp) == IB_QPT_RC) ||
(qp_type(qp) == IB_QPT_UC))) { (qp_type(qp) == IB_QPT_UC))) {
unsigned int mtu = qp->mtu; unsigned int mtu = qp->mtu;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment