uverbs_std_types.h 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  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_STD_TYPES__
  6. #define _UVERBS_STD_TYPES__
  7. #include <rdma/uverbs_types.h>
  8. #include <rdma/uverbs_ioctl.h>
  9. #include <rdma/ib_user_ioctl_verbs.h>
  10. /* Returns _id, or causes a compile error if _id is not a u32.
  11. *
  12. * The uobj APIs should only be used with the write based uAPI to access
  13. * object IDs. The write API must use a u32 for the object handle, which is
  14. * checked by this macro.
  15. */
  16. #define _uobj_check_id(_id) ((_id) * typecheck(u32, _id))
  17. #define uobj_get_type(_attrs, _object) \
  18. uapi_get_object((_attrs)->ufile->device->uapi, _object)
  19. #define uobj_get_read(_type, _id, _attrs) \
  20. rdma_lookup_get_uobject(uobj_get_type(_attrs, _type), (_attrs)->ufile, \
  21. _uobj_check_id(_id), UVERBS_LOOKUP_READ, \
  22. _attrs)
  23. #define ufd_get_read(_type, _fdnum, _attrs) \
  24. rdma_lookup_get_uobject(uobj_get_type(_attrs, _type), (_attrs)->ufile, \
  25. (_fdnum)*typecheck(s32, _fdnum), \
  26. UVERBS_LOOKUP_READ, _attrs)
  27. static inline void *_uobj_get_obj_read(struct ib_uobject *uobj)
  28. {
  29. if (IS_ERR(uobj))
  30. return NULL;
  31. return uobj->object;
  32. }
  33. #define uobj_get_obj_read(_object, _type, _id, _attrs) \
  34. ((struct ib_##_object *)_uobj_get_obj_read( \
  35. uobj_get_read(_type, _id, _attrs)))
  36. #define uobj_get_write(_type, _id, _attrs) \
  37. rdma_lookup_get_uobject(uobj_get_type(_attrs, _type), (_attrs)->ufile, \
  38. _uobj_check_id(_id), UVERBS_LOOKUP_WRITE, \
  39. _attrs)
  40. int __uobj_perform_destroy(const struct uverbs_api_object *obj, u32 id,
  41. struct uverbs_attr_bundle *attrs);
  42. #define uobj_perform_destroy(_type, _id, _attrs) \
  43. __uobj_perform_destroy(uobj_get_type(_attrs, _type), \
  44. _uobj_check_id(_id), _attrs)
  45. struct ib_uobject *__uobj_get_destroy(const struct uverbs_api_object *obj,
  46. u32 id, struct uverbs_attr_bundle *attrs);
  47. #define uobj_get_destroy(_type, _id, _attrs) \
  48. __uobj_get_destroy(uobj_get_type(_attrs, _type), _uobj_check_id(_id), \
  49. _attrs)
  50. static inline void uobj_put_destroy(struct ib_uobject *uobj)
  51. {
  52. rdma_lookup_put_uobject(uobj, UVERBS_LOOKUP_DESTROY);
  53. }
  54. static inline void uobj_put_read(struct ib_uobject *uobj)
  55. {
  56. rdma_lookup_put_uobject(uobj, UVERBS_LOOKUP_READ);
  57. }
  58. #define uobj_put_obj_read(_obj) \
  59. uobj_put_read((_obj)->uobject)
  60. static inline void uobj_put_write(struct ib_uobject *uobj)
  61. {
  62. rdma_lookup_put_uobject(uobj, UVERBS_LOOKUP_WRITE);
  63. }
  64. static inline void uobj_alloc_abort(struct ib_uobject *uobj,
  65. struct uverbs_attr_bundle *attrs)
  66. {
  67. rdma_alloc_abort_uobject(uobj, attrs, false);
  68. }
  69. static inline void uobj_finalize_uobj_create(struct ib_uobject *uobj,
  70. struct uverbs_attr_bundle *attrs)
  71. {
  72. /*
  73. * Tell the core code that the write() handler has completed
  74. * initializing the object and that the core should commit or
  75. * abort this object based upon the return code from the write()
  76. * method. Similar to what uverbs_finalize_uobj_create() does for
  77. * ioctl()
  78. */
  79. WARN_ON(attrs->uobject);
  80. attrs->uobject = uobj;
  81. }
  82. static inline struct ib_uobject *
  83. __uobj_alloc(const struct uverbs_api_object *obj,
  84. struct uverbs_attr_bundle *attrs, struct ib_device **ib_dev)
  85. {
  86. struct ib_uobject *uobj = rdma_alloc_begin_uobject(obj, attrs);
  87. if (!IS_ERR(uobj))
  88. *ib_dev = attrs->context->device;
  89. return uobj;
  90. }
  91. #define uobj_alloc(_type, _attrs, _ib_dev) \
  92. __uobj_alloc(uobj_get_type(_attrs, _type), _attrs, _ib_dev)
  93. static inline void uverbs_flow_action_fill_action(struct ib_flow_action *action,
  94. struct ib_uobject *uobj,
  95. struct ib_device *ib_dev,
  96. enum ib_flow_action_type type)
  97. {
  98. atomic_set(&action->usecnt, 0);
  99. action->device = ib_dev;
  100. action->type = type;
  101. action->uobject = uobj;
  102. uobj->object = action;
  103. }
  104. struct ib_uflow_resources {
  105. size_t max;
  106. size_t num;
  107. size_t collection_num;
  108. size_t counters_num;
  109. struct ib_counters **counters;
  110. struct ib_flow_action **collection;
  111. };
  112. struct ib_uflow_object {
  113. struct ib_uobject uobject;
  114. struct ib_uflow_resources *resources;
  115. };
  116. struct ib_uflow_resources *flow_resources_alloc(size_t num_specs);
  117. void flow_resources_add(struct ib_uflow_resources *uflow_res,
  118. enum ib_flow_spec_type type,
  119. void *ibobj);
  120. void ib_uverbs_flow_resources_free(struct ib_uflow_resources *uflow_res);
  121. static inline void ib_set_flow(struct ib_uobject *uobj, struct ib_flow *ibflow,
  122. struct ib_qp *qp, struct ib_device *device,
  123. struct ib_uflow_resources *uflow_res)
  124. {
  125. struct ib_uflow_object *uflow;
  126. uobj->object = ibflow;
  127. ibflow->uobject = uobj;
  128. if (qp) {
  129. atomic_inc(&qp->usecnt);
  130. ibflow->qp = qp;
  131. }
  132. ibflow->device = device;
  133. uflow = container_of(uobj, typeof(*uflow), uobject);
  134. uflow->resources = uflow_res;
  135. }
  136. struct uverbs_api_object {
  137. const struct uverbs_obj_type *type_attrs;
  138. const struct uverbs_obj_type_class *type_class;
  139. u8 disabled:1;
  140. u32 id;
  141. };
  142. static inline u32 uobj_get_object_id(struct ib_uobject *uobj)
  143. {
  144. return uobj->uapi_object->id;
  145. }
  146. #endif