static int iser_fast_reg_fmr(struct iscsi_iser_task *iser_task, struct iser_data_buf *mem, struct iser_reg_resources *rsc, struct iser_mem_reg *reg) { struct ib_conn *ib_conn = &iser_task->iser_conn->ib_conn; struct iser_device *device = ib_conn->device; struct iser_page_vec *page_vec = rsc->page_vec; struct ib_fmr_pool *fmr_pool = rsc->fmr_pool; struct ib_pool_fmr *fmr; int ret, plen; page_vec->npages = 0; page_vec->fake_mr.page_size = SIZE_4K; plen = ib_sg_to_pages(&page_vec->fake_mr, mem->sg, mem->size, NULL, iser_set_page); if (unlikely(plen < mem->size)) { iser_err("page vec too short to hold this SG\n"); iser_data_buf_dump(mem, device->ib_device); iser_dump_page_vec(page_vec); return -EINVAL; } fmr = ib_fmr_pool_map_phys(fmr_pool, page_vec->pages, page_vec->npages, page_vec->pages[0]); if (IS_ERR(fmr)) { ret = PTR_ERR(fmr); iser_err("ib_fmr_pool_map_phys failed: %d\n", ret); return ret; } reg->sge.lkey = fmr->fmr->lkey; reg->rkey = fmr->fmr->rkey; reg->sge.addr = page_vec->fake_mr.iova; reg->sge.length = page_vec->fake_mr.length; reg->mem_h = fmr; iser_dbg("fmr reg: lkey=0x%x, rkey=0x%x, addr=0x%llx," " length=0x%x\n", reg->sge.lkey, reg->rkey, reg->sge.addr, reg->sge.length); return 0; }
/** * iser_reg_page_vec - Register physical memory * * returns: 0 on success, errno code on failure */ int iser_reg_page_vec(struct iser_conn *ib_conn, struct iser_page_vec *page_vec, struct iser_mem_reg *mem_reg) { struct ib_pool_fmr *mem; u64 io_addr; u64 *page_list; int status; page_list = page_vec->pages; io_addr = page_list[0]; mem = ib_fmr_pool_map_phys(ib_conn->fmr_pool, page_list, page_vec->length, io_addr); if (IS_ERR(mem)) { status = (int)PTR_ERR(mem); iser_err("ib_fmr_pool_map_phys failed: %d\n", status); return status; } mem_reg->lkey = mem->fmr->lkey; mem_reg->rkey = mem->fmr->rkey; mem_reg->len = page_vec->length * SIZE_4K; mem_reg->va = io_addr; mem_reg->is_fmr = 1; mem_reg->mem_h = (void *)mem; mem_reg->va += page_vec->offset; mem_reg->len = page_vec->data_size; iser_dbg("PHYSICAL Mem.register, [PHYS p_array: 0x%p, sz: %d, " "entry[0]: (0x%08lx,%ld)] -> " "[lkey: 0x%08X mem_h: 0x%p va: 0x%08lX sz: %ld]\n", page_vec, page_vec->length, (unsigned long)page_vec->pages[0], (unsigned long)page_vec->data_size, (unsigned int)mem_reg->lkey, mem_reg->mem_h, (unsigned long)mem_reg->va, (unsigned long)mem_reg->len); return 0; }