RDMA/rw: Fix error flow during RDMA context initialization
In case the SGL was mapped for P2P DMA operation, we must unmap it using
pci_p2pdma_unmap_sg during the error unwind of rdma_rw_ctx_init()
Fixes: 7f73eac3a7
("PCI/P2PDMA: Introduce pci_p2pdma_unmap_sg()")
Link: https://lore.kernel.org/r/20200220100819.41860-1-maxg@mellanox.com
Signed-off-by: Max Gurtovoy <maxg@mellanox.com>
Reviewed-by: Leon Romanovsky <leonro@mellanox.com>
Reviewed-by: Logan Gunthorpe <logang@deltatee.com>
Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
This commit is contained in:
parent
4ca501d6aa
commit
6affca140c
@ -273,6 +273,23 @@ static int rdma_rw_init_single_wr(struct rdma_rw_ctx *ctx, struct ib_qp *qp,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void rdma_rw_unmap_sg(struct ib_device *dev, struct scatterlist *sg,
|
||||||
|
u32 sg_cnt, enum dma_data_direction dir)
|
||||||
|
{
|
||||||
|
if (is_pci_p2pdma_page(sg_page(sg)))
|
||||||
|
pci_p2pdma_unmap_sg(dev->dma_device, sg, sg_cnt, dir);
|
||||||
|
else
|
||||||
|
ib_dma_unmap_sg(dev, sg, sg_cnt, dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rdma_rw_map_sg(struct ib_device *dev, struct scatterlist *sg,
|
||||||
|
u32 sg_cnt, enum dma_data_direction dir)
|
||||||
|
{
|
||||||
|
if (is_pci_p2pdma_page(sg_page(sg)))
|
||||||
|
return pci_p2pdma_map_sg(dev->dma_device, sg, sg_cnt, dir);
|
||||||
|
return ib_dma_map_sg(dev, sg, sg_cnt, dir);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* rdma_rw_ctx_init - initialize a RDMA READ/WRITE context
|
* rdma_rw_ctx_init - initialize a RDMA READ/WRITE context
|
||||||
* @ctx: context to initialize
|
* @ctx: context to initialize
|
||||||
@ -295,11 +312,7 @@ int rdma_rw_ctx_init(struct rdma_rw_ctx *ctx, struct ib_qp *qp, u8 port_num,
|
|||||||
struct ib_device *dev = qp->pd->device;
|
struct ib_device *dev = qp->pd->device;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (is_pci_p2pdma_page(sg_page(sg)))
|
ret = rdma_rw_map_sg(dev, sg, sg_cnt, dir);
|
||||||
ret = pci_p2pdma_map_sg(dev->dma_device, sg, sg_cnt, dir);
|
|
||||||
else
|
|
||||||
ret = ib_dma_map_sg(dev, sg, sg_cnt, dir);
|
|
||||||
|
|
||||||
if (!ret)
|
if (!ret)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
sg_cnt = ret;
|
sg_cnt = ret;
|
||||||
@ -338,7 +351,7 @@ int rdma_rw_ctx_init(struct rdma_rw_ctx *ctx, struct ib_qp *qp, u8 port_num,
|
|||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
out_unmap_sg:
|
out_unmap_sg:
|
||||||
ib_dma_unmap_sg(dev, sg, sg_cnt, dir);
|
rdma_rw_unmap_sg(dev, sg, sg_cnt, dir);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(rdma_rw_ctx_init);
|
EXPORT_SYMBOL(rdma_rw_ctx_init);
|
||||||
@ -588,11 +601,7 @@ void rdma_rw_ctx_destroy(struct rdma_rw_ctx *ctx, struct ib_qp *qp, u8 port_num,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_pci_p2pdma_page(sg_page(sg)))
|
rdma_rw_unmap_sg(qp->pd->device, sg, sg_cnt, dir);
|
||||||
pci_p2pdma_unmap_sg(qp->pd->device->dma_device, sg,
|
|
||||||
sg_cnt, dir);
|
|
||||||
else
|
|
||||||
ib_dma_unmap_sg(qp->pd->device, sg, sg_cnt, dir);
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(rdma_rw_ctx_destroy);
|
EXPORT_SYMBOL(rdma_rw_ctx_destroy);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user