| From ccfdbaa5cf4601b9b71601893029dcc9245c002b Mon Sep 17 00:00:00 2001 |
| From: Jason Gunthorpe <jgg@ziepe.ca> |
| Date: Thu, 7 May 2020 09:33:48 +0300 |
| Subject: RDMA/uverbs: Move IB_EVENT_DEVICE_FATAL to destroy_uobj |
| |
| From: Jason Gunthorpe <jgg@mellanox.com> |
| |
| commit ccfdbaa5cf4601b9b71601893029dcc9245c002b upstream. |
| |
| When multiple async FDs were allowed to exist the idea was for all |
| broadcast events to be delivered to all async FDs, however |
| IB_EVENT_DEVICE_FATAL was missed. |
| |
| Instead of having ib_uverbs_free_hw_resources() special case the global |
| async_fd, have it cause the event during the uobject destruction. Every |
| async fd is now a uobject so simply generate the IB_EVENT_DEVICE_FATAL |
| while destroying the async fd uobject. This ensures every async FD gets a |
| copy of the event. |
| |
| Fixes: d680e88e2013 ("RDMA/core: Add UVERBS_METHOD_ASYNC_EVENT_ALLOC") |
| Link: https://lore.kernel.org/r/20200507063348.98713-3-leon@kernel.org |
| Signed-off-by: Yishai Hadas <yishaih@mellanox.com> |
| Signed-off-by: Leon Romanovsky <leonro@mellanox.com> |
| Signed-off-by: Jason Gunthorpe <jgg@mellanox.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/infiniband/core/uverbs.h | 3 +++ |
| drivers/infiniband/core/uverbs_main.c | 10 +++------- |
| drivers/infiniband/core/uverbs_std_types_async_fd.c | 4 ++++ |
| 3 files changed, 10 insertions(+), 7 deletions(-) |
| |
| --- a/drivers/infiniband/core/uverbs.h |
| +++ b/drivers/infiniband/core/uverbs.h |
| @@ -228,6 +228,9 @@ void ib_uverbs_release_ucq(struct ib_uve |
| struct ib_ucq_object *uobj); |
| void ib_uverbs_release_uevent(struct ib_uevent_object *uobj); |
| void ib_uverbs_release_file(struct kref *ref); |
| +void ib_uverbs_async_handler(struct ib_uverbs_async_event_file *async_file, |
| + __u64 element, __u64 event, |
| + struct list_head *obj_list, u32 *counter); |
| |
| void ib_uverbs_comp_handler(struct ib_cq *cq, void *cq_context); |
| void ib_uverbs_cq_event_handler(struct ib_event *event, void *context_ptr); |
| --- a/drivers/infiniband/core/uverbs_main.c |
| +++ b/drivers/infiniband/core/uverbs_main.c |
| @@ -386,10 +386,9 @@ void ib_uverbs_comp_handler(struct ib_cq |
| kill_fasync(&ev_queue->async_queue, SIGIO, POLL_IN); |
| } |
| |
| -static void |
| -ib_uverbs_async_handler(struct ib_uverbs_async_event_file *async_file, |
| - __u64 element, __u64 event, struct list_head *obj_list, |
| - u32 *counter) |
| +void ib_uverbs_async_handler(struct ib_uverbs_async_event_file *async_file, |
| + __u64 element, __u64 event, |
| + struct list_head *obj_list, u32 *counter) |
| { |
| struct ib_uverbs_event *entry; |
| unsigned long flags; |
| @@ -1187,9 +1186,6 @@ static void ib_uverbs_free_hw_resources( |
| */ |
| mutex_unlock(&uverbs_dev->lists_mutex); |
| |
| - ib_uverbs_async_handler(READ_ONCE(file->async_file), 0, |
| - IB_EVENT_DEVICE_FATAL, NULL, NULL); |
| - |
| uverbs_destroy_ufile_hw(file, RDMA_REMOVE_DRIVER_REMOVE); |
| kref_put(&file->ref, ib_uverbs_release_file); |
| |
| --- a/drivers/infiniband/core/uverbs_std_types_async_fd.c |
| +++ b/drivers/infiniband/core/uverbs_std_types_async_fd.c |
| @@ -26,6 +26,10 @@ static int uverbs_async_event_destroy_uo |
| 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); |
| return 0; |
| } |
| |