aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Boyer <andrew.boyer@dell.com>2016-11-23 12:39:21 -0500
committerDoug Ledford <dledford@redhat.com>2016-12-12 16:31:45 -0500
commitd4fb59256ac03d84f68e36c430b58d6fc76dd651 (patch)
tree439d45878decc2d4ea3eed161be54dffb034d87f
parentd38eb801aa145aedf4b97e8e0bb2e65763aa6149 (diff)
IB/rxe: Add support for zero-byte operations
The last_psn algorithm fails in the zero-byte case: it calculates first_psn = N, last_psn = N-1. This makes the operation unretryable since the res structure will fail the (first_psn <= psn <= last_psn) test in find_resource(). While here, use BTH_PSN_MASK to mask the calculated last_psn. Signed-off-by: Andrew Boyer <andrew.boyer@dell.com> Reviewed-by: Moni Shoua <monis@mellanox.com> Signed-off-by: Doug Ledford <dledford@redhat.com>
-rw-r--r--drivers/infiniband/sw/rxe/rxe_mr.c3
-rw-r--r--drivers/infiniband/sw/rxe/rxe_resp.c18
2 files changed, 18 insertions, 3 deletions
diff --git a/drivers/infiniband/sw/rxe/rxe_mr.c b/drivers/infiniband/sw/rxe/rxe_mr.c
index 1869152f1d23..d0faca294006 100644
--- a/drivers/infiniband/sw/rxe/rxe_mr.c
+++ b/drivers/infiniband/sw/rxe/rxe_mr.c
@@ -355,6 +355,9 @@ int rxe_mem_copy(struct rxe_mem *mem, u64 iova, void *addr, int length,
355 size_t offset; 355 size_t offset;
356 u32 crc = crcp ? (*crcp) : 0; 356 u32 crc = crcp ? (*crcp) : 0;
357 357
358 if (length == 0)
359 return 0;
360
358 if (mem->type == RXE_MEM_TYPE_DMA) { 361 if (mem->type == RXE_MEM_TYPE_DMA) {
359 u8 *src, *dest; 362 u8 *src, *dest;
360 363
diff --git a/drivers/infiniband/sw/rxe/rxe_resp.c b/drivers/infiniband/sw/rxe/rxe_resp.c
index cb3fd4cb0daa..a5e9ce34171b 100644
--- a/drivers/infiniband/sw/rxe/rxe_resp.c
+++ b/drivers/infiniband/sw/rxe/rxe_resp.c
@@ -444,6 +444,13 @@ static enum resp_states check_rkey(struct rxe_qp *qp,
444 return RESPST_EXECUTE; 444 return RESPST_EXECUTE;
445 } 445 }
446 446
447 /* A zero-byte op is not required to set an addr or rkey. */
448 if ((pkt->mask & (RXE_READ_MASK | RXE_WRITE_OR_SEND)) &&
449 (pkt->mask & RXE_RETH_MASK) &&
450 reth_len(pkt) == 0) {
451 return RESPST_EXECUTE;
452 }
453
447 va = qp->resp.va; 454 va = qp->resp.va;
448 rkey = qp->resp.rkey; 455 rkey = qp->resp.rkey;
449 resid = qp->resp.resid; 456 resid = qp->resp.resid;
@@ -680,9 +687,14 @@ static enum resp_states read_reply(struct rxe_qp *qp,
680 res->read.va_org = qp->resp.va; 687 res->read.va_org = qp->resp.va;
681 688
682 res->first_psn = req_pkt->psn; 689 res->first_psn = req_pkt->psn;
683 res->last_psn = req_pkt->psn + 690
684 (reth_len(req_pkt) + mtu - 1) / 691 if (reth_len(req_pkt)) {
685 mtu - 1; 692 res->last_psn = (req_pkt->psn +
693 (reth_len(req_pkt) + mtu - 1) /
694 mtu - 1) & BTH_PSN_MASK;
695 } else {
696 res->last_psn = res->first_psn;
697 }
686 res->cur_psn = req_pkt->psn; 698 res->cur_psn = req_pkt->psn;
687 699
688 res->read.resid = qp->resp.resid; 700 res->read.resid = qp->resp.resid;