RDMA/bnxt_re: Avoid repeated requests to allocate WC pages

Applications can request multiple WC pages for the same ucontext.
As of now, only 1 WC page per ucontext is supported. Add a lock to
avoid concurrent access and a check to fail repeated requests.
Also, if the mmap entry insert fails for the WC, free the Doorbell
page index mapped for the WC page.

Fixes: eee6268421 ("RDMA/bnxt_re: Move the UAPI methods to a dedicated file")
Fixes: 360da60d6c ("RDMA/bnxt_re: Enable low latency push")
Link: https://patch.msgid.link/r/20260615224751.232802-12-selvin.xavier@broadcom.com
Reviewed-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
Signed-off-by: Selvin Xavier <selvin.xavier@broadcom.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
This commit is contained in:
Selvin Xavier 2026-06-15 15:47:47 -07:00 committed by Jason Gunthorpe
parent 87267803a8
commit 441baa7904
3 changed files with 29 additions and 6 deletions

View File

@ -4770,6 +4770,7 @@ int bnxt_re_alloc_ucontext(struct ib_ucontext *ctx, struct ib_udata *udata)
goto fail;
}
spin_lock_init(&uctx->sh_lock);
mutex_init(&uctx->wcdpi_lock);
resp.comp_mask = BNXT_RE_UCNTX_CMASK_HAVE_CCTX;
chip_met_rev_num = rdev->chip_ctx->chip_num;

View File

@ -143,6 +143,7 @@ struct bnxt_re_ucontext {
struct bnxt_re_dev *rdev;
struct bnxt_qplib_dpi dpi;
struct bnxt_qplib_dpi wcdpi;
struct mutex wcdpi_lock; /* serialises WC DPI alloc/free */
void *shpg;
spinlock_t sh_lock; /* protect shpg */
struct rdma_user_mmap_entry *shpage_mmap;

View File

@ -98,14 +98,23 @@ static int UVERBS_HANDLER(BNXT_RE_METHOD_ALLOC_PAGE)(struct uverbs_attr_bundle *
switch (alloc_type) {
case BNXT_RE_ALLOC_WC_PAGE:
if (cctx->modes.db_push) {
if (cctx->modes.db_push) {
mutex_lock(&uctx->wcdpi_lock);
/* already allocated — one WC page per context */
if (uctx->wcdpi.dbr) {
mutex_unlock(&uctx->wcdpi_lock);
return -EEXIST;
}
if (bnxt_qplib_alloc_dpi(&rdev->qplib_res, &uctx->wcdpi,
uctx, BNXT_QPLIB_DPI_TYPE_WC))
uctx, BNXT_QPLIB_DPI_TYPE_WC)) {
mutex_unlock(&uctx->wcdpi_lock);
return -ENOMEM;
}
length = PAGE_SIZE;
dpi = uctx->wcdpi.dpi;
addr = (u64)uctx->wcdpi.umdbr;
mmap_flag = BNXT_RE_MMAP_WC_DB;
mutex_unlock(&uctx->wcdpi_lock);
} else {
return -EINVAL;
}
@ -128,8 +137,15 @@ static int UVERBS_HANDLER(BNXT_RE_METHOD_ALLOC_PAGE)(struct uverbs_attr_bundle *
}
entry = bnxt_re_mmap_entry_insert(uctx, addr, mmap_flag, &mmap_offset);
if (!entry)
if (!entry) {
if (mmap_flag == BNXT_RE_MMAP_WC_DB) {
mutex_lock(&uctx->wcdpi_lock);
bnxt_qplib_dealloc_dpi(&rdev->qplib_res, &uctx->wcdpi);
uctx->wcdpi.dbr = NULL;
mutex_unlock(&uctx->wcdpi_lock);
}
return -ENOMEM;
}
uobj->object = entry;
uverbs_finalize_uobj_create(attrs, BNXT_RE_ALLOC_PAGE_HANDLE);
@ -160,11 +176,16 @@ static int alloc_page_obj_cleanup(struct ib_uobject *uobject,
switch (entry->mmap_flag) {
case BNXT_RE_MMAP_WC_DB:
if (uctx && uctx->wcdpi.dbr) {
if (uctx) {
struct bnxt_re_dev *rdev = uctx->rdev;
bnxt_qplib_dealloc_dpi(&rdev->qplib_res, &uctx->wcdpi);
uctx->wcdpi.dbr = NULL;
mutex_lock(&uctx->wcdpi_lock);
if (uctx->wcdpi.dbr) {
bnxt_qplib_dealloc_dpi(&rdev->qplib_res,
&uctx->wcdpi);
uctx->wcdpi.dbr = NULL;
}
mutex_unlock(&uctx->wcdpi_lock);
}
break;
case BNXT_RE_MMAP_DBR_BAR: