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:
parent
af732adfac
commit
beec0239c3
@ -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 \
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
53
drivers/infiniband/sw/rxe/rxe_mw.c
Normal file
53
drivers/infiniband/sw/rxe/rxe_mw.c
Normal 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);
|
||||
}
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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 {
|
||||
|
Loading…
Reference in New Issue
Block a user