RDMA/rxe: Add ib_alloc_mw and ib_dealloc_mw verbs
authorBob Pearson <rpearsonhpe@gmail.com>
Tue, 8 Jun 2021 04:25:47 +0000 (23:25 -0500)
committerJason Gunthorpe <jgg@nvidia.com>
Wed, 16 Jun 2021 23:51:17 +0000 (20:51 -0300)
Add ib_alloc_mw and ib_dealloc_mw verbs APIs.

Added new file rxe_mw.c focused on MWs. Changed the 8 bit random key
generator. Added a cleanup routine for MWs. Added verbs routines to
ib_device_ops.

Link: https://lore.kernel.org/r/20210608042552.33275-5-rpearsonhpe@gmail.com
Signed-off-by: Bob Pearson <rpearsonhpe@gmail.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
drivers/infiniband/sw/rxe/Makefile
drivers/infiniband/sw/rxe/rxe_loc.h
drivers/infiniband/sw/rxe/rxe_mr.c
drivers/infiniband/sw/rxe/rxe_mw.c [new file with mode: 0644]
drivers/infiniband/sw/rxe/rxe_pool.c
drivers/infiniband/sw/rxe/rxe_verbs.c
drivers/infiniband/sw/rxe/rxe_verbs.h

index 66af72dca759c795ca4ccee25b159443af46f95d..1e24673e9318491fdcced7576a39b2cf910197ec 100644 (file)
@@ -15,6 +15,7 @@ rdma_rxe-y := \
        rxe_qp.o \
        rxe_cq.o \
        rxe_mr.o \
+       rxe_mw.o \
        rxe_opcode.o \
        rxe_mmap.o \
        rxe_icrc.o \
index b21038cb370f6ee4d018718ac7118ce749e5481c..422b9481d5f68152615949af359ac3fb8fe2acef 100644 (file)
@@ -76,6 +76,7 @@ enum copy_direction {
        from_mr_obj,
 };
 
+u8 rxe_get_next_key(u32 last_key);
 void rxe_mr_init_dma(struct rxe_pd *pd, int access, struct rxe_mr *mr);
 
 int rxe_mr_init_user(struct rxe_pd *pd, u64 start, u64 length, u64 iova,
@@ -106,6 +107,11 @@ void rxe_mr_cleanup(struct rxe_pool_entry *arg);
 
 int advance_dma_data(struct rxe_dma_info *dma, unsigned int length);
 
+/* rxe_mw.c */
+int rxe_alloc_mw(struct ib_mw *ibmw, struct ib_udata *udata);
+int rxe_dealloc_mw(struct ib_mw *ibmw);
+void rxe_mw_cleanup(struct rxe_pool_entry *arg);
+
 /* rxe_net.c */
 void rxe_loopback(struct sk_buff *skb);
 int rxe_send(struct rxe_pkt_info *pkt, struct sk_buff *skb);
index 373b46aab04377df5916b7b285016a62cbd9ecbe..cfd35a442c10dada42b9a2dfc6f5bc5a818a3c1f 100644 (file)
@@ -7,19 +7,17 @@
 #include "rxe.h"
 #include "rxe_loc.h"
 
-/*
- * lfsr (linear feedback shift register) with period 255
+/* Return a random 8 bit key value that is
+ * different than the last_key. Set last_key to -1
+ * if this is the first key for an MR or MW
  */
-static u8 rxe_get_key(void)
+u8 rxe_get_next_key(u32 last_key)
 {
-       static u32 key = 1;
-
-       key = key << 1;
-
-       key |= (0 != (key & 0x100)) ^ (0 != (key & 0x10))
-               ^ (0 != (key & 0x80)) ^ (0 != (key & 0x40));
+       u8 key;
 
-       key &= 0xff;
+       do {
+               get_random_bytes(&key, 1);
+       } while (key == last_key);
 
        return key;
 }
@@ -47,7 +45,7 @@ int mr_check_range(struct rxe_mr *mr, u64 iova, size_t length)
 
 static void rxe_mr_init(int access, struct rxe_mr *mr)
 {
-       u32 lkey = mr->pelem.index << 8 | rxe_get_key();
+       u32 lkey = mr->pelem.index << 8 | rxe_get_next_key(-1);
        u32 rkey = (access & IB_ACCESS_REMOTE) ? lkey : 0;
 
        mr->ibmr.lkey = lkey;
diff --git a/drivers/infiniband/sw/rxe/rxe_mw.c b/drivers/infiniband/sw/rxe/rxe_mw.c
new file mode 100644 (file)
index 0000000..69128e2
--- /dev/null
@@ -0,0 +1,53 @@
+// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
+/*
+ * Copyright (c) 2020 Hewlett Packard Enterprise, Inc. All rights reserved.
+ */
+
+#include "rxe.h"
+
+int rxe_alloc_mw(struct ib_mw *ibmw, struct ib_udata *udata)
+{
+       struct rxe_mw *mw = to_rmw(ibmw);
+       struct rxe_pd *pd = to_rpd(ibmw->pd);
+       struct rxe_dev *rxe = to_rdev(ibmw->device);
+       int ret;
+
+       rxe_add_ref(pd);
+
+       ret = rxe_add_to_pool(&rxe->mw_pool, mw);
+       if (ret) {
+               rxe_drop_ref(pd);
+               return ret;
+       }
+
+       rxe_add_index(mw);
+       ibmw->rkey = (mw->pelem.index << 8) | rxe_get_next_key(-1);
+       mw->state = (mw->ibmw.type == IB_MW_TYPE_2) ?
+                       RXE_MW_STATE_FREE : RXE_MW_STATE_VALID;
+       spin_lock_init(&mw->lock);
+
+       return 0;
+}
+
+int rxe_dealloc_mw(struct ib_mw *ibmw)
+{
+       struct rxe_mw *mw = to_rmw(ibmw);
+       struct rxe_pd *pd = to_rpd(ibmw->pd);
+       unsigned long flags;
+
+       spin_lock_irqsave(&mw->lock, flags);
+       mw->state = RXE_MW_STATE_INVALID;
+       spin_unlock_irqrestore(&mw->lock, flags);
+
+       rxe_drop_ref(mw);
+       rxe_drop_ref(pd);
+
+       return 0;
+}
+
+void rxe_mw_cleanup(struct rxe_pool_entry *elem)
+{
+       struct rxe_mw *mw = container_of(elem, typeof(*mw), pelem);
+
+       rxe_drop_index(mw);
+}
index df0bec719341d47363a516ad788dc1c23594190b..0b8e7c6255a25560db16a250bf7c220a5de45b99 100644 (file)
@@ -65,6 +65,7 @@ struct rxe_type_info rxe_type_info[RXE_NUM_TYPES] = {
                .name           = "rxe-mw",
                .size           = sizeof(struct rxe_mw),
                .elem_offset    = offsetof(struct rxe_mw, pelem),
+               .cleanup        = rxe_mw_cleanup,
                .flags          = RXE_POOL_INDEX | RXE_POOL_NO_ALLOC,
                .max_index      = RXE_MAX_MW_INDEX,
                .min_index      = RXE_MIN_MW_INDEX,
index 33731b5dd9c31e3f059b04628af243522430a0ea..b128ff9f4427b849c0781a5bbb3b08ad9c7530ce 100644 (file)
@@ -1106,6 +1106,7 @@ static const struct ib_device_ops rxe_dev_ops = {
 
        .alloc_hw_stats = rxe_ib_alloc_hw_stats,
        .alloc_mr = rxe_alloc_mr,
+       .alloc_mw = rxe_alloc_mw,
        .alloc_pd = rxe_alloc_pd,
        .alloc_ucontext = rxe_alloc_ucontext,
        .attach_mcast = rxe_attach_mcast,
@@ -1115,6 +1116,7 @@ static const struct ib_device_ops rxe_dev_ops = {
        .create_srq = rxe_create_srq,
        .create_user_ah = rxe_create_ah,
        .dealloc_driver = rxe_dealloc,
+       .dealloc_mw = rxe_dealloc_mw,
        .dealloc_pd = rxe_dealloc_pd,
        .dealloc_ucontext = rxe_dealloc_ucontext,
        .dereg_mr = rxe_dereg_mr,
index 207bbd5014e9cd03b36c6fa88dde6d73771a46bf..5effb12d22cc21b62de888a06b929f6b7b36737c 100644 (file)
@@ -326,6 +326,8 @@ enum rxe_mw_state {
 struct rxe_mw {
        struct ib_mw ibmw;
        struct rxe_pool_entry pelem;
+       spinlock_t lock;
+       enum rxe_mw_state state;
 };
 
 struct rxe_mc_grp {