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: refactor nvme_pci_use_sgls

Move the average segment size into a separate helper, and return a
tristate to distinguish the case where can use SGL vs where we have to
use SGLs. This will allow the simplify the code and make more efficient
decisions in follow on changes.

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

authored by

Christoph Hellwig and committed by
Jens Axboe
de769c84 858299dc

+27 -14
+27 -14
drivers/nvme/host/pci.c
··· 578 578 spin_unlock(&nvmeq->sq_lock); 579 579 } 580 580 581 + enum nvme_use_sgl { 582 + SGL_UNSUPPORTED, 583 + SGL_SUPPORTED, 584 + SGL_FORCED, 585 + }; 586 + 581 587 static inline bool nvme_pci_metadata_use_sgls(struct nvme_dev *dev, 582 588 struct request *req) 583 589 { ··· 593 587 nvme_req(req)->flags & NVME_REQ_USERCMD; 594 588 } 595 589 596 - static inline bool nvme_pci_use_sgls(struct nvme_dev *dev, struct request *req, 597 - int nseg) 590 + static inline enum nvme_use_sgl nvme_pci_use_sgls(struct nvme_dev *dev, 591 + struct request *req) 598 592 { 599 593 struct nvme_queue *nvmeq = req->mq_hctx->driver_data; 600 - unsigned int avg_seg_size; 601 594 602 - avg_seg_size = DIV_ROUND_UP(blk_rq_payload_bytes(req), nseg); 595 + if (nvmeq->qid && nvme_ctrl_sgl_supported(&dev->ctrl)) { 596 + if (nvme_req(req)->flags & NVME_REQ_USERCMD) 597 + return SGL_FORCED; 598 + if (req->nr_integrity_segments > 1) 599 + return SGL_FORCED; 600 + return SGL_SUPPORTED; 601 + } 603 602 604 - if (!nvme_ctrl_sgl_supported(&dev->ctrl)) 605 - return false; 606 - if (!nvmeq->qid) 607 - return false; 608 - if (nvme_pci_metadata_use_sgls(dev, req)) 609 - return true; 610 - if (!sgl_threshold || avg_seg_size < sgl_threshold) 611 - return nvme_req(req)->flags & NVME_REQ_USERCMD; 612 - return true; 603 + return SGL_UNSUPPORTED; 604 + } 605 + 606 + static unsigned int nvme_pci_avg_seg_size(struct request *req) 607 + { 608 + struct nvme_iod *iod = blk_mq_rq_to_pdu(req); 609 + 610 + return DIV_ROUND_UP(blk_rq_payload_bytes(req), iod->sgt.nents); 613 611 } 614 612 615 613 static inline struct dma_pool *nvme_dma_pool(struct nvme_queue *nvmeq, ··· 861 851 { 862 852 struct nvme_queue *nvmeq = req->mq_hctx->driver_data; 863 853 struct nvme_iod *iod = blk_mq_rq_to_pdu(req); 854 + enum nvme_use_sgl use_sgl = nvme_pci_use_sgls(dev, req); 864 855 blk_status_t ret = BLK_STS_RESOURCE; 865 856 int rc; 866 857 ··· 899 888 goto out_free_sg; 900 889 } 901 890 902 - if (nvme_pci_use_sgls(dev, req, iod->sgt.nents)) 891 + if (use_sgl == SGL_FORCED || 892 + (use_sgl == SGL_SUPPORTED && 893 + (sgl_threshold && nvme_pci_avg_seg_size(req) >= sgl_threshold))) 903 894 ret = nvme_pci_setup_sgls(nvmeq, req, &cmnd->rw); 904 895 else 905 896 ret = nvme_pci_setup_prps(nvmeq, req, &cmnd->rw);