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