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/uverbs: Support external FD uobjects

Add support for uobjects that wrap externally allocated file
descriptors (FDs).

In this mode, the FD number still follows the standard uverbs allocation
flow, but the file pointer is allocated externally and has its own fops
and private data.

As a result, alloc_begin_fd_uobject() must handle cases where
fd_type->fops is NULL, and both alloc_commit_fd_uobject() and
alloc_abort_fd_uobject() must account for whether filp->private_data
exists, since it is populated outside the standard uverbs flow.

Signed-off-by: Yishai Hadas <yishaih@nvidia.com>
Signed-off-by: Edward Srouji <edwards@nvidia.com>
Link: https://patch.msgid.link/20260201-dmabuf-export-v3-1-da238b614fe3@nvidia.com
Signed-off-by: Leon Romanovsky <leon@kernel.org>

authored by

Yishai Hadas and committed by
Leon Romanovsky
9ad95a0f 06fddc7a

+21 -14
+21 -14
drivers/infiniband/core/rdma_core.c
··· 465 465 466 466 fd_type = 467 467 container_of(obj->type_attrs, struct uverbs_obj_fd_type, type); 468 - if (WARN_ON(fd_type->fops->release != &uverbs_uobject_fd_release && 468 + if (WARN_ON(fd_type->fops && fd_type->fops->release != &uverbs_uobject_fd_release && 469 469 fd_type->fops->release != &uverbs_async_event_release)) { 470 470 ret = ERR_PTR(-EINVAL); 471 471 goto err_fd; ··· 477 477 goto err_fd; 478 478 } 479 479 480 - /* Note that uverbs_uobject_fd_release() is called during abort */ 481 - filp = anon_inode_getfile(fd_type->name, fd_type->fops, NULL, 482 - fd_type->flags); 483 - if (IS_ERR(filp)) { 484 - ret = ERR_CAST(filp); 485 - goto err_getfile; 480 + if (fd_type->fops) { 481 + /* Note that uverbs_uobject_fd_release() is called during abort */ 482 + filp = anon_inode_getfile(fd_type->name, fd_type->fops, NULL, 483 + fd_type->flags); 484 + if (IS_ERR(filp)) { 485 + ret = ERR_CAST(filp); 486 + goto err_getfile; 487 + } 488 + uobj->object = filp; 486 489 } 487 - uobj->object = filp; 488 490 489 491 uobj->id = new_fd; 490 492 return uobj; ··· 563 561 { 564 562 struct file *filp = uobj->object; 565 563 566 - fput(filp); 564 + if (filp) 565 + fput(filp); 566 + 567 567 put_unused_fd(uobj->id); 568 568 } 569 569 ··· 632 628 /* This shouldn't be used anymore. Use the file object instead */ 633 629 uobj->id = 0; 634 630 635 - /* 636 - * NOTE: Once we install the file we loose ownership of our kref on 637 - * uobj. It will be put by uverbs_uobject_fd_release() 638 - */ 639 - filp->private_data = uobj; 631 + if (!filp->private_data) { 632 + /* 633 + * NOTE: Once we install the file we loose ownership of our kref on 634 + * uobj. It will be put by uverbs_uobject_fd_release() 635 + */ 636 + filp->private_data = uobj; 637 + } 638 + 640 639 fd_install(fd, filp); 641 640 } 642 641