diff options
author | Andrew Boyer <andrew.boyer@dell.com> | 2016-11-23 12:39:21 -0500 |
---|---|---|
committer | Doug Ledford <dledford@redhat.com> | 2016-12-12 16:31:45 -0500 |
commit | d4fb59256ac03d84f68e36c430b58d6fc76dd651 (patch) | |
tree | 439d45878decc2d4ea3eed161be54dffb034d87f | |
parent | d38eb801aa145aedf4b97e8e0bb2e65763aa6149 (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.c | 3 | ||||
-rw-r--r-- | drivers/infiniband/sw/rxe/rxe_resp.c | 18 |
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; |