描述:注册物理内存,获取具有数据传输所需密钥的内存区域结构
.get_dma_mr = rxe_get_dma_mr,
内核的PD下面会注册一个内部的特殊MR,这个MR的范围包含了所有的系统内存。然后如果内核态的RDMA用户创建PD的时候传入了这个flag,就会把这个MR的R_Key挂在PD结构体的unsafe_global_rkey里面返回给用户。用户可以把这个R_Key传给对端使用,对端就可以用这个R_Key访问本端的全部内存了,可以避免频繁注册MR带来的开销。
调用链:Allocates an unused protection domain.
a) 类型转换为rxe类型
b) 验证mr_type
c) 申请rxe_mem: mr = rxe_alloc(&rxe->mr_pool);
d) 为mr分配索引:rxe_add_index(mr)
e) 对对象进行引用:rxe_add_ref(pd)
f) 构成mr:rxe_mem_init_dam(pd, max_num_sg, mr);
l int rxe_mem_init_dma(struct rxe_pd *pd,
int max_pages, struct rxe_mem *mem)
l 初始化mr:rxe_mem_init(0, mem)->生成lkey和rkey
g) 返回新分配的mr
struct ib_pd *__ib_alloc_pd(struct ib_device *device, unsigned int flags,const char *caller){
mr = pd->device->ops.get_dma_mr(pd, mr_access_flags);
}
Ops_rxe
.get_dma_mr = rxe_get_dma_mr
static struct ib_mr *rxe_get_dma_mr(struct ib_pd *ibpd, int access)
{
err = rxe_mem_init_dma(pd, access, mr);
}
int rxe_mem_init_dma(struct rxe_pd *pd,
int access, struct rxe_mem *mem)
{
rxe_mem_init(access, mem);
mem->pd = pd;
mem->access = access;
mem->state = RXE_MEM_STATE_VALID;
mem->type = RXE_MEM_TYPE_DMA;
return 0;
}
Ops_i40iw
static struct ib_mr *i40iw_get_dma_mr(struct ib_pd *pd, int acc)
{
u64 kva = 0;
return i40iw_reg_phys_mr(pd, 0, 0, acc, &kva);
}
/**
* i40iw_reg_phys_mr - register kernel physical memory
* @pd: ibpd pointer
* @addr: physical address of memory to register
* @size: size of memory to register
* @acc: Access rights
* @iova_start: start of virtual address for physical buffers
*/
struct ib_mr *i40iw_reg_phys_mr(struct ib_pd *pd,
u64 addr,
u64 size,
int acc,
u64 *iova_start)
{
struct i40iw_pd *iwpd = to_iwpd(pd);
struct i40iw_device *iwdev = to_iwdev(pd->device);
struct i40iw_pbl *iwpbl;
struct i40iw_mr *iwmr;
enum i40iw_status_code status;
u32 stag;
u16 access = I40IW_ACCESS_FLAGS_LOCALREAD;
int ret;
iwmr = kzalloc(sizeof(*iwmr), GFP_KERNEL);
if (!iwmr)
return ERR_PTR(-ENOMEM);
iwmr->ibmr.pd = pd;
iwmr->ibmr.device = pd->device;
iwpbl = &iwmr->iwpbl;
iwpbl->iwmr = iwmr;
iwmr->type =
iwpbl->user_base = *iova_start;
stag = i40iw_create_stag(iwdev);
if (!stag) {
ret = -EOVERFLOW;
goto err;
access |= i40iw_get_user_access(acc);
iwmr->stag = stag;
iwmr->ibmr.rkey = stag;
iwmr->ibmr.lkey = stag;
iwmr->page_cnt = 1;
iwmr->pgaddrmem[0] = addr;
iwmr->length = size;
status = i40iw_hwreg_mr(iwdev, iwmr, access);
if (status) {
i40iw_free_stag(iwdev, stag);
ret = -ENOMEM;
goto err;
i40iw_add_pdusecount(iwpd);
return &iwmr->ibmr;
err:
kfree(iwmr);
return ERR_PTR(ret);
}
标签:dma,struct,get,mem,rxe,iwmr,pd,mr From: https://blog.51cto.com/u_16113732/7394524