uverbs_types.h 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. /* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */
  2. /*
  3. * Copyright (c) 2017, Mellanox Technologies inc. All rights reserved.
  4. */
  5. #ifndef _UVERBS_TYPES_
  6. #define _UVERBS_TYPES_
  7. #include <linux/kernel.h>
  8. #include <rdma/ib_verbs.h>
  9. struct uverbs_obj_type;
  10. struct uverbs_api_object;
  11. enum rdma_lookup_mode {
  12. UVERBS_LOOKUP_READ,
  13. UVERBS_LOOKUP_WRITE,
  14. /*
  15. * Destroy is like LOOKUP_WRITE, except that the uobject is not
  16. * locked. uobj_destroy is used to convert a LOOKUP_DESTROY lock into
  17. * a LOOKUP_WRITE lock.
  18. */
  19. UVERBS_LOOKUP_DESTROY,
  20. };
  21. /*
  22. * The following sequences are valid:
  23. * Success flow:
  24. * alloc_begin
  25. * alloc_commit
  26. * [..]
  27. * Access flow:
  28. * lookup_get(exclusive=false) & uverbs_try_lock_object
  29. * lookup_put(exclusive=false) via rdma_lookup_put_uobject
  30. * Destruction flow:
  31. * lookup_get(exclusive=true) & uverbs_try_lock_object
  32. * remove_commit
  33. * remove_handle (optional)
  34. * lookup_put(exclusive=true) via rdma_lookup_put_uobject
  35. *
  36. * Allocate Error flow #1
  37. * alloc_begin
  38. * alloc_abort
  39. * Allocate Error flow #2
  40. * alloc_begin
  41. * remove_commit
  42. * alloc_abort
  43. * Allocate Error flow #3
  44. * alloc_begin
  45. * alloc_commit (fails)
  46. * remove_commit
  47. * alloc_abort
  48. *
  49. * In all cases the caller must hold the ufile kref until alloc_commit or
  50. * alloc_abort returns.
  51. */
  52. struct uverbs_obj_type_class {
  53. struct ib_uobject *(*alloc_begin)(const struct uverbs_api_object *obj,
  54. struct uverbs_attr_bundle *attrs);
  55. /* This consumes the kref on uobj */
  56. void (*alloc_commit)(struct ib_uobject *uobj);
  57. /* This does not consume the kref on uobj */
  58. void (*alloc_abort)(struct ib_uobject *uobj);
  59. struct ib_uobject *(*lookup_get)(const struct uverbs_api_object *obj,
  60. struct ib_uverbs_file *ufile, s64 id,
  61. enum rdma_lookup_mode mode);
  62. void (*lookup_put)(struct ib_uobject *uobj, enum rdma_lookup_mode mode);
  63. /* This does not consume the kref on uobj */
  64. int __must_check (*destroy_hw)(struct ib_uobject *uobj,
  65. enum rdma_remove_reason why,
  66. struct uverbs_attr_bundle *attrs);
  67. void (*remove_handle)(struct ib_uobject *uobj);
  68. };
  69. struct uverbs_obj_type {
  70. const struct uverbs_obj_type_class * const type_class;
  71. size_t obj_size;
  72. };
  73. /*
  74. * Objects type classes which support a detach state (object is still alive but
  75. * it's not attached to any context need to make sure:
  76. * (a) no call through to a driver after a detach is called
  77. * (b) detach isn't called concurrently with context_cleanup
  78. */
  79. struct uverbs_obj_idr_type {
  80. /*
  81. * In idr based objects, uverbs_obj_type_class points to a generic
  82. * idr operations. In order to specialize the underlying types (e.g. CQ,
  83. * QPs, etc.), we add destroy_object specific callbacks.
  84. */
  85. struct uverbs_obj_type type;
  86. /* Free driver resources from the uobject, make the driver uncallable,
  87. * and move the uobject to the detached state. If the object was
  88. * destroyed by the user's request, a failure should leave the uobject
  89. * completely unchanged.
  90. */
  91. int __must_check (*destroy_object)(struct ib_uobject *uobj,
  92. enum rdma_remove_reason why,
  93. struct uverbs_attr_bundle *attrs);
  94. };
  95. struct ib_uobject *rdma_lookup_get_uobject(const struct uverbs_api_object *obj,
  96. struct ib_uverbs_file *ufile, s64 id,
  97. enum rdma_lookup_mode mode,
  98. struct uverbs_attr_bundle *attrs);
  99. void rdma_lookup_put_uobject(struct ib_uobject *uobj,
  100. enum rdma_lookup_mode mode);
  101. struct ib_uobject *rdma_alloc_begin_uobject(const struct uverbs_api_object *obj,
  102. struct uverbs_attr_bundle *attrs);
  103. void rdma_alloc_abort_uobject(struct ib_uobject *uobj,
  104. struct uverbs_attr_bundle *attrs,
  105. bool hw_obj_valid);
  106. void rdma_alloc_commit_uobject(struct ib_uobject *uobj,
  107. struct uverbs_attr_bundle *attrs);
  108. /*
  109. * uverbs_uobject_get is called in order to increase the reference count on
  110. * an uobject. This is useful when a handler wants to keep the uobject's memory
  111. * alive, regardless if this uobject is still alive in the context's objects
  112. * repository. Objects are put via uverbs_uobject_put.
  113. */
  114. static inline void uverbs_uobject_get(struct ib_uobject *uobject)
  115. {
  116. kref_get(&uobject->ref);
  117. }
  118. void uverbs_uobject_put(struct ib_uobject *uobject);
  119. struct uverbs_obj_fd_type {
  120. /*
  121. * In fd based objects, uverbs_obj_type_ops points to generic
  122. * fd operations. In order to specialize the underlying types (e.g.
  123. * completion_channel), we use fops, name and flags for fd creation.
  124. * destroy_object is called when the uobject is to be destroyed,
  125. * because the driver is removed or the FD is closed.
  126. */
  127. struct uverbs_obj_type type;
  128. int (*destroy_object)(struct ib_uobject *uobj,
  129. enum rdma_remove_reason why);
  130. const struct file_operations *fops;
  131. const char *name;
  132. int flags;
  133. };
  134. extern const struct uverbs_obj_type_class uverbs_idr_class;
  135. extern const struct uverbs_obj_type_class uverbs_fd_class;
  136. int uverbs_uobject_fd_release(struct inode *inode, struct file *filp);
  137. #define UVERBS_BUILD_BUG_ON(cond) (sizeof(char[1 - 2 * !!(cond)]) - \
  138. sizeof(char))
  139. #define UVERBS_TYPE_ALLOC_FD(_obj_size, _destroy_object, _fops, _name, _flags) \
  140. ((&((const struct uverbs_obj_fd_type) \
  141. {.type = { \
  142. .type_class = &uverbs_fd_class, \
  143. .obj_size = (_obj_size) + \
  144. UVERBS_BUILD_BUG_ON((_obj_size) < \
  145. sizeof(struct ib_uobject)), \
  146. }, \
  147. .destroy_object = _destroy_object, \
  148. .fops = _fops, \
  149. .name = _name, \
  150. .flags = _flags}))->type)
  151. #define UVERBS_TYPE_ALLOC_IDR_SZ(_size, _destroy_object) \
  152. ((&((const struct uverbs_obj_idr_type) \
  153. {.type = { \
  154. .type_class = &uverbs_idr_class, \
  155. .obj_size = (_size) + \
  156. UVERBS_BUILD_BUG_ON((_size) < \
  157. sizeof(struct ib_uobject)) \
  158. }, \
  159. .destroy_object = _destroy_object,}))->type)
  160. #define UVERBS_TYPE_ALLOC_IDR(_destroy_object) \
  161. UVERBS_TYPE_ALLOC_IDR_SZ(sizeof(struct ib_uobject), \
  162. _destroy_object)
  163. #endif