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

RDMA/uverbs: Move IB_EVENT_DEVICE_FATAL to destroy_uobj

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>

+10 -7
+3
drivers/infiniband/core/uverbs.h
··· 228 228 struct ib_ucq_object *uobj); 229 229 void ib_uverbs_release_uevent(struct ib_uevent_object *uobj); 230 230 void ib_uverbs_release_file(struct kref *ref); 231 + void ib_uverbs_async_handler(struct ib_uverbs_async_event_file *async_file, 232 + __u64 element, __u64 event, 233 + struct list_head *obj_list, u32 *counter); 231 234 232 235 void ib_uverbs_comp_handler(struct ib_cq *cq, void *cq_context); 233 236 void ib_uverbs_cq_event_handler(struct ib_event *event, void *context_ptr);
+3 -7
drivers/infiniband/core/uverbs_main.c
··· 386 386 kill_fasync(&ev_queue->async_queue, SIGIO, POLL_IN); 387 387 } 388 388 389 - static void 390 - ib_uverbs_async_handler(struct ib_uverbs_async_event_file *async_file, 391 - __u64 element, __u64 event, struct list_head *obj_list, 392 - u32 *counter) 389 + void ib_uverbs_async_handler(struct ib_uverbs_async_event_file *async_file, 390 + __u64 element, __u64 event, 391 + struct list_head *obj_list, u32 *counter) 393 392 { 394 393 struct ib_uverbs_event *entry; 395 394 unsigned long flags; ··· 1185 1186 * mmput). 1186 1187 */ 1187 1188 mutex_unlock(&uverbs_dev->lists_mutex); 1188 - 1189 - ib_uverbs_async_handler(READ_ONCE(file->async_file), 0, 1190 - IB_EVENT_DEVICE_FATAL, NULL, NULL); 1191 1189 1192 1190 uverbs_destroy_ufile_hw(file, RDMA_REMOVE_DRIVER_REMOVE); 1193 1191 kref_put(&file->ref, ib_uverbs_release_file);
+4
drivers/infiniband/core/uverbs_std_types_async_fd.c
··· 26 26 container_of(uobj, struct ib_uverbs_async_event_file, uobj); 27 27 28 28 ib_unregister_event_handler(&event_file->event_handler); 29 + 30 + if (why == RDMA_REMOVE_DRIVER_REMOVE) 31 + ib_uverbs_async_handler(event_file, 0, IB_EVENT_DEVICE_FATAL, 32 + NULL, NULL); 29 33 return 0; 30 34 } 31 35