Skip to content

Commit

Permalink
nvme-pci: optimize mapping single segment requests using SGLs
Browse files Browse the repository at this point in the history
If the controller supports SGLs we can take another short cut for single
segment request, given that we can always map those without another
indirection structure, and thus don't need to create a scatterlist
structure.

Signed-off-by: Christoph Hellwig <[email protected]>
Reviewed-by: Keith Busch <[email protected]>
Reviewed-by: Sagi Grimberg <[email protected]>
Reviewed-by: Chaitanya Kulkarni <[email protected]>
  • Loading branch information
Christoph Hellwig committed Apr 5, 2019
1 parent dff824b commit 2979105
Showing 1 changed file with 22 additions and 0 deletions.
22 changes: 22 additions & 0 deletions drivers/nvme/host/pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -819,6 +819,23 @@ static blk_status_t nvme_setup_prp_simple(struct nvme_dev *dev,
return 0;
}

static blk_status_t nvme_setup_sgl_simple(struct nvme_dev *dev,
struct request *req, struct nvme_rw_command *cmnd,
struct bio_vec *bv)
{
struct nvme_iod *iod = blk_mq_rq_to_pdu(req);

iod->first_dma = dma_map_bvec(dev->dev, bv, rq_dma_dir(req), 0);
if (dma_mapping_error(dev->dev, iod->first_dma))
return BLK_STS_RESOURCE;
iod->dma_len = bv->bv_len;

cmnd->dptr.sgl.addr = cpu_to_le64(iod->first_dma);
cmnd->dptr.sgl.length = cpu_to_le32(iod->dma_len);
cmnd->dptr.sgl.type = NVME_SGL_FMT_DATA_DESC << 4;
return 0;
}

static blk_status_t nvme_map_data(struct nvme_dev *dev, struct request *req,
struct nvme_command *cmnd)
{
Expand All @@ -836,6 +853,11 @@ static blk_status_t nvme_map_data(struct nvme_dev *dev, struct request *req,
if (bv.bv_offset + bv.bv_len <= dev->ctrl.page_size * 2)
return nvme_setup_prp_simple(dev, req,
&cmnd->rw, &bv);

if (iod->nvmeq->qid &&
dev->ctrl.sgls & ((1 << 0) | (1 << 1)))
return nvme_setup_sgl_simple(dev, req,
&cmnd->rw, &bv);
}
}

Expand Down

0 comments on commit 2979105

Please sign in to comment.