mirror of
https://github.com/linux-msm/laptops-kernel.git
synced 2026-08-13 14:19:53 -07:00
Merge tag 'nvme-7.1-2026-05-21' of git://git.infradead.org/nvme into block-7.1
Pull NVMe fixes from Keith: "- Fix memory leak for peer-to-peer addresses - Fix dma map leaks on resource errors" * tag 'nvme-7.1-2026-05-21' of git://git.infradead.org/nvme: nvme-pci: fix dma mapping leak on data setup error nvme-pci: fix dma_vecs leak on p2p memory
This commit is contained in:
+30
-4
@@ -966,7 +966,8 @@ static bool nvme_pci_prp_save_mapping(struct request *req,
|
||||
{
|
||||
struct nvme_iod *iod = blk_mq_rq_to_pdu(req);
|
||||
|
||||
if (dma_use_iova(&iod->dma_state) || !dma_need_unmap(dma_dev))
|
||||
if (dma_use_iova(&iod->dma_state) || !dma_need_unmap(dma_dev) ||
|
||||
(iod->flags & IOD_DATA_P2P))
|
||||
return true;
|
||||
|
||||
if (!iod->nr_dma_vecs) {
|
||||
@@ -996,6 +997,23 @@ static bool nvme_pci_prp_iter_next(struct request *req, struct device *dma_dev,
|
||||
return nvme_pci_prp_save_mapping(req, dma_dev, iter);
|
||||
}
|
||||
|
||||
static void nvme_unmap_iter(struct request *req, struct blk_dma_iter *iter,
|
||||
struct dma_iova_state *state)
|
||||
{
|
||||
struct nvme_queue *nvmeq = req->mq_hctx->driver_data;
|
||||
struct device *dev = nvmeq->dev->dev;
|
||||
|
||||
if (!blk_rq_dma_unmap(req, dev, state, iter->len, iter->p2pdma.map)) {
|
||||
unsigned int attrs = 0;
|
||||
|
||||
if (iter->p2pdma.map == PCI_P2PDMA_MAP_THRU_HOST_BRIDGE)
|
||||
attrs |= DMA_ATTR_MMIO;
|
||||
|
||||
dma_unmap_phys(dev, iter->addr, iter->len, rq_dma_dir(req),
|
||||
attrs);
|
||||
}
|
||||
}
|
||||
|
||||
static blk_status_t nvme_pci_setup_data_prp(struct request *req,
|
||||
struct blk_dma_iter *iter)
|
||||
{
|
||||
@@ -1006,8 +1024,10 @@ static blk_status_t nvme_pci_setup_data_prp(struct request *req,
|
||||
unsigned int prp_len, i;
|
||||
__le64 *prp_list;
|
||||
|
||||
if (!nvme_pci_prp_save_mapping(req, nvmeq->dev->dev, iter))
|
||||
if (!nvme_pci_prp_save_mapping(req, nvmeq->dev->dev, iter)) {
|
||||
nvme_unmap_iter(req, iter, &iod->dma_state);
|
||||
return iter->status;
|
||||
}
|
||||
|
||||
/*
|
||||
* PRP1 always points to the start of the DMA transfers.
|
||||
@@ -1112,6 +1132,7 @@ bad_sgl:
|
||||
dev_err_once(nvmeq->dev->dev,
|
||||
"Incorrectly formed request for payload:%d nents:%d\n",
|
||||
blk_rq_payload_bytes(req), blk_rq_nr_phys_segments(req));
|
||||
nvme_unmap_data(req);
|
||||
return BLK_STS_IOERR;
|
||||
}
|
||||
|
||||
@@ -1155,8 +1176,11 @@ static blk_status_t nvme_pci_setup_data_sgl(struct request *req,
|
||||
|
||||
sg_list = dma_pool_alloc(nvme_dma_pool(nvmeq, iod), GFP_ATOMIC,
|
||||
&sgl_dma);
|
||||
if (!sg_list)
|
||||
if (!sg_list) {
|
||||
nvme_unmap_iter(req, iter, &iod->dma_state);
|
||||
return BLK_STS_RESOURCE;
|
||||
}
|
||||
|
||||
iod->descriptors[iod->nr_descriptors++] = sg_list;
|
||||
|
||||
do {
|
||||
@@ -1313,8 +1337,10 @@ static blk_status_t nvme_pci_setup_meta_iter(struct request *req)
|
||||
|
||||
sg_list = dma_pool_alloc(nvmeq->descriptor_pools.small, GFP_ATOMIC,
|
||||
&sgl_dma);
|
||||
if (!sg_list)
|
||||
if (!sg_list) {
|
||||
nvme_unmap_iter(req, &iter, &iod->meta_dma_state);
|
||||
return BLK_STS_RESOURCE;
|
||||
}
|
||||
|
||||
iod->meta_descriptor = sg_list;
|
||||
iod->meta_dma = sgl_dma;
|
||||
|
||||
Reference in New Issue
Block a user