@@ -79,6 +79,7 @@ static void rxe_init_device_param(struct rxe_dev *rxe)
rxe->attr.max_cq = RXE_MAX_CQ;
rxe->attr.max_cqe = (1 << RXE_MAX_LOG_CQE) - 1;
rxe->attr.max_mr = RXE_MAX_MR;
+ rxe->attr.max_mw = RXE_MAX_MW;
rxe->attr.max_pd = RXE_MAX_PD;
rxe->attr.max_qp_rd_atom = RXE_MAX_QP_RD_ATOM;
rxe->attr.max_res_rd_atom = RXE_MAX_RES_RD_ATOM;
@@ -35,15 +35,64 @@
#include "rxe.h"
#include "rxe_loc.h"
+/* place holder alloc and dealloc routines
+ * need to add cross references between qp and mr with mw
+ * and cleanup when one side is deleted. Enough to make
+ * verbs function correctly for now */
struct ib_mw *rxe_alloc_mw(struct ib_pd *ibpd, enum ib_mw_type type,
struct ib_udata *udata)
{
- pr_err_once("rxe_alloc_mw: not implemented\n");
- return ERR_PTR(-ENOSYS);
+ struct rxe_pd *pd = to_rpd(ibpd);
+ struct rxe_dev *rxe = to_rdev(ibpd->device);
+ struct rxe_mw *mw;
+ u32 rkey;
+ u8 key;
+
+ if (unlikely((type != IB_MW_TYPE_1) &&
+ (type != IB_MW_TYPE_2)))
+ return ERR_PTR(-EINVAL);
+
+ rxe_add_ref(pd);
+
+ mw = rxe_alloc(&rxe->mw_pool);
+ if (!mw) {
+ rxe_drop_ref(pd);
+ return ERR_PTR(-ENOMEM);
+ }
+
+ /* pick a random key part as a starting point */
+ rxe_add_index(mw);
+ get_random_bytes(&key, sizeof(key));
+ rkey = mw->pelem.index << 8 | key;
+
+ spin_lock_init(&mw->lock);
+ mw->qp = NULL;
+ mw->mr = NULL;
+ mw->addr = 0;
+ mw->length = 0;
+ mw->ibmw.pd = ibpd;
+ mw->ibmw.type = type;
+ mw->ibmw.rkey = rkey;
+ mw->state = (type == IB_MW_TYPE_2) ?
+ RXE_MW_STATE_FREE :
+ RXE_MW_STATE_VALID;
+
+ return &mw->ibmw;
}
int rxe_dealloc_mw(struct ib_mw *ibmw)
{
- pr_err_once("rxe_dealloc_mw: not implemented\n");
- return -ENOSYS;
+ 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(pd);
+ rxe_drop_index(mw);
+ rxe_drop_ref(mw);
+
+ return 0;
}
@@ -85,7 +85,8 @@ enum rxe_device_param {
RXE_MAX_SGE_RD = 32,
RXE_MAX_CQ = 16384,
RXE_MAX_LOG_CQE = 15,
- RXE_MAX_MR = 256 * 1024,
+ RXE_MAX_MR = 0x40000,
+ RXE_MAX_MW = 0x40000,
RXE_MAX_PD = 0x7ffc,
RXE_MAX_QP_RD_ATOM = 128,
RXE_MAX_RES_RD_ATOM = 0x3f000,
@@ -114,9 +115,10 @@ enum rxe_device_param {
RXE_MAX_SRQ_INDEX = 0x00040000,
RXE_MIN_MR_INDEX = 0x00000001,
- RXE_MAX_MR_INDEX = 0x00040000,
- RXE_MIN_MW_INDEX = 0x00040001,
- RXE_MAX_MW_INDEX = 0x00060000,
+ RXE_MAX_MR_INDEX = RXE_MIN_MR_INDEX + RXE_MAX_MR - 1,
+ RXE_MIN_MW_INDEX = RXE_MIN_MR_INDEX + RXE_MAX_MR,
+ RXE_MAX_MW_INDEX = RXE_MIN_MW_INDEX + RXE_MAX_MW - 1,
+
RXE_MAX_PKT_PER_ACK = 64,
RXE_MAX_UNACKED_PSNS = 128,
@@ -85,7 +85,7 @@ struct rxe_type_info rxe_type_info[RXE_NUM_TYPES] = {
},
[RXE_TYPE_MW] = {
.name = "rxe-mw",
- .size = sizeof(struct rxe_mr),
+ .size = sizeof(struct rxe_mw),
.flags = RXE_POOL_INDEX,
.max_index = RXE_MAX_MW_INDEX,
.min_index = RXE_MIN_MW_INDEX,
@@ -358,7 +358,11 @@ struct rxe_mw {
struct ib_mw ibmw;
struct rxe_qp *qp; /* type 2B only */
struct rxe_mem *mr;
+ spinlock_t lock;
enum rxe_mw_state state;
+ u32 access;
+ u64 addr;
+ u64 length;
};
struct rxe_mc_grp {
Created basic functional alloc_mw and dealloc_mw funnctions and changed the parameters in rxe_param.h so that MWs can actually be created. This change supported running user space test cases for these APIs. Signed-off-by: Bob Pearson <rpearson@hpe.com> --- drivers/infiniband/sw/rxe/rxe.c | 1 + drivers/infiniband/sw/rxe/rxe_mw.c | 57 +++++++++++++++++++++++++-- drivers/infiniband/sw/rxe/rxe_param.h | 10 +++-- drivers/infiniband/sw/rxe/rxe_pool.c | 2 +- drivers/infiniband/sw/rxe/rxe_verbs.h | 4 ++ 5 files changed, 65 insertions(+), 9 deletions(-)