diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c index 1f279b0a8e49..fb9e75257607 100644 --- a/drivers/infiniband/core/uverbs_main.c +++ b/drivers/infiniband/core/uverbs_main.c @@ -475,7 +475,9 @@ void ib_uverbs_init_async_event_file( ib_uverbs_init_event_queue(&async_file->ev_queue); - if (!WARN_ON(uverbs_file->async_file)) { + /* The first async_event_file becomes the default one for the file. */ + lockdep_assert_held(&uverbs_file->ucontext_lock); + if (!uverbs_file->async_file) { /* Pairs with the put in ib_uverbs_release_file */ uverbs_uobject_get(&async_file->uobj); smp_store_release(&uverbs_file->async_file, async_file); diff --git a/drivers/infiniband/core/uverbs_std_types_async_fd.c b/drivers/infiniband/core/uverbs_std_types_async_fd.c index 31ff96898b06..484dba136950 100644 --- a/drivers/infiniband/core/uverbs_std_types_async_fd.c +++ b/drivers/infiniband/core/uverbs_std_types_async_fd.c @@ -8,6 +8,19 @@ #include "rdma_core.h" #include "uverbs.h" +static int UVERBS_HANDLER(UVERBS_METHOD_ASYNC_EVENT_ALLOC)( + struct uverbs_attr_bundle *attrs) +{ + struct ib_uobject *uobj = + uverbs_attr_get_uobject(attrs, UVERBS_METHOD_ASYNC_EVENT_ALLOC); + + mutex_lock(&attrs->ufile->ucontext_lock); + ib_uverbs_init_async_event_file( + container_of(uobj, struct ib_uverbs_async_event_file, uobj)); + mutex_unlock(&attrs->ufile->ucontext_lock); + return 0; +} + static int uverbs_async_event_destroy_uobj(struct ib_uobject *uobj, enum rdma_remove_reason why) { @@ -19,13 +32,21 @@ static int uverbs_async_event_destroy_uobj(struct ib_uobject *uobj, return 0; } +DECLARE_UVERBS_NAMED_METHOD( + UVERBS_METHOD_ASYNC_EVENT_ALLOC, + UVERBS_ATTR_FD(UVERBS_ATTR_ASYNC_EVENT_ALLOC_FD_HANDLE, + UVERBS_OBJECT_ASYNC_EVENT, + UVERBS_ACCESS_NEW, + UA_MANDATORY)); + DECLARE_UVERBS_NAMED_OBJECT( UVERBS_OBJECT_ASYNC_EVENT, UVERBS_TYPE_ALLOC_FD(sizeof(struct ib_uverbs_async_event_file), uverbs_async_event_destroy_uobj, &uverbs_async_event_fops, "[infinibandevent]", - O_RDONLY)); + O_RDONLY), + &UVERBS_METHOD(UVERBS_METHOD_ASYNC_EVENT_ALLOC)); const struct uapi_definition uverbs_def_obj_async_fd[] = { UAPI_DEF_CHAIN_OBJ_TREE_NAMED(UVERBS_OBJECT_ASYNC_EVENT), diff --git a/include/uapi/rdma/ib_user_ioctl_cmds.h b/include/uapi/rdma/ib_user_ioctl_cmds.h index 9cfadb5120d9..498955c576f3 100644 --- a/include/uapi/rdma/ib_user_ioctl_cmds.h +++ b/include/uapi/rdma/ib_user_ioctl_cmds.h @@ -242,4 +242,12 @@ enum uverbs_attrs_flow_destroy_ids { UVERBS_ATTR_DESTROY_FLOW_HANDLE, }; +enum uverbs_method_async_event { + UVERBS_METHOD_ASYNC_EVENT_ALLOC, +}; + +enum uverbs_attrs_async_event_create { + UVERBS_ATTR_ASYNC_EVENT_ALLOC_FD_HANDLE, +}; + #endif