Commit 255efcae authored by Gal Pressman's avatar Gal Pressman Committed by Jason Gunthorpe

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: default avatarJason Gunthorpe <jgg@ziepe.ca>
Reviewed-by: default avatarFiras JahJah <firasj@amazon.com>
Reviewed-by: default avatarYossi Leybovich <sleybo@amazon.com>
Signed-off-by: default avatarGal Pressman <galpress@amazon.com>
Signed-off-by: default avatarJason Gunthorpe <jgg@mellanox.com>
parent 5f5e4eb4
...@@ -1285,30 +1285,30 @@ static int pbl_create(struct efa_dev *dev, ...@@ -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;
pbl->physically_continuous = 1;
if (is_vmalloc_addr(pbl->pbl_buf)) {
pbl->physically_continuous = 0;
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_indirect_initialize(dev, pbl);
if (err) if (err)
goto err_continuous; goto err_free;
} else { } else {
pbl->physically_continuous = 0; pbl->physically_continuous = 1;
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, err = umem_to_page_list(dev, umem, pbl->pbl_buf, hp_cnt,
hp_shift); hp_shift);
if (err) if (err)
goto err_indirect; goto err_free;
err = pbl_indirect_initialize(dev, pbl);
err = pbl_continuous_initialize(dev, pbl);
if (err) if (err)
goto err_indirect; goto err_free;
} }
ibdev_dbg(&dev->ibdev, ibdev_dbg(&dev->ibdev,
...@@ -1317,24 +1317,20 @@ static int pbl_create(struct efa_dev *dev, ...@@ -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,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment