Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

RDMA/bnxt_re: Support doorbell extensions

Some applications may need multiple doorbells to support parallel
processing of threads that each operate on a group of resources.

The following uapi methods have been implemented in this patch.

- BNXT_RE_METHOD_DBR_ALLOC:
This will allow the appliation to create extra doorbell regions
and use the associated doorbell page index in CREATE_QP and
use the associated DB address while ringing the doorbell.

- BNXT_RE_METHOD_DBR_FREE:
Free the allocated doorbell region.

- BNXT_RE_METHOD_GET_DEFAULT_DBR:
Return the default doorbell page index and doorbell page address
associated with the ucontext.

Link: https://patch.msgid.link/r/20260302110036.36387-4-sriharsha.basavapatna@broadcom.com
Co-developed-by: Sriharsha Basavapatna <sriharsha.basavapatna@broadcom.com>
Signed-off-by: Sriharsha Basavapatna <sriharsha.basavapatna@broadcom.com>
Signed-off-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
Reviewed-by: Selvin Xavier <selvin.xavier@broadcom.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>

authored by

Kalesh AP and committed by
Jason Gunthorpe
1234a9d8 13f9a813

+213
+7
drivers/infiniband/hw/bnxt_re/ib_verbs.h
··· 164 164 u8 mmap_flag; 165 165 }; 166 166 167 + struct bnxt_re_dbr_obj { 168 + struct bnxt_re_dev *rdev; 169 + struct bnxt_qplib_dpi dpi; 170 + struct bnxt_re_user_mmap_entry *entry; 171 + atomic_t usecnt; /* QPs using this dbr */ 172 + }; 173 + 167 174 struct bnxt_re_flow { 168 175 struct ib_flow ib_flow; 169 176 struct bnxt_re_dev *rdev;
+43
drivers/infiniband/hw/bnxt_re/qplib_res.c
··· 683 683 } 684 684 685 685 /* DPIs */ 686 + int bnxt_qplib_alloc_uc_dpi(struct bnxt_qplib_res *res, struct bnxt_qplib_dpi *dpi) 687 + { 688 + struct bnxt_qplib_dpi_tbl *dpit = &res->dpi_tbl; 689 + struct bnxt_qplib_reg_desc *reg; 690 + u32 bit_num; 691 + int rc = 0; 692 + 693 + reg = &dpit->wcreg; 694 + mutex_lock(&res->dpi_tbl_lock); 695 + bit_num = find_first_bit(dpit->tbl, dpit->max); 696 + if (bit_num >= dpit->max) { 697 + rc = -ENOMEM; 698 + goto unlock; 699 + } 700 + /* Found unused DPI */ 701 + clear_bit(bit_num, dpit->tbl); 702 + dpi->bit = bit_num; 703 + dpi->dpi = bit_num + (reg->offset - dpit->ucreg.offset) / PAGE_SIZE; 704 + dpi->umdbr = reg->bar_base + reg->offset + bit_num * PAGE_SIZE; 705 + unlock: 706 + mutex_unlock(&res->dpi_tbl_lock); 707 + return rc; 708 + } 709 + 710 + int bnxt_qplib_free_uc_dpi(struct bnxt_qplib_res *res, struct bnxt_qplib_dpi *dpi) 711 + { 712 + struct bnxt_qplib_dpi_tbl *dpit = &res->dpi_tbl; 713 + int rc = 0; 714 + 715 + mutex_lock(&res->dpi_tbl_lock); 716 + if (dpi->bit >= dpit->max) { 717 + rc = -EINVAL; 718 + goto unlock; 719 + } 720 + 721 + if (test_and_set_bit(dpi->bit, dpit->tbl)) 722 + rc = -EINVAL; 723 + memset(dpi, 0, sizeof(*dpi)); 724 + unlock: 725 + mutex_unlock(&res->dpi_tbl_lock); 726 + return rc; 727 + } 728 + 686 729 int bnxt_qplib_alloc_dpi(struct bnxt_qplib_res *res, 687 730 struct bnxt_qplib_dpi *dpi, 688 731 void *app, u8 type)
+4
drivers/infiniband/hw/bnxt_re/qplib_res.h
··· 436 436 void *app, u8 type); 437 437 int bnxt_qplib_dealloc_dpi(struct bnxt_qplib_res *res, 438 438 struct bnxt_qplib_dpi *dpi); 439 + int bnxt_qplib_alloc_uc_dpi(struct bnxt_qplib_res *res, 440 + struct bnxt_qplib_dpi *dpi); 441 + int bnxt_qplib_free_uc_dpi(struct bnxt_qplib_res *res, 442 + struct bnxt_qplib_dpi *dpi); 439 443 void bnxt_qplib_cleanup_res(struct bnxt_qplib_res *res); 440 444 int bnxt_qplib_init_res(struct bnxt_qplib_res *res); 441 445 void bnxt_qplib_free_res(struct bnxt_qplib_res *res);
+130
drivers/infiniband/hw/bnxt_re/uapi.c
··· 331 331 &UVERBS_METHOD(BNXT_RE_METHOD_GET_TOGGLE_MEM), 332 332 &UVERBS_METHOD(BNXT_RE_METHOD_RELEASE_TOGGLE_MEM)); 333 333 334 + static int UVERBS_HANDLER(BNXT_RE_METHOD_DBR_ALLOC)(struct uverbs_attr_bundle *attrs) 335 + { 336 + struct bnxt_re_db_region dbr = {}; 337 + struct bnxt_re_ucontext *uctx; 338 + struct bnxt_re_dbr_obj *obj; 339 + struct ib_ucontext *ib_uctx; 340 + struct bnxt_qplib_dpi *dpi; 341 + struct bnxt_re_dev *rdev; 342 + struct ib_uobject *uobj; 343 + u64 mmap_offset; 344 + int ret; 345 + 346 + ib_uctx = ib_uverbs_get_ucontext(attrs); 347 + if (IS_ERR(ib_uctx)) 348 + return PTR_ERR(ib_uctx); 349 + 350 + uctx = container_of(ib_uctx, struct bnxt_re_ucontext, ib_uctx); 351 + rdev = uctx->rdev; 352 + uobj = uverbs_attr_get_uobject(attrs, BNXT_RE_ALLOC_DBR_HANDLE); 353 + 354 + obj = kzalloc_obj(*obj); 355 + if (!obj) 356 + return -ENOMEM; 357 + 358 + dpi = &obj->dpi; 359 + ret = bnxt_qplib_alloc_uc_dpi(&rdev->qplib_res, dpi); 360 + if (ret) 361 + goto free_mem; 362 + 363 + obj->entry = bnxt_re_mmap_entry_insert(uctx, dpi->umdbr, 364 + BNXT_RE_MMAP_UC_DB, 365 + &mmap_offset); 366 + if (!obj->entry) { 367 + ret = -ENOMEM; 368 + goto free_dpi; 369 + } 370 + 371 + obj->rdev = rdev; 372 + uobj->object = obj; 373 + uverbs_finalize_uobj_create(attrs, BNXT_RE_ALLOC_DBR_HANDLE); 374 + 375 + dbr.umdbr = dpi->umdbr; 376 + dbr.dpi = dpi->dpi; 377 + ret = uverbs_copy_to_struct_or_zero(attrs, BNXT_RE_ALLOC_DBR_ATTR, 378 + &dbr, sizeof(dbr)); 379 + if (ret) 380 + return ret; 381 + 382 + ret = uverbs_copy_to(attrs, BNXT_RE_ALLOC_DBR_OFFSET, 383 + &mmap_offset, sizeof(mmap_offset)); 384 + if (ret) 385 + return ret; 386 + return 0; 387 + free_dpi: 388 + bnxt_qplib_free_uc_dpi(&rdev->qplib_res, dpi); 389 + free_mem: 390 + kfree(obj); 391 + return ret; 392 + } 393 + 394 + static int bnxt_re_dbr_cleanup(struct ib_uobject *uobject, 395 + enum rdma_remove_reason why, 396 + struct uverbs_attr_bundle *attrs) 397 + { 398 + struct bnxt_re_dbr_obj *obj = uobject->object; 399 + struct bnxt_re_dev *rdev = obj->rdev; 400 + 401 + rdma_user_mmap_entry_remove(&obj->entry->rdma_entry); 402 + bnxt_qplib_free_uc_dpi(&rdev->qplib_res, &obj->dpi); 403 + return 0; 404 + } 405 + 406 + static int UVERBS_HANDLER(BNXT_RE_METHOD_GET_DEFAULT_DBR)(struct uverbs_attr_bundle *attrs) 407 + { 408 + struct bnxt_re_db_region dpi = {}; 409 + struct bnxt_re_ucontext *uctx; 410 + struct ib_ucontext *ib_uctx; 411 + int ret; 412 + 413 + ib_uctx = ib_uverbs_get_ucontext(attrs); 414 + if (IS_ERR(ib_uctx)) 415 + return PTR_ERR(ib_uctx); 416 + 417 + uctx = container_of(ib_uctx, struct bnxt_re_ucontext, ib_uctx); 418 + dpi.umdbr = uctx->dpi.umdbr; 419 + dpi.dpi = uctx->dpi.dpi; 420 + 421 + ret = uverbs_copy_to_struct_or_zero(attrs, BNXT_RE_DEFAULT_DBR_ATTR, 422 + &dpi, sizeof(dpi)); 423 + if (ret) 424 + return ret; 425 + 426 + return 0; 427 + } 428 + 429 + DECLARE_UVERBS_NAMED_METHOD(BNXT_RE_METHOD_DBR_ALLOC, 430 + UVERBS_ATTR_IDR(BNXT_RE_ALLOC_DBR_HANDLE, 431 + BNXT_RE_OBJECT_DBR, 432 + UVERBS_ACCESS_NEW, 433 + UA_MANDATORY), 434 + UVERBS_ATTR_PTR_OUT(BNXT_RE_ALLOC_DBR_ATTR, 435 + UVERBS_ATTR_STRUCT(struct bnxt_re_db_region, 436 + umdbr), 437 + UA_MANDATORY), 438 + UVERBS_ATTR_PTR_OUT(BNXT_RE_ALLOC_DBR_OFFSET, 439 + UVERBS_ATTR_TYPE(u64), 440 + UA_MANDATORY)); 441 + 442 + DECLARE_UVERBS_NAMED_METHOD_DESTROY(BNXT_RE_METHOD_DBR_FREE, 443 + UVERBS_ATTR_IDR(BNXT_RE_FREE_DBR_HANDLE, 444 + BNXT_RE_OBJECT_DBR, 445 + UVERBS_ACCESS_DESTROY, 446 + UA_MANDATORY)); 447 + 448 + DECLARE_UVERBS_NAMED_OBJECT(BNXT_RE_OBJECT_DBR, 449 + UVERBS_TYPE_ALLOC_IDR(bnxt_re_dbr_cleanup), 450 + &UVERBS_METHOD(BNXT_RE_METHOD_DBR_ALLOC), 451 + &UVERBS_METHOD(BNXT_RE_METHOD_DBR_FREE)); 452 + 453 + DECLARE_UVERBS_NAMED_METHOD(BNXT_RE_METHOD_GET_DEFAULT_DBR, 454 + UVERBS_ATTR_PTR_OUT(BNXT_RE_DEFAULT_DBR_ATTR, 455 + UVERBS_ATTR_STRUCT(struct bnxt_re_db_region, 456 + umdbr), 457 + UA_MANDATORY)); 458 + 459 + DECLARE_UVERBS_GLOBAL_METHODS(BNXT_RE_OBJECT_DEFAULT_DBR, 460 + &UVERBS_METHOD(BNXT_RE_METHOD_GET_DEFAULT_DBR)); 461 + 334 462 const struct uapi_definition bnxt_re_uapi_defs[] = { 335 463 UAPI_DEF_CHAIN_OBJ_TREE_NAMED(BNXT_RE_OBJECT_ALLOC_PAGE), 336 464 UAPI_DEF_CHAIN_OBJ_TREE_NAMED(BNXT_RE_OBJECT_NOTIFY_DRV), 337 465 UAPI_DEF_CHAIN_OBJ_TREE_NAMED(BNXT_RE_OBJECT_GET_TOGGLE_MEM), 466 + UAPI_DEF_CHAIN_OBJ_TREE_NAMED(BNXT_RE_OBJECT_DBR), 467 + UAPI_DEF_CHAIN_OBJ_TREE_NAMED(BNXT_RE_OBJECT_DEFAULT_DBR), 338 468 {} 339 469 };
+29
include/uapi/rdma/bnxt_re-abi.h
··· 163 163 BNXT_RE_OBJECT_ALLOC_PAGE = (1U << UVERBS_ID_NS_SHIFT), 164 164 BNXT_RE_OBJECT_NOTIFY_DRV, 165 165 BNXT_RE_OBJECT_GET_TOGGLE_MEM, 166 + BNXT_RE_OBJECT_DBR, 167 + BNXT_RE_OBJECT_DEFAULT_DBR, 166 168 }; 167 169 168 170 enum bnxt_re_alloc_page_type { ··· 233 231 struct bnxt_re_query_device_ex_resp { 234 232 struct bnxt_re_packet_pacing_caps packet_pacing_caps; 235 233 }; 234 + 235 + struct bnxt_re_db_region { 236 + __u32 dpi; 237 + __u32 reserved; 238 + __aligned_u64 umdbr; 239 + }; 240 + 241 + enum bnxt_re_obj_dbr_alloc_attrs { 242 + BNXT_RE_ALLOC_DBR_HANDLE = (1U << UVERBS_ID_NS_SHIFT), 243 + BNXT_RE_ALLOC_DBR_ATTR, 244 + BNXT_RE_ALLOC_DBR_OFFSET, 245 + }; 246 + 247 + enum bnxt_re_obj_dbr_free_attrs { 248 + BNXT_RE_FREE_DBR_HANDLE = (1U << UVERBS_ID_NS_SHIFT), 249 + }; 250 + 251 + enum bnxt_re_obj_default_dbr_attrs { 252 + BNXT_RE_DEFAULT_DBR_ATTR = (1U << UVERBS_ID_NS_SHIFT), 253 + }; 254 + 255 + enum bnxt_re_obj_dpi_methods { 256 + BNXT_RE_METHOD_DBR_ALLOC = (1U << UVERBS_ID_NS_SHIFT), 257 + BNXT_RE_METHOD_DBR_FREE, 258 + BNXT_RE_METHOD_GET_DEFAULT_DBR, 259 + }; 260 + 236 261 #endif /* __BNXT_RE_UVERBS_ABI_H__*/