Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

nvme-pci: merge the simple PRP and SGL setup into a common helper

nvme_setup_prp_simple and nvme_setup_sgl_simple share a lot of logic.
Merge them into a single helper that makes use of the previously added
use_sgl tristate.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Keith Busch <kbusch@kernel.org>
Link: https://lore.kernel.org/r/20250625113531.522027-5-hch@lst.de
Signed-off-by: Jens Axboe <axboe@kernel.dk>

authored by

Christoph Hellwig and committed by
Jens Axboe
cd71b52a de769c84

+31 -43
+31 -43
drivers/nvme/host/pci.c
··· 817 817 return BLK_STS_OK; 818 818 } 819 819 820 - static blk_status_t nvme_setup_prp_simple(struct nvme_dev *dev, 821 - struct request *req, struct nvme_rw_command *cmnd, 822 - struct bio_vec *bv) 820 + static blk_status_t nvme_pci_setup_data_simple(struct request *req, 821 + enum nvme_use_sgl use_sgl) 823 822 { 824 823 struct nvme_iod *iod = blk_mq_rq_to_pdu(req); 825 - unsigned int offset = bv->bv_offset & (NVME_CTRL_PAGE_SIZE - 1); 826 - unsigned int first_prp_len = NVME_CTRL_PAGE_SIZE - offset; 824 + struct nvme_queue *nvmeq = req->mq_hctx->driver_data; 825 + struct bio_vec bv = req_bvec(req); 826 + unsigned int prp1_offset = bv.bv_offset & (NVME_CTRL_PAGE_SIZE - 1); 827 + bool prp_possible = prp1_offset + bv.bv_len <= NVME_CTRL_PAGE_SIZE * 2; 828 + dma_addr_t dma_addr; 827 829 828 - iod->first_dma = dma_map_bvec(dev->dev, bv, rq_dma_dir(req), 0); 829 - if (dma_mapping_error(dev->dev, iod->first_dma)) 830 + if (!use_sgl && !prp_possible) 831 + return BLK_STS_AGAIN; 832 + if (is_pci_p2pdma_page(bv.bv_page)) 833 + return BLK_STS_AGAIN; 834 + 835 + dma_addr = dma_map_bvec(nvmeq->dev->dev, &bv, rq_dma_dir(req), 0); 836 + if (dma_mapping_error(nvmeq->dev->dev, dma_addr)) 830 837 return BLK_STS_RESOURCE; 831 - iod->dma_len = bv->bv_len; 838 + iod->dma_len = bv.bv_len; 832 839 833 - cmnd->dptr.prp1 = cpu_to_le64(iod->first_dma); 834 - if (bv->bv_len > first_prp_len) 835 - cmnd->dptr.prp2 = cpu_to_le64(iod->first_dma + first_prp_len); 836 - else 837 - cmnd->dptr.prp2 = 0; 838 - return BLK_STS_OK; 839 - } 840 + if (use_sgl == SGL_FORCED || !prp_possible) { 841 + iod->cmd.common.flags = NVME_CMD_SGL_METABUF; 842 + iod->cmd.common.dptr.sgl.addr = cpu_to_le64(dma_addr); 843 + iod->cmd.common.dptr.sgl.length = cpu_to_le32(bv.bv_len); 844 + iod->cmd.common.dptr.sgl.type = NVME_SGL_FMT_DATA_DESC << 4; 845 + } else { 846 + unsigned int first_prp_len = NVME_CTRL_PAGE_SIZE - prp1_offset; 840 847 841 - static blk_status_t nvme_setup_sgl_simple(struct nvme_dev *dev, 842 - struct request *req, struct nvme_rw_command *cmnd, 843 - struct bio_vec *bv) 844 - { 845 - struct nvme_iod *iod = blk_mq_rq_to_pdu(req); 848 + iod->cmd.common.dptr.prp1 = cpu_to_le64(dma_addr); 849 + iod->cmd.common.dptr.prp2 = 0; 850 + if (bv.bv_len > first_prp_len) 851 + iod->cmd.common.dptr.prp2 = 852 + cpu_to_le64(dma_addr + first_prp_len); 853 + } 846 854 847 - iod->first_dma = dma_map_bvec(dev->dev, bv, rq_dma_dir(req), 0); 848 - if (dma_mapping_error(dev->dev, iod->first_dma)) 849 - return BLK_STS_RESOURCE; 850 - iod->dma_len = bv->bv_len; 851 - 852 - cmnd->flags = NVME_CMD_SGL_METABUF; 853 - cmnd->dptr.sgl.addr = cpu_to_le64(iod->first_dma); 854 - cmnd->dptr.sgl.length = cpu_to_le32(iod->dma_len); 855 - cmnd->dptr.sgl.type = NVME_SGL_FMT_DATA_DESC << 4; 856 855 return BLK_STS_OK; 857 856 } 858 857 ··· 865 866 int rc; 866 867 867 868 if (blk_rq_nr_phys_segments(req) == 1) { 868 - struct bio_vec bv = req_bvec(req); 869 - 870 - if (!is_pci_p2pdma_page(bv.bv_page)) { 871 - if (!nvme_pci_metadata_use_sgls(dev, req) && 872 - (bv.bv_offset & (NVME_CTRL_PAGE_SIZE - 1)) + 873 - bv.bv_len <= NVME_CTRL_PAGE_SIZE * 2) 874 - return nvme_setup_prp_simple(dev, req, 875 - &cmnd->rw, &bv); 876 - 877 - if (nvmeq->qid && sgl_threshold && 878 - nvme_ctrl_sgl_supported(&dev->ctrl)) 879 - return nvme_setup_sgl_simple(dev, req, 880 - &cmnd->rw, &bv); 881 - } 869 + ret = nvme_pci_setup_data_simple(req, use_sgl); 870 + if (ret != BLK_STS_AGAIN) 871 + return ret; 882 872 } 883 873 884 874 iod->dma_len = 0;