]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
nvmet: Introduce helper functions to allocate and free request SGLs
authorLogan Gunthorpe <logang@deltatee.com>
Thu, 4 Oct 2018 21:27:46 +0000 (15:27 -0600)
committerBjorn Helgaas <bhelgaas@google.com>
Wed, 17 Oct 2018 17:18:23 +0000 (12:18 -0500)
Add helpers to allocate and free the SGL in a struct nvmet_req:

  int nvmet_req_alloc_sgl(struct nvmet_req *req)
  void nvmet_req_free_sgl(struct nvmet_req *req)

This will be expanded in a future patch to implement peer-to-peer memory
DMAs and should be common with all target drivers.

The new helpers are used in nvmet-rdma.  Seeing we use req.transfer_len as
the length of the SGL it is set earlier and cleared on any error.  It also
seems to be unnecessary to accumulate the length as the map_sgl functions
should only ever be called once per request.

Signed-off-by: Logan Gunthorpe <logang@deltatee.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Acked-by: Sagi Grimberg <sagi@grimberg.me>
drivers/nvme/target/core.c
drivers/nvme/target/nvmet.h
drivers/nvme/target/rdma.c

index b5ec96abd04870209ed7ea97452180cf6cb63038..310b9fb54f6a92123fc584ec0c9a55e277efff80 100644 (file)
@@ -725,6 +725,24 @@ void nvmet_req_execute(struct nvmet_req *req)
 }
 EXPORT_SYMBOL_GPL(nvmet_req_execute);
 
+int nvmet_req_alloc_sgl(struct nvmet_req *req)
+{
+       req->sg = sgl_alloc(req->transfer_len, GFP_KERNEL, &req->sg_cnt);
+       if (!req->sg)
+               return -ENOMEM;
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(nvmet_req_alloc_sgl);
+
+void nvmet_req_free_sgl(struct nvmet_req *req)
+{
+       sgl_free(req->sg);
+       req->sg = NULL;
+       req->sg_cnt = 0;
+}
+EXPORT_SYMBOL_GPL(nvmet_req_free_sgl);
+
 static inline bool nvmet_cc_en(u32 cc)
 {
        return (cc >> NVME_CC_EN_SHIFT) & 0x1;
index ec9af4ee03b603cb2e4e68c23e78d9b59a1a331a..e7b7406c4e22b6ecee6f0e5347164ff5fd758ce7 100644 (file)
@@ -336,6 +336,8 @@ bool nvmet_req_init(struct nvmet_req *req, struct nvmet_cq *cq,
 void nvmet_req_uninit(struct nvmet_req *req);
 void nvmet_req_execute(struct nvmet_req *req);
 void nvmet_req_complete(struct nvmet_req *req, u16 status);
+int nvmet_req_alloc_sgl(struct nvmet_req *req);
+void nvmet_req_free_sgl(struct nvmet_req *req);
 
 void nvmet_cq_setup(struct nvmet_ctrl *ctrl, struct nvmet_cq *cq, u16 qid,
                u16 size);
index bfc4da660bb4036c9d53764793824f5befb3edb2..9e091e78a2f06221a13fdf48d84d980f19d704f2 100644 (file)
@@ -503,7 +503,7 @@ static void nvmet_rdma_release_rsp(struct nvmet_rdma_rsp *rsp)
        }
 
        if (rsp->req.sg != rsp->cmd->inline_sg)
-               sgl_free(rsp->req.sg);
+               nvmet_req_free_sgl(&rsp->req);
 
        if (unlikely(!list_empty_careful(&queue->rsp_wr_wait_list)))
                nvmet_rdma_process_wr_wait_list(queue);
@@ -652,24 +652,24 @@ static u16 nvmet_rdma_map_sgl_keyed(struct nvmet_rdma_rsp *rsp,
 {
        struct rdma_cm_id *cm_id = rsp->queue->cm_id;
        u64 addr = le64_to_cpu(sgl->addr);
-       u32 len = get_unaligned_le24(sgl->length);
        u32 key = get_unaligned_le32(sgl->key);
        int ret;
 
+       rsp->req.transfer_len = get_unaligned_le24(sgl->length);
+
        /* no data command? */
-       if (!len)
+       if (!rsp->req.transfer_len)
                return 0;
 
-       rsp->req.sg = sgl_alloc(len, GFP_KERNEL, &rsp->req.sg_cnt);
-       if (!rsp->req.sg)
-               return NVME_SC_INTERNAL;
+       ret = nvmet_req_alloc_sgl(&rsp->req);
+       if (ret < 0)
+               goto error_out;
 
        ret = rdma_rw_ctx_init(&rsp->rw, cm_id->qp, cm_id->port_num,
                        rsp->req.sg, rsp->req.sg_cnt, 0, addr, key,
                        nvmet_data_dir(&rsp->req));
        if (ret < 0)
-               return NVME_SC_INTERNAL;
-       rsp->req.transfer_len += len;
+               goto error_out;
        rsp->n_rdma += ret;
 
        if (invalidate) {
@@ -678,6 +678,10 @@ static u16 nvmet_rdma_map_sgl_keyed(struct nvmet_rdma_rsp *rsp,
        }
 
        return 0;
+
+error_out:
+       rsp->req.transfer_len = 0;
+       return NVME_SC_INTERNAL;
 }
 
 static u16 nvmet_rdma_map_sgl(struct nvmet_rdma_rsp *rsp)