Lines Matching refs:uobj
61 int uverbs_try_lock_object(struct ib_uobject *uobj, in uverbs_try_lock_object() argument
77 return atomic_fetch_add_unless(&uobj->usecnt, 1, -1) == -1 ? in uverbs_try_lock_object()
81 return atomic_cmpxchg(&uobj->usecnt, 0, -1) == 0 ? 0 : -EBUSY; in uverbs_try_lock_object()
89 static void assert_uverbs_usecnt(struct ib_uobject *uobj, in assert_uverbs_usecnt() argument
95 WARN_ON(atomic_read(&uobj->usecnt) <= 0); in assert_uverbs_usecnt()
98 WARN_ON(atomic_read(&uobj->usecnt) != -1); in assert_uverbs_usecnt()
123 static int uverbs_destroy_uobject(struct ib_uobject *uobj, in uverbs_destroy_uobject() argument
132 assert_uverbs_usecnt(uobj, UVERBS_LOOKUP_WRITE); in uverbs_destroy_uobject()
135 WARN_ON(!list_empty(&uobj->list)); in uverbs_destroy_uobject()
136 WARN_ON(!uobj->context); in uverbs_destroy_uobject()
137 uobj->uapi_object->type_class->alloc_abort(uobj); in uverbs_destroy_uobject()
138 } else if (uobj->object) { in uverbs_destroy_uobject()
139 ret = uobj->uapi_object->type_class->destroy_hw(uobj, reason, in uverbs_destroy_uobject()
145 uobj->object = NULL; in uverbs_destroy_uobject()
148 uobj->context = NULL; in uverbs_destroy_uobject()
156 atomic_set(&uobj->usecnt, 0); in uverbs_destroy_uobject()
158 uobj->uapi_object->type_class->remove_handle(uobj); in uverbs_destroy_uobject()
160 if (!list_empty(&uobj->list)) { in uverbs_destroy_uobject()
162 list_del_init(&uobj->list); in uverbs_destroy_uobject()
169 uverbs_uobject_put(uobj); in uverbs_destroy_uobject()
177 uverbs_uobject_put(uobj); in uverbs_destroy_uobject()
189 int uobj_destroy(struct ib_uobject *uobj, struct uverbs_attr_bundle *attrs) in uobj_destroy() argument
203 ret = uverbs_try_lock_object(uobj, UVERBS_LOOKUP_WRITE); in uobj_destroy()
207 ret = uverbs_destroy_uobject(uobj, RDMA_REMOVE_DESTROY, attrs); in uobj_destroy()
209 atomic_set(&uobj->usecnt, 0); in uobj_destroy()
226 struct ib_uobject *uobj; in __uobj_get_destroy() local
229 uobj = rdma_lookup_get_uobject(obj, attrs->ufile, id, in __uobj_get_destroy()
231 if (IS_ERR(uobj)) in __uobj_get_destroy()
232 return uobj; in __uobj_get_destroy()
234 ret = uobj_destroy(uobj, attrs); in __uobj_get_destroy()
236 rdma_lookup_put_uobject(uobj, UVERBS_LOOKUP_DESTROY); in __uobj_get_destroy()
240 return uobj; in __uobj_get_destroy()
250 struct ib_uobject *uobj; in __uobj_perform_destroy() local
252 uobj = __uobj_get_destroy(obj, id, attrs); in __uobj_perform_destroy()
253 if (IS_ERR(uobj)) in __uobj_perform_destroy()
254 return PTR_ERR(uobj); in __uobj_perform_destroy()
255 uobj_put_destroy(uobj); in __uobj_perform_destroy()
264 struct ib_uobject *uobj; in alloc_uobj() local
275 uobj = kzalloc(obj->type_attrs->obj_size, GFP_KERNEL); in alloc_uobj()
276 if (!uobj) in alloc_uobj()
282 uobj->ufile = ufile; in alloc_uobj()
283 uobj->context = attrs->context; in alloc_uobj()
284 INIT_LIST_HEAD(&uobj->list); in alloc_uobj()
285 uobj->uapi_object = obj; in alloc_uobj()
291 atomic_set(&uobj->usecnt, -1); in alloc_uobj()
292 kref_init(&uobj->ref); in alloc_uobj()
294 return uobj; in alloc_uobj()
297 static int idr_add_uobj(struct ib_uobject *uobj) in idr_add_uobj() argument
304 return xa_alloc(&uobj->ufile->idr, &uobj->id, NULL, xa_limit_32b, in idr_add_uobj()
314 struct ib_uobject *uobj; in lookup_get_idr_uobject() local
326 uobj = xa_load(&ufile->idr, id); in lookup_get_idr_uobject()
327 if (!uobj || !kref_get_unless_zero(&uobj->ref)) in lookup_get_idr_uobject()
328 uobj = ERR_PTR(-ENOENT); in lookup_get_idr_uobject()
330 return uobj; in lookup_get_idr_uobject()
378 struct ib_uobject *uobj; in rdma_lookup_get_uobject() local
383 uobj = lookup_get_idr_uobject(NULL, ufile, id, mode); in rdma_lookup_get_uobject()
384 if (IS_ERR(uobj)) in rdma_lookup_get_uobject()
385 return uobj; in rdma_lookup_get_uobject()
390 uobj = obj->type_class->lookup_get(obj, ufile, id, mode); in rdma_lookup_get_uobject()
391 if (IS_ERR(uobj)) in rdma_lookup_get_uobject()
392 return uobj; in rdma_lookup_get_uobject()
394 if (uobj->uapi_object != obj) { in rdma_lookup_get_uobject()
411 ret = uverbs_try_lock_object(uobj, mode); in rdma_lookup_get_uobject()
415 attrs->context = uobj->context; in rdma_lookup_get_uobject()
417 return uobj; in rdma_lookup_get_uobject()
419 uobj->uapi_object->type_class->lookup_put(uobj, mode); in rdma_lookup_get_uobject()
420 uverbs_uobject_put(uobj); in rdma_lookup_get_uobject()
429 struct ib_uobject *uobj; in alloc_begin_idr_uobject() local
431 uobj = alloc_uobj(attrs, obj); in alloc_begin_idr_uobject()
432 if (IS_ERR(uobj)) in alloc_begin_idr_uobject()
433 return uobj; in alloc_begin_idr_uobject()
435 ret = idr_add_uobj(uobj); in alloc_begin_idr_uobject()
439 ret = ib_rdmacg_try_charge(&uobj->cg_obj, uobj->context->device, in alloc_begin_idr_uobject()
444 return uobj; in alloc_begin_idr_uobject()
447 xa_erase(&attrs->ufile->idr, uobj->id); in alloc_begin_idr_uobject()
449 uverbs_uobject_put(uobj); in alloc_begin_idr_uobject()
459 struct ib_uobject *uobj, *ret; in alloc_begin_fd_uobject() local
462 uobj = alloc_uobj(attrs, obj); in alloc_begin_fd_uobject()
463 if (IS_ERR(uobj)) in alloc_begin_fd_uobject()
464 return uobj; in alloc_begin_fd_uobject()
487 uobj->object = filp; in alloc_begin_fd_uobject()
489 uobj->id = new_fd; in alloc_begin_fd_uobject()
490 return uobj; in alloc_begin_fd_uobject()
495 uverbs_uobject_put(uobj); in alloc_begin_fd_uobject()
524 static void alloc_abort_idr_uobject(struct ib_uobject *uobj) in alloc_abort_idr_uobject() argument
526 ib_rdmacg_uncharge(&uobj->cg_obj, uobj->context->device, in alloc_abort_idr_uobject()
529 xa_erase(&uobj->ufile->idr, uobj->id); in alloc_abort_idr_uobject()
532 static int __must_check destroy_hw_idr_uobject(struct ib_uobject *uobj, in destroy_hw_idr_uobject() argument
537 container_of(uobj->uapi_object->type_attrs, in destroy_hw_idr_uobject()
539 int ret = idr_type->destroy_object(uobj, why, attrs); in destroy_hw_idr_uobject()
547 ib_rdmacg_uncharge(&uobj->cg_obj, uobj->context->device, in destroy_hw_idr_uobject()
553 static void remove_handle_idr_uobject(struct ib_uobject *uobj) in remove_handle_idr_uobject() argument
555 xa_erase(&uobj->ufile->idr, uobj->id); in remove_handle_idr_uobject()
557 uverbs_uobject_put(uobj); in remove_handle_idr_uobject()
560 static void alloc_abort_fd_uobject(struct ib_uobject *uobj) in alloc_abort_fd_uobject() argument
562 struct file *filp = uobj->object; in alloc_abort_fd_uobject()
565 put_unused_fd(uobj->id); in alloc_abort_fd_uobject()
568 static int __must_check destroy_hw_fd_uobject(struct ib_uobject *uobj, in destroy_hw_fd_uobject() argument
573 uobj->uapi_object->type_attrs, struct uverbs_obj_fd_type, type); in destroy_hw_fd_uobject()
575 fd_type->destroy_object(uobj, why); in destroy_hw_fd_uobject()
579 static void remove_handle_fd_uobject(struct ib_uobject *uobj) in remove_handle_fd_uobject() argument
583 static void alloc_commit_idr_uobject(struct ib_uobject *uobj) in alloc_commit_idr_uobject() argument
585 struct ib_uverbs_file *ufile = uobj->ufile; in alloc_commit_idr_uobject()
595 old = xa_store(&ufile->idr, uobj->id, uobj, GFP_KERNEL); in alloc_commit_idr_uobject()
620 static void alloc_commit_fd_uobject(struct ib_uobject *uobj) in alloc_commit_fd_uobject() argument
622 int fd = uobj->id; in alloc_commit_fd_uobject()
623 struct file *filp = uobj->object; in alloc_commit_fd_uobject()
626 kref_get(&uobj->ufile->ref); in alloc_commit_fd_uobject()
629 uobj->id = 0; in alloc_commit_fd_uobject()
635 filp->private_data = uobj; in alloc_commit_fd_uobject()
644 void rdma_alloc_commit_uobject(struct ib_uobject *uobj, in rdma_alloc_commit_uobject() argument
650 uverbs_uobject_get(uobj); in rdma_alloc_commit_uobject()
652 list_add(&uobj->list, &ufile->uobjects); in rdma_alloc_commit_uobject()
656 atomic_set(&uobj->usecnt, 0); in rdma_alloc_commit_uobject()
659 uobj->uapi_object->type_class->alloc_commit(uobj); in rdma_alloc_commit_uobject()
698 void rdma_alloc_abort_uobject(struct ib_uobject *uobj, in rdma_alloc_abort_uobject() argument
702 struct ib_uverbs_file *ufile = uobj->ufile; in rdma_alloc_abort_uobject()
706 ret = uobj->uapi_object->type_class->destroy_hw( in rdma_alloc_abort_uobject()
707 uobj, RDMA_REMOVE_ABORT, attrs); in rdma_alloc_abort_uobject()
715 return rdma_alloc_commit_uobject(uobj, attrs); in rdma_alloc_abort_uobject()
718 uverbs_destroy_uobject(uobj, RDMA_REMOVE_ABORT, attrs); in rdma_alloc_abort_uobject()
724 static void lookup_put_idr_uobject(struct ib_uobject *uobj, in lookup_put_idr_uobject() argument
729 static void lookup_put_fd_uobject(struct ib_uobject *uobj, in lookup_put_fd_uobject() argument
732 struct file *filp = uobj->object; in lookup_put_fd_uobject()
742 void rdma_lookup_put_uobject(struct ib_uobject *uobj, in rdma_lookup_put_uobject() argument
745 assert_uverbs_usecnt(uobj, mode); in rdma_lookup_put_uobject()
753 atomic_dec(&uobj->usecnt); in rdma_lookup_put_uobject()
756 atomic_set(&uobj->usecnt, 0); in rdma_lookup_put_uobject()
762 uobj->uapi_object->type_class->lookup_put(uobj, mode); in rdma_lookup_put_uobject()
764 uverbs_uobject_put(uobj); in rdma_lookup_put_uobject()
812 struct ib_uobject *uobj; in uverbs_uobject_fd_release() local
819 uobj = filp->private_data; in uverbs_uobject_fd_release()
820 ufile = uobj->ufile; in uverbs_uobject_fd_release()
824 .context = uobj->context, in uverbs_uobject_fd_release()
834 WARN_ON(uverbs_try_lock_object(uobj, UVERBS_LOOKUP_WRITE)); in uverbs_uobject_fd_release()
835 uverbs_destroy_uobject(uobj, RDMA_REMOVE_CLOSE, &attrs); in uverbs_uobject_fd_release()
843 uverbs_uobject_put(uobj); in uverbs_uobject_fd_release()
991 void uverbs_finalize_object(struct ib_uobject *uobj, in uverbs_finalize_object() argument
1003 rdma_lookup_put_uobject(uobj, UVERBS_LOOKUP_READ); in uverbs_finalize_object()
1006 rdma_lookup_put_uobject(uobj, UVERBS_LOOKUP_WRITE); in uverbs_finalize_object()
1009 if (uobj) in uverbs_finalize_object()
1010 rdma_lookup_put_uobject(uobj, UVERBS_LOOKUP_DESTROY); in uverbs_finalize_object()
1014 rdma_alloc_commit_uobject(uobj, attrs); in uverbs_finalize_object()
1016 rdma_alloc_abort_uobject(uobj, attrs, hw_obj_valid); in uverbs_finalize_object()