diff mbox series

[15/20] Fixed a dumb bug

Message ID 20200815045912.8626-16-rpearson@hpe.com (mailing list archive)
State Changes Requested
Delegated to: Jason Gunthorpe
Headers show
Series [01/20] Added ib_uverbs_wc_opcode to ib_user_verbs.h | expand

Commit Message

Bob Pearson Aug. 15, 2020, 4:58 a.m. UTC
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@hpe.com>
---
 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 mbox series

Patch

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;
 }