// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB /* * Copyright (c) 2019, Mellanox Technologies inc. All rights reserved. */ #include #include #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); ib_uverbs_init_async_event_file( container_of(uobj, struct ib_uverbs_async_event_file, uobj)); return 0; } static void uverbs_async_event_destroy_uobj(struct ib_uobject *uobj, enum rdma_remove_reason why) { struct ib_uverbs_async_event_file *event_file = container_of(uobj, struct ib_uverbs_async_event_file, uobj); ib_unregister_event_handler(&event_file->event_handler); if (why == RDMA_REMOVE_DRIVER_REMOVE) ib_uverbs_async_handler(event_file, 0, IB_EVENT_DEVICE_FATAL, NULL, NULL); } int uverbs_async_event_release(struct inode *inode, struct file *filp) { struct ib_uverbs_async_event_file *event_file; struct ib_uobject *uobj = filp->private_data; int ret; if (!uobj) return uverbs_uobject_fd_release(inode, filp); event_file = container_of(uobj, struct ib_uverbs_async_event_file, uobj); /* * The async event FD has to deliver IB_EVENT_DEVICE_FATAL even after * disassociation, so cleaning the event list must only happen after * release. The user knows it has reached the end of the event stream * when it sees IB_EVENT_DEVICE_FATAL. */ uverbs_uobject_get(uobj); ret = uverbs_uobject_fd_release(inode, filp); ib_uverbs_free_event_queue(&event_file->ev_queue); uverbs_uobject_put(uobj); return ret; } 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), &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), {} };