diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2022-05-06 09:50:25 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2022-05-06 09:50:25 -0700 |
commit | 4df22ca85d3d73f9822b1a354bb56dd1872180cd (patch) | |
tree | 502da0ee4adb63c56928c76c7833fc05ba053587 /drivers/infiniband/sw/rxe/rxe_resp.c | |
parent | 64267926e01b06f43e26232722fb3dc3f4819823 (diff) | |
parent | bfdc0edd11f9501b891a069b5bbd3b16731941e1 (diff) |
Merge tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma
Pull rdma fixes from Jason Gunthorpe:
"A few recent regressions in rxe's multicast code, and some old driver
bugs:
- Error case unwind bug in rxe for rkeys
- Dot not call netdev functions under a spinlock in rxe multicast
code
- Use the proper BH lock type in rxe multicast code
- Fix idrma deadlock and crash
- Add a missing flush to drain irdma QPs when in error
- Fix high userspace latency in irdma during destroy due to
synchronize_rcu()
- Rare race in siw MPA processing"
* tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma:
RDMA/rxe: Change mcg_lock to a _bh lock
RDMA/rxe: Do not call dev_mc_add/del() under a spinlock
RDMA/siw: Fix a condition race issue in MPA request processing
RDMA/irdma: Fix possible crash due to NULL netdev in notifier
RDMA/irdma: Reduce iWARP QP destroy time
RDMA/irdma: Flush iWARP QP if modified to ERR from RTR state
RDMA/rxe: Recheck the MR in when generating a READ reply
RDMA/irdma: Fix deadlock in irdma_cleanup_cm_core()
RDMA/rxe: Fix "Replace mr by rkey in responder resources"
Diffstat (limited to 'drivers/infiniband/sw/rxe/rxe_resp.c')
-rw-r--r-- | drivers/infiniband/sw/rxe/rxe_resp.c | 35 |
1 files changed, 25 insertions, 10 deletions
diff --git a/drivers/infiniband/sw/rxe/rxe_resp.c b/drivers/infiniband/sw/rxe/rxe_resp.c index 16fc7ea1298d..9cd0eaff98de 100644 --- a/drivers/infiniband/sw/rxe/rxe_resp.c +++ b/drivers/infiniband/sw/rxe/rxe_resp.c @@ -680,6 +680,11 @@ static struct resp_res *rxe_prepare_read_res(struct rxe_qp *qp, * It is assumed that the access permissions if originally good * are OK and the mappings to be unchanged. * + * TODO: If someone reregisters an MR to change its size or + * access permissions during the processing of an RDMA read + * we should kill the responder resource and complete the + * operation with an error. + * * Return: mr on success else NULL */ 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) if (rkey_is_mw(rkey)) { mw = rxe_pool_get_index(&rxe->mw_pool, rkey >> 8); - if (!mw || mw->rkey != rkey) + if (!mw) return NULL; - if (mw->state != RXE_MW_STATE_VALID) { + mr = mw->mr; + if (mw->rkey != rkey || mw->state != RXE_MW_STATE_VALID || + !mr || mr->state != RXE_MR_STATE_VALID) { rxe_put(mw); return NULL; } - mr = mw->mr; + rxe_get(mr); rxe_put(mw); - } else { - mr = rxe_pool_get_index(&rxe->mr_pool, rkey >> 8); - if (!mr || mr->rkey != rkey) - return NULL; + + return mr; } - if (mr->state != RXE_MR_STATE_VALID) { + mr = rxe_pool_get_index(&rxe->mr_pool, rkey >> 8); + if (!mr) + return NULL; + + if (mr->rkey != rkey || mr->state != RXE_MR_STATE_VALID) { rxe_put(mr); return NULL; } @@ -736,8 +745,14 @@ static enum resp_states read_reply(struct rxe_qp *qp, } if (res->state == rdatm_res_state_new) { - mr = qp->resp.mr; - qp->resp.mr = NULL; + if (!res->replay) { + mr = qp->resp.mr; + qp->resp.mr = NULL; + } else { + mr = rxe_recheck_mr(qp, res->read.rkey); + if (!mr) + return RESPST_ERR_RKEY_VIOLATION; + } if (res->read.resid <= mtu) opcode = IB_OPCODE_RC_RDMA_READ_RESPONSE_ONLY; |