Skip to content

Commit 290c4a9

Browse files
rpearsonhpe-designjgunthorpe
authored andcommitted
RDMA/rxe: Fix "Replace mr by rkey in responder resources"
The referenced commit generates a reference counting error if the rkey has the same index but the wrong key. In this case the reference taken by rxe_pool_get_index() is not dropped. Drop the reference if the keys don't match in rxe_recheck_mr(). Check that the mw and mr are still valid. Fixes: 8a1a0be ("RDMA/rxe: Replace mr by rkey in responder resources") Link: https://lore.kernel.org/r/20220411030647.20011-1-rpearsonhpe@gmail.com Signed-off-by: Bob Pearson <rpearsonhpe@gmail.com> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
1 parent ce522ba commit 290c4a9

1 file changed

Lines changed: 17 additions & 8 deletions

File tree

drivers/infiniband/sw/rxe/rxe_resp.c

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -680,6 +680,11 @@ static struct resp_res *rxe_prepare_read_res(struct rxe_qp *qp,
680680
* It is assumed that the access permissions if originally good
681681
* are OK and the mappings to be unchanged.
682682
*
683+
* TODO: If someone reregisters an MR to change its size or
684+
* access permissions during the processing of an RDMA read
685+
* we should kill the responder resource and complete the
686+
* operation with an error.
687+
*
683688
* Return: mr on success else NULL
684689
*/
685690
static struct rxe_mr *rxe_recheck_mr(struct rxe_qp *qp, u32 rkey)
@@ -690,23 +695,27 @@ static struct rxe_mr *rxe_recheck_mr(struct rxe_qp *qp, u32 rkey)
690695

691696
if (rkey_is_mw(rkey)) {
692697
mw = rxe_pool_get_index(&rxe->mw_pool, rkey >> 8);
693-
if (!mw || mw->rkey != rkey)
698+
if (!mw)
694699
return NULL;
695700

696-
if (mw->state != RXE_MW_STATE_VALID) {
701+
mr = mw->mr;
702+
if (mw->rkey != rkey || mw->state != RXE_MW_STATE_VALID ||
703+
!mr || mr->state != RXE_MR_STATE_VALID) {
697704
rxe_put(mw);
698705
return NULL;
699706
}
700707

701-
mr = mw->mr;
708+
rxe_get(mr);
702709
rxe_put(mw);
703-
} else {
704-
mr = rxe_pool_get_index(&rxe->mr_pool, rkey >> 8);
705-
if (!mr || mr->rkey != rkey)
706-
return NULL;
710+
711+
return mr;
707712
}
708713

709-
if (mr->state != RXE_MR_STATE_VALID) {
714+
mr = rxe_pool_get_index(&rxe->mr_pool, rkey >> 8);
715+
if (!mr)
716+
return NULL;
717+
718+
if (mr->rkey != rkey || mr->state != RXE_MR_STATE_VALID) {
710719
rxe_put(mr);
711720
return NULL;
712721
}

0 commit comments

Comments
 (0)