added code to prevent infinite loops in get l/rkey added a drop_key in mr dereg (fixing the root cause of loops) Signed-off-by: Bob Pearson <rpearson@xxxxxxx> --- drivers/infiniband/sw/rxe/rxe_mr.c | 22 +++++++++++----------- drivers/infiniband/sw/rxe/rxe_mw.c | 24 +++++++++++++----------- drivers/infiniband/sw/rxe/rxe_verbs.c | 1 + 3 files changed, 25 insertions(+), 22 deletions(-) diff --git a/drivers/infiniband/sw/rxe/rxe_mr.c b/drivers/infiniband/sw/rxe/rxe_mr.c index ba4e33227633..533b02fc2d0e 100644 --- a/drivers/infiniband/sw/rxe/rxe_mr.c +++ b/drivers/infiniband/sw/rxe/rxe_mr.c @@ -34,20 +34,20 @@ #include "rxe.h" #include "rxe_loc.h" -/* choose a unique non zero random number for lkey */ +/* choose a unique non zero random number for lkey + * use high order bit to indicate MR vs MW */ void rxe_set_mr_lkey(struct rxe_mr *mr) { - int ret; u32 lkey; - -next_lkey: - get_random_bytes(&lkey, sizeof(lkey)); - lkey &= 0x7fffffff; - if (unlikely(lkey == 0)) - goto next_lkey; - ret = rxe_add_key(mr, &lkey); - if (unlikely(ret == -EAGAIN)) - goto next_lkey; + int tries = 0; + + do { + get_random_bytes(&lkey, sizeof(lkey)); + lkey &= 0x7fffffff; + if (likely(lkey && (rxe_add_key(mr, &lkey) == 0))) + return; + } while (tries++ < 10); + pr_err("rxe_set_mr_lkey: unable to get random lkey\n"); } #if 0 diff --git a/drivers/infiniband/sw/rxe/rxe_mw.c b/drivers/infiniband/sw/rxe/rxe_mw.c index b45a04efa4a0..a0ff2543d0cd 100644 --- a/drivers/infiniband/sw/rxe/rxe_mw.c +++ b/drivers/infiniband/sw/rxe/rxe_mw.c @@ -35,22 +35,24 @@ #include "rxe.h" #include "rxe_loc.h" -/* choose a unique non zero random number for rkey */ +/* choose a unique non zero random number for rkey + * use high order bit to indicate MR vs MW */ void rxe_set_mw_rkey(struct rxe_mw *mw) { - int ret; u32 rkey; - -next_rkey: - get_random_bytes(&rkey, sizeof(rkey)); - if (unlikely(rkey == 0)) - goto next_rkey; - rkey |= 0x80000000; - ret = rxe_add_key(mw, &rkey); - if (unlikely(ret == -EAGAIN)) - goto next_rkey; + int tries = 0; + + do { + get_random_bytes(&rkey, sizeof(rkey)); + rkey |= 0x80000000; + if (likely((rkey & 0x7fffffff) && + (rxe_add_key(mw, &rkey) == 0))) + return; + } while (tries++ < 10); + pr_err("rxe_set_mw_rkey: unable to get random rkey\n"); } + /* place holder alloc and dealloc routines * TODO add cross references between qp and mr with mw * and cleanup when one side is deleted. Enough to make diff --git a/drivers/infiniband/sw/rxe/rxe_verbs.c b/drivers/infiniband/sw/rxe/rxe_verbs.c index b91364ba2c68..476d90e3f91f 100644 --- a/drivers/infiniband/sw/rxe/rxe_verbs.c +++ b/drivers/infiniband/sw/rxe/rxe_verbs.c @@ -986,6 +986,7 @@ static int rxe_dereg_mr(struct ib_mr *ibmr, struct ib_udata *udata) mr->state = RXE_MEM_STATE_ZOMBIE; rxe_drop_ref(mr->pd); rxe_drop_index(mr); + rxe_drop_key(mr); rxe_drop_ref(mr); return 0; } -- 2.25.1