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

IB/core: Explicitly destroy an object while keeping uobject

When some objects are destroyed, we need to extract their status at
destruction. After object's destruction, this status
(e.g. events_reported) relies in the uobject. In order to have the
latest and correct status, the underlying object should be destroyed,
but we should keep the uobject alive and read this information off the
uobject. We introduce a rdma_explicit_destroy function. This function
destroys the class type object (for example, the IDR class type which
destroys the underlying object as well) and then convert the uobject
to be of a null class type. This uobject will then be destroyed as any
other uobject once uverbs_finalize_object[s] is called.

Signed-off-by: Matan Barak <matanb@mellanox.com>
Reviewed-by: Yishai Hadas <yishaih@mellanox.com>
Signed-off-by: Doug Ledford <dledford@redhat.com>

authored by

Matan Barak and committed by
Doug Ledford
4da70da2 35410306

+36
+35
drivers/infiniband/core/rdma_core.c
··· 451 451 return ret; 452 452 } 453 453 454 + static int null_obj_type_class_remove_commit(struct ib_uobject *uobj, 455 + enum rdma_remove_reason why) 456 + { 457 + return 0; 458 + } 459 + 460 + static const struct uverbs_obj_type null_obj_type = { 461 + .type_class = &((const struct uverbs_obj_type_class){ 462 + .remove_commit = null_obj_type_class_remove_commit, 463 + /* be cautious */ 464 + .needs_kfree_rcu = true}), 465 + }; 466 + 467 + int rdma_explicit_destroy(struct ib_uobject *uobject) 468 + { 469 + int ret; 470 + struct ib_ucontext *ucontext = uobject->context; 471 + 472 + /* Cleanup is running. Calling this should have been impossible */ 473 + if (!down_read_trylock(&ucontext->cleanup_rwsem)) { 474 + WARN(true, "ib_uverbs: Cleanup is running while removing an uobject\n"); 475 + return 0; 476 + } 477 + lockdep_check(uobject, true); 478 + ret = uobject->type->type_class->remove_commit(uobject, 479 + RDMA_REMOVE_DESTROY); 480 + if (ret) 481 + return ret; 482 + 483 + uobject->type = &null_obj_type; 484 + 485 + up_read(&ucontext->cleanup_rwsem); 486 + return 0; 487 + } 488 + 454 489 static void alloc_commit_idr_uobject(struct ib_uobject *uobj) 455 490 { 456 491 uverbs_uobject_add(uobj);
+1
include/rdma/uverbs_types.h
··· 129 129 void rdma_alloc_abort_uobject(struct ib_uobject *uobj); 130 130 int __must_check rdma_remove_commit_uobject(struct ib_uobject *uobj); 131 131 int rdma_alloc_commit_uobject(struct ib_uobject *uobj); 132 + int rdma_explicit_destroy(struct ib_uobject *uobject); 132 133 133 134 struct uverbs_obj_fd_type { 134 135 /*