首页 > 其他分享 >rdma-mr内核接口rxe_reg_user_mr

rdma-mr内核接口rxe_reg_user_mr

时间:2023-09-11 14:01:46浏览次数:39  
标签:struct mem rxe iwmr umem rdma mr

描述:注册用户内存区域【通过IB_USER_VERBS_CMD_REG_MR】

根据type

流程:

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_user(pd, start, length, iova, ccess, udata, mr)

g)    mr:rxe_mem_init(0, mem)->生成lkey和rkey

h)    返回新分配的mr

       Ops_rxe:

/**

 * rxe_reg_user_mr - Register a user memory region

 * @pd: ptr of pd

 * @start: virtual start address

 * @length: length of mr

 * @virt: virtual address

 * @acc: access of mr

 * @udata: user data

static struct ib_mr *rxe_reg_user_mr(struct ib_pd *ibpd,

                     u64 start,

                     u64 length,

                     u64 iova,

                     int access, struct ib_udata *udata)

{

    err = rxe_mem_init_user(pd, start, length, iova,

                access, udata, mr);


}

rxe_mem_init_user()

int rxe_mem_init_user(struct rxe_pd *pd, u64 start,

              u64 length, u64 iova, int access, struct ib_udata *udata,

              struct rxe_mem *mem)

{

    struct rxe_map      **map;

    struct rxe_phys_buf *buf = NULL;

    struct ib_umem      *umem;

    struct sg_page_iter sg_iter;

    int         num_buf;

    void            *vaddr;

    int err;


    umem = ib_umem_get(udata, start, length, access, 0);

    if (IS_ERR(umem)) {

        pr_warn("err %d from rxe_umem_get\n",

            (int)PTR_ERR(umem));

        err = -EINVAL;

        goto err1;


    mem->umem = umem;

    num_buf = ib_umem_num_pages(umem);


    rxe_mem_init(access, mem);


    err = rxe_mem_alloc(mem, num_buf);

    if (err) {

        pr_warn("err %d from rxe_mem_alloc\n", err);

        ib_umem_release(umem);

        goto err1;


    mem->page_shift     =

    mem->page_mask = PAGE_SIZE - 1;


    num_buf         = 0;

    map         = mem->map;

    if (length > 0) {

        buf = map[0]->buf;


        for_each_sg_page(umem->sg_head.sgl, &sg_iter, umem->nmap, 0) {

            if (num_buf >= RXE_BUF_PER_MAP) {

                map++;

                buf = map[0]->buf;

                num_buf = 0;


            vaddr = page_address(sg_page_iter_page(&sg_iter));

            if (!vaddr) {

                pr_warn("null vaddr\n");

                err = -ENOMEM;

                goto


            buf->addr = (uintptr_t)vaddr;

            buf->size =

            num_buf++;

            buf++;



    mem->pd         = pd;

    mem->umem       = umem;

    mem->access     = access;

    mem->length     = length;

    mem->iova       = iova;

    mem->va         = start;

    mem->offset     = ib_umem_offset(umem);

    mem->state      = RXE_MEM_STATE_VALID;

    mem->type       = RXE_MEM_TYPE_MR;


    return 0;


err1:

return err;

ops_i40iw:

/**

 * i40iw_reg_user_mr - Register a user memory region

 * @pd: ptr of pd

 * @start: virtual start address

 * @length: length of mr

 * @virt: virtual address

 * @acc: access of mr

 * @udata: user data

 */

static struct ib_mr *i40iw_reg_user_mr(struct ib_pd *pd,

                       u64 start,

                       u64 length,

                       u64 virt,

                       int acc,

                       struct ib_udata *udata)

{

    struct i40iw_pd *iwpd = to_iwpd(pd);

    struct i40iw_device *iwdev = to_iwdev(pd->device);

    struct i40iw_ucontext *ucontext = rdma_udata_to_drv_context(

        udata, struct

    struct i40iw_pble_alloc *palloc;

    struct i40iw_pbl *iwpbl;

    struct i40iw_mr *iwmr;

    struct ib_umem *region;

    struct i40iw_mem_reg_req req;

    u64 pbl_depth = 0;

    u32 stag = 0;

    u16 access;

    u64 region_length;

    bool use_pbles = false;

    unsigned long flags;

    int err = -ENOSYS;

    int ret;

    int pg_shift;


    if (iwdev->closing)

        return ERR_PTR(-ENODEV);


    if (length > I40IW_MAX_MR_SIZE)

        return ERR_PTR(-EINVAL);

    region = ib_umem_get(udata, start, length, acc, 0);

    if (IS_ERR(region))

        return (struct ib_mr *)region;


    if (ib_copy_from_udata(&req, udata, sizeof(req))) {

        ib_umem_release(region);

        return ERR_PTR(-EFAULT);


    iwmr = kzalloc(sizeof(*iwmr), GFP_KERNEL);

    if (!iwmr) {

        ib_umem_release(region);

        return ERR_PTR(-ENOMEM);


    iwpbl = &iwmr->iwpbl;

    iwpbl->iwmr = iwmr;

    iwmr->region = region;

    iwmr->ibmr.pd = pd;

    iwmr->ibmr.device = pd->device;


    iwmr->page_size =

    if (req.reg_type ==

        iwmr->page_size = ib_umem_find_best_pgsz(region, SZ_4K |

                             virt);


    region_length = region->length + (start & (iwmr->page_size - 1));

    pg_shift = ffs(iwmr->page_size) - 1;

    pbl_depth = region_length >> pg_shift;

    pbl_depth += (region_length & (iwmr->page_size - 1)) ? 1 : 0;

    iwmr->length = region->length;


    iwpbl->user_base = virt;

    palloc = &iwpbl->pble_alloc;


    iwmr->type = req.reg_type;

    iwmr->page_cnt =


    switch (req.reg_type) {

    case

        use_pbles = ((req.sq_pages + req.rq_pages) > 2);

        err = i40iw_handle_q_mem(iwdev, &req, iwpbl, use_pbles);

        if (err)

            goto error;

        spin_lock_irqsave(&ucontext->qp_reg_mem_list_lock, flags);

        list_add_tail(&iwpbl->list, &ucontext->qp_reg_mem_list);

        iwpbl->on_list = true;

        spin_unlock_irqrestore(&ucontext->qp_reg_mem_list_lock, flags);

        break;

    case

        use_pbles = (req.cq_pages > 1);

        err = i40iw_handle_q_mem(iwdev, &req, iwpbl, use_pbles);

        if (err)

            goto error;


        spin_lock_irqsave(&ucontext->cq_reg_mem_list_lock, flags);

        list_add_tail(&iwpbl->list, &ucontext->cq_reg_mem_list);

        iwpbl->on_list = true;

        spin_unlock_irqrestore(&ucontext->cq_reg_mem_list_lock, flags);

        break;

    case

        use_pbles = (iwmr->page_cnt != 1);

        access = I40IW_ACCESS_FLAGS_LOCALREAD;


        err = i40iw_setup_pbles(iwdev, iwmr, use_pbles);

        if (err)

            goto error;


        if (use_pbles) {

            ret = i40iw_check_mr_contiguous(palloc, iwmr->page_size);

            if (ret) {

                i40iw_free_pble(iwdev->pble_rsrc, palloc);

                iwpbl->pbl_allocated = false;


        access |= i40iw_get_user_access(acc);

        stag = i40iw_create_stag(iwdev);

        if (!stag) {

            err = -ENOMEM;

            goto error;


        iwmr->stag = stag;

        iwmr->ibmr.rkey = stag;

        iwmr->ibmr.lkey = stag;


        err = i40iw_hwreg_mr(iwdev, iwmr, access);

        if (err) {

            i40iw_free_stag(iwdev, stag);

            goto error;


        break;

    default:

        goto error;


    iwmr->type = req.reg_type;

    if (req.reg_type ==

        i40iw_add_pdusecount(iwpd);

    return &iwmr->ibmr;


error:

    if (palloc->level != I40IW_LEVEL_0 && iwpbl->pbl_allocated)

        i40iw_free_pble(iwdev->pble_rsrc, palloc);

    ib_umem_release(region);

    kfree(iwmr);

    return ERR_PTR(err);

}

标签:struct,mem,rxe,iwmr,umem,rdma,mr
From: https://blog.51cto.com/u_16113732/7435693

相关文章

  • MRP物料需求计划的逻辑原理
    【摘要】MRP是生产制造企业“管好”物料的核心工具方法,基本思想是根据客户对最终产品的需求数量和需求时间,按产品的结构精确地算出所有零件和部件的数量,并按各种零件和部件的生产周期或采购周期(Leadtime,提前期),反推出它们的生产计划和采购计划。本期介绍MRP的基本逻辑原理和相关......
  • RDMA-内核接口-rxe_map_mr_sg
    描述:映射mr的sg调用链:此处多处调用staticintnvme_rdma_map_sg_fr(structnvme_rdma_queue*queue,    structnvme_rdma_request*req,structnvme_command*c,    intcount){   req->mr=ib_mr_pool_get(queue->qp,&queue->qp->rdma_mrs);  /*  ......
  • 构筑下一代数据中心互联的“超级高速公路”,中科驭数正式发布KPU FLEXFLOW®-2100R RDM
    2023服贸会期间,中科驭数重磅推出最新自研的高性能网络“利器”——KPUFLEXFLOW®-2100RRDMA加速DPU卡。这款产品的发布标志着中科驭数在高性能计算和数据中心领域的不断创新,旨在面向高速网络、高性能存储搭建起算力集群内部通信的"超级高速公路”,助力高性能计算领域创新。站在数......
  • 玉米表型数据,KL,ERN,KT,CC,MRDV,SCMV分别代表什么
    KL:KernelLength(粒子长度)-这通常指的是玉米粒的长度,是玉米品质和产量方面的重要性状之一。ERN:EarNumber(穗数)-这可能表示每株玉米植株上的穗数,也是产量和生长特性的一项重要指标。KT:KernelThickness(粒子厚度)-这可能指的是玉米粒的厚度或宽度,也与品质和产量相关。......
  • RDMA-MR内核接口-rxe_get_dma_mr
    描述:注册物理内存,获取具有数据传输所需密钥的内存区域结构.get_dma_mr=rxe_get_dma_mr,内核的PD下面会注册一个内部的特殊MR,这个MR的范围包含了所有的系统内存。然后如果内核态的RDMA用户创建PD的时候传入了这个flag,就会把这个MR的R_Key挂在PD结构体的unsafe_global_rkey里面返回......
  • 使用 Hue 玩转 Amazon EMR(SparkSQL, Phoenix) 和 Amazon Redshift
    现状ApacheHue是一个基于Web的交互式SQL助手,通过它可以帮助大数据从业人员(数仓工程师,数据分析师等)与数据仓库进行SQL交互。在AmazonEMR集群启动时,通过勾选Hue进行安装。在Hue启用以后,将原先需要登录主节点进行SQL编写及提交的工作转移到web前端,不仅方便统一管......
  • .NET API 中的 FromRoute、FromQuery、FromBody 用法
    原文链接:https://www.cnblogs.com/ysmc/p/17663663.html最近技术交流群里,还有不少小伙伴不知道 FromRoute、FromQuery、FromBody这几个特性是怎么使用的,也不清楚它们之间的区别在哪里,特意写下这个文章,希望可以帮助到迷茫的小伙伴。在API开发过程中,我们先要确定我们的接口......
  • error: undefined reference to `cv::imread(cv::String const&, int)' 解决方法
    方法1原文链接:https://blog.csdn.net/WhiteLiu/article/details/72901520编译时出现下列错误:undefinedreferenceto'cv::imread(cv::Stringconst&,int)'undefinedreferenceto'cv::String::deallocate()'undefinedreferenceto'cv::imread(cv::S......
  • RDMA远程直接内存访问
    RDMA(RemoteDirectMemoryAccess)技术全称远程直接内存访问,就是为了解决网络传输中服务器端数据处理的延迟而产生的。它将数据直接从一台计算机的内存传输到另一台计算机,无需双方操作系统的介入。这允许高吞吐、低延迟的网络通信,尤其适合在大规模并行计算机集群中使用。RDMA通过网......
  • m基于MRC的MIMO分集接收matlab仿真
    1.算法仿真效果matlab2022a仿真结果如下:  2.算法涉及理论知识概要        多输入多输出(MIMO)系统利用多个发射和接收天线来提高无线通信系统的性能。MIMO技术通过空间多样性和信道多样性来增强系统容量、抗干扰性和可靠性。在MIMO系统中,分集是一种关键技术,它利用......