[PATCH 1/2] nvme-pci: refactor nvme_unmap_data
Marc Orr
marcorr at google.com
Wed Jan 20 10:19:34 EST 2021
On Wed, Jan 20, 2021 at 1:49 AM Christoph Hellwig <hch at lst.de> wrote:
>
> Split out three helpers from nvme_unmap_data that will allow finer grained
> unwinding from nvme_map_data.
>
> Signed-off-by: Christoph Hellwig <hch at lst.de>
> ---
> drivers/nvme/host/pci.c | 77 ++++++++++++++++++++++++++---------------
> 1 file changed, 49 insertions(+), 28 deletions(-)
>
> diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c
> index 25456d02eddb8c..e29ece9e4d4b8e 100644
> --- a/drivers/nvme/host/pci.c
> +++ b/drivers/nvme/host/pci.c
> @@ -543,50 +543,71 @@ static inline bool nvme_pci_use_sgls(struct nvme_dev *dev, struct request *req)
> return true;
> }
>
> -static void nvme_unmap_data(struct nvme_dev *dev, struct request *req)
> +static void nvme_free_prps(struct nvme_dev *dev, struct request *req)
> {
> - struct nvme_iod *iod = blk_mq_rq_to_pdu(req);
> const int last_prp = NVME_CTRL_PAGE_SIZE / sizeof(__le64) - 1;
> - dma_addr_t dma_addr = iod->first_dma, next_dma_addr;
> + struct nvme_iod *iod = blk_mq_rq_to_pdu(req);
> + dma_addr_t dma_addr = iod->first_dma;
> int i;
>
> - if (iod->dma_len) {
> - dma_unmap_page(dev->dev, dma_addr, iod->dma_len,
> - rq_dma_dir(req));
> - return;
> + for (i = 0; i < iod->npages; i++) {
> + __le64 *prp_list = nvme_pci_iod_list(req)[i];
> + dma_addr_t next_dma_addr = le64_to_cpu(prp_list[last_prp]);
> +
> + dma_pool_free(dev->prp_page_pool, prp_list, dma_addr);
> + dma_addr = next_dma_addr;
> }
>
> - WARN_ON_ONCE(!iod->nents);
> +}
>
> - if (is_pci_p2pdma_page(sg_page(iod->sg)))
> - pci_p2pdma_unmap_sg(dev->dev, iod->sg, iod->nents,
> - rq_dma_dir(req));
> - else
> - dma_unmap_sg(dev->dev, iod->sg, iod->nents, rq_dma_dir(req));
> +static void nvme_free_sgls(struct nvme_dev *dev, struct request *req)
> +{
> + const int last_sg = SGES_PER_PAGE - 1;
> + struct nvme_iod *iod = blk_mq_rq_to_pdu(req);
> + dma_addr_t dma_addr = iod->first_dma;
> + int i;
>
> + for (i = 0; i < iod->npages; i++) {
> + struct nvme_sgl_desc *sg_list = nvme_pci_iod_list(req)[i];
> + dma_addr_t next_dma_addr = le64_to_cpu((sg_list[last_sg]).addr);
>
> - if (iod->npages == 0)
> - dma_pool_free(dev->prp_small_pool, nvme_pci_iod_list(req)[0],
> - dma_addr);
> + dma_pool_free(dev->prp_page_pool, sg_list, dma_addr);
> + dma_addr = next_dma_addr;
> + }
>
> - for (i = 0; i < iod->npages; i++) {
> - void *addr = nvme_pci_iod_list(req)[i];
> +}
>
> - if (iod->use_sgl) {
> - struct nvme_sgl_desc *sg_list = addr;
> +static void nvme_unmap_sg(struct nvme_dev *dev, struct request *req)
> +{
> + struct nvme_iod *iod = blk_mq_rq_to_pdu(req);
>
> - next_dma_addr =
> - le64_to_cpu((sg_list[SGES_PER_PAGE - 1]).addr);
> - } else {
> - __le64 *prp_list = addr;
> + if (is_pci_p2pdma_page(sg_page(iod->sg)))
> + pci_p2pdma_unmap_sg(dev->dev, iod->sg, iod->nents,
> + rq_dma_dir(req));
> + else
> + dma_unmap_sg(dev->dev, iod->sg, iod->nents, rq_dma_dir(req));
> +}
>
> - next_dma_addr = le64_to_cpu(prp_list[last_prp]);
> - }
> +static void nvme_unmap_data(struct nvme_dev *dev, struct request *req)
> +{
> + struct nvme_iod *iod = blk_mq_rq_to_pdu(req);
>
> - dma_pool_free(dev->prp_page_pool, addr, dma_addr);
> - dma_addr = next_dma_addr;
> + if (iod->dma_len) {
> + dma_unmap_page(dev->dev, iod->first_dma, iod->dma_len,
> + rq_dma_dir(req));
> + return;
> }
>
> + WARN_ON_ONCE(!iod->nents);
> +
> + nvme_unmap_sg(dev, req);
> + if (iod->npages == 0)
> + dma_pool_free(dev->prp_small_pool, nvme_pci_iod_list(req)[0],
> + iod->first_dma);
> + else if (iod->use_sgl)
> + nvme_free_sgls(dev, req);
> + else
> + nvme_free_prps(dev, req);
> mempool_free(iod->sg, dev->iod_mempool);
> }
Reviewed-by: Marc Orr <marcorr at google.com>
>
> --
> 2.29.2
>
More information about the Linux-nvme
mailing list