RDMA/efa: Use kvzalloc instead of kzalloc with fallback
Use kvzalloc which attempts to allocate a physically continuous buffer and fallbacks to virtually continuous on failure instead of open coding it in the driver. The is_vmalloc_addr function is used to determine whether the buffer is physically continuous or not (which determines direct vs indirect MR registration mode). Suggested-by: Jason Gunthorpe <jgg@ziepe.ca> Reviewed-by: Firas JahJah <firasj@amazon.com> Reviewed-by: Yossi Leybovich <sleybo@amazon.com> Signed-off-by: Gal Pressman <galpress@amazon.com> Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
This commit is contained in:
Родитель
5f5e4eb4fb
Коммит
255efcaeb6
|
@ -1285,30 +1285,30 @@ static int pbl_create(struct efa_dev *dev,
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
pbl->pbl_buf_size_in_bytes = hp_cnt * EFA_CHUNK_PAYLOAD_PTR_SIZE;
|
pbl->pbl_buf_size_in_bytes = hp_cnt * EFA_CHUNK_PAYLOAD_PTR_SIZE;
|
||||||
pbl->pbl_buf = kzalloc(pbl->pbl_buf_size_in_bytes,
|
pbl->pbl_buf = kvzalloc(pbl->pbl_buf_size_in_bytes, GFP_KERNEL);
|
||||||
GFP_KERNEL | __GFP_NOWARN);
|
if (!pbl->pbl_buf)
|
||||||
if (pbl->pbl_buf) {
|
return -ENOMEM;
|
||||||
|
|
||||||
|
if (is_vmalloc_addr(pbl->pbl_buf)) {
|
||||||
|
pbl->physically_continuous = 0;
|
||||||
|
err = umem_to_page_list(dev, umem, pbl->pbl_buf, hp_cnt,
|
||||||
|
hp_shift);
|
||||||
|
if (err)
|
||||||
|
goto err_free;
|
||||||
|
|
||||||
|
err = pbl_indirect_initialize(dev, pbl);
|
||||||
|
if (err)
|
||||||
|
goto err_free;
|
||||||
|
} else {
|
||||||
pbl->physically_continuous = 1;
|
pbl->physically_continuous = 1;
|
||||||
err = umem_to_page_list(dev, umem, pbl->pbl_buf, hp_cnt,
|
err = umem_to_page_list(dev, umem, pbl->pbl_buf, hp_cnt,
|
||||||
hp_shift);
|
hp_shift);
|
||||||
if (err)
|
if (err)
|
||||||
goto err_continuous;
|
goto err_free;
|
||||||
|
|
||||||
err = pbl_continuous_initialize(dev, pbl);
|
err = pbl_continuous_initialize(dev, pbl);
|
||||||
if (err)
|
if (err)
|
||||||
goto err_continuous;
|
goto err_free;
|
||||||
} else {
|
|
||||||
pbl->physically_continuous = 0;
|
|
||||||
pbl->pbl_buf = vzalloc(pbl->pbl_buf_size_in_bytes);
|
|
||||||
if (!pbl->pbl_buf)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
err = umem_to_page_list(dev, umem, pbl->pbl_buf, hp_cnt,
|
|
||||||
hp_shift);
|
|
||||||
if (err)
|
|
||||||
goto err_indirect;
|
|
||||||
err = pbl_indirect_initialize(dev, pbl);
|
|
||||||
if (err)
|
|
||||||
goto err_indirect;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ibdev_dbg(&dev->ibdev,
|
ibdev_dbg(&dev->ibdev,
|
||||||
|
@ -1317,24 +1317,20 @@ static int pbl_create(struct efa_dev *dev,
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err_continuous:
|
err_free:
|
||||||
kfree(pbl->pbl_buf);
|
kvfree(pbl->pbl_buf);
|
||||||
return err;
|
|
||||||
err_indirect:
|
|
||||||
vfree(pbl->pbl_buf);
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pbl_destroy(struct efa_dev *dev, struct pbl_context *pbl)
|
static void pbl_destroy(struct efa_dev *dev, struct pbl_context *pbl)
|
||||||
{
|
{
|
||||||
if (pbl->physically_continuous) {
|
if (pbl->physically_continuous)
|
||||||
dma_unmap_single(&dev->pdev->dev, pbl->phys.continuous.dma_addr,
|
dma_unmap_single(&dev->pdev->dev, pbl->phys.continuous.dma_addr,
|
||||||
pbl->pbl_buf_size_in_bytes, DMA_TO_DEVICE);
|
pbl->pbl_buf_size_in_bytes, DMA_TO_DEVICE);
|
||||||
kfree(pbl->pbl_buf);
|
else
|
||||||
} else {
|
|
||||||
pbl_indirect_terminate(dev, pbl);
|
pbl_indirect_terminate(dev, pbl);
|
||||||
vfree(pbl->pbl_buf);
|
|
||||||
}
|
kvfree(pbl->pbl_buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int efa_create_inline_pbl(struct efa_dev *dev, struct efa_mr *mr,
|
static int efa_create_inline_pbl(struct efa_dev *dev, struct efa_mr *mr,
|
||||||
|
|
Загрузка…
Ссылка в новой задаче