On 10/14/21 1:32 PM, Jason Gunthorpe wrote: > On Thu, Oct 14, 2021 at 11:14:57AM -0500, Bob Pearson wrote: > >> But ib_uverbs_destroy_ah does *not* call rdma_uverbs_destroy_ah() it just >> deletes the object. > > ib_uverbs_destroy_ah > uobj_perform_destroy > __uobj_perform_destroy > __uobj_get_destroy > uobj_destroy > uverbs_destroy_uobject: > > } else if (uobj->object) { > ret = uobj->uapi_object->type_class->destroy_hw(uobj, reason, > attrs); > > Which calls > > destroy_hw_idr_uobject > int ret = idr_type->destroy_object(uobj, why, attrs); > > Which links to this: > > DECLARE_UVERBS_NAMED_OBJECT(UVERBS_OBJECT_AH, > UVERBS_TYPE_ALLOC_IDR(uverbs_free_ah), > &UVERBS_METHOD(UVERBS_METHOD_AH_DESTROY)); > > And thus calls > > static int uverbs_free_ah(struct ib_uobject *uobject, > enum rdma_remove_reason why, > struct uverbs_attr_bundle *attrs) > { > return rdma_destroy_ah_user((struct ib_ah *)uobject->object, > RDMA_DESTROY_AH_SLEEPABLE, > &attrs->driver_udata); > } > > So, look along that path and find out where it goes wrong? > > Jason > Thanks I had more or less figured that out. I looked at other objects and saw a similar pattern. I think I've traced the problem back to myself. Bob