RDMA/rxe: Add ib_alloc_mw and ib_dealloc_mw verbs

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>
This commit is contained in:
Bob Pearson 2021-06-07 23:25:47 -05:00 committed by Jason Gunthorpe
parent af732adfac
commit beec0239c3
7 changed files with 74 additions and 11 deletions

View 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 \

View 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);

View 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;
u8 key;
key = key << 1;
key |= (0 != (key & 0x100)) ^ (0 != (key & 0x10))
^ (0 != (key & 0x80)) ^ (0 != (key & 0x40));
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;

View file

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

View 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,

View 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,

View 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 {