0
点赞
收藏
分享

微信扫一扫

RDMA-内核接口-rxe_map_mr_sg

描述:映射mr的sg

调用链:

此处多处调用


static int nvme_rdma_map_sg_fr(struct nvme_rdma_queue *queue,

        struct nvme_rdma_request *req, struct nvme_command *c,

        int count)

{

    req->mr = ib_mr_pool_get(queue->qp, &queue->qp->rdma_mrs);

    /*

     * Align the MR to a 4K page size to match the ctrl page size and

     * the block virtual boundary.

     */

    nr = ib_map_mr_sg(req->mr, req->sg_table.sgl, count, NULL, SZ_4K);


}


映射dma映射的SG列表的最大前缀,并将其设置为内存区域

int ib_map_mr_sg(struct ib_mr *mr, struct scatterlist *sg, int sg_nents,

         unsigned int *sg_offset, unsigned int page_size)

{

    if (unlikely(!mr->device->ops.map_mr_sg))

        return -EOPNOTSUPP;


    mr->page_size = page_size;


    return mr->device->ops.map_mr_sg(mr, sg, sg_nents, sg_offset);

}

Ops_rxe:

static int rxe_map_mr_sg(struct ib_mr *ibmr, struct scatterlist *sg,

             int sg_nents, unsigned int *sg_offset)

{

    struct rxe_mem *mr = to_rmr(ibmr);

    int n;


    mr->nbuf = 0;


    n = ib_sg_to_pages(ibmr, sg, sg_nents, sg_offset, rxe_set_page);


    mr->va = ibmr->iova;

    mr->iova = ibmr->iova;

    mr->length = ibmr->length;

    mr->page_shift = ilog2(ibmr->page_size);

    mr->page_mask = ibmr->page_size - 1;

    mr->offset = mr->iova & mr->page_mask;


    return n;

}

调用ib_sg_to_pages()方法,主要在驱动程序页分配函数指针rxe_set_page

static int rxe_set_page(struct ib_mr *ibmr, u64 addr)

{

    struct rxe_mem *mr = to_rmr(ibmr);

    struct rxe_map *map;

    struct rxe_phys_buf *buf;


    if (unlikely(mr->nbuf == mr->num_buf))

        return -ENOMEM;


    map = mr->map[mr->nbuf / RXE_BUF_PER_MAP];

    buf = &map->buf[mr->nbuf % RXE_BUF_PER_MAP];


    buf->addr = addr;

    buf->size = ibmr->page_size;

    mr->nbuf++;


    return 0;

}

Ops_i40iw:

static int i40iw_map_mr_sg(struct ib_mr *ibmr, struct scatterlist *sg,

               int sg_nents, unsigned int *sg_offset)

{

    struct i40iw_mr *iwmr = to_iwmr(ibmr);


    iwmr->npages = 0;

    return ib_sg_to_pages(ibmr, sg, sg_nents, sg_offset, i40iw_set_page);

}

调用ib_sg_to_pages()方法,主要在驱动程序页分配函数指针i40iw_set_page

static int i40iw_set_page(struct ib_mr *ibmr, u64 addr)

{

    struct i40iw_mr *iwmr = to_iwmr(ibmr);

    struct i40iw_pbl *iwpbl = &iwmr->iwpbl;

    struct i40iw_pble_alloc *palloc = &iwpbl->pble_alloc;

    u64 *pbl;


    if (unlikely(iwmr->npages == iwmr->page_cnt))

        return -ENOMEM;


    pbl = (u64 *)palloc->level1.addr;

    pbl[iwmr->npages++] = cpu_to_le64(addr);

    return 0;

}

举报

相关推荐

0 条评论