GNU Linux-libre 6.7.9-gnu
[releases.git] / drivers / infiniband / core / uverbs_std_types_srq.c
1 // SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
2 /*
3  * Copyright (c) 2020, Mellanox Technologies inc.  All rights reserved.
4  */
5
6 #include <rdma/uverbs_std_types.h>
7 #include "rdma_core.h"
8 #include "uverbs.h"
9
10 static int uverbs_free_srq(struct ib_uobject *uobject,
11                     enum rdma_remove_reason why,
12                     struct uverbs_attr_bundle *attrs)
13 {
14         struct ib_srq *srq = uobject->object;
15         struct ib_uevent_object *uevent =
16                 container_of(uobject, struct ib_uevent_object, uobject);
17         enum ib_srq_type srq_type = srq->srq_type;
18         int ret;
19
20         ret = ib_destroy_srq_user(srq, &attrs->driver_udata);
21         if (ret)
22                 return ret;
23
24         if (srq_type == IB_SRQT_XRC) {
25                 struct ib_usrq_object *us =
26                         container_of(uobject, struct ib_usrq_object,
27                                      uevent.uobject);
28
29                 atomic_dec(&us->uxrcd->refcnt);
30         }
31
32         ib_uverbs_release_uevent(uevent);
33         return 0;
34 }
35
36 static int UVERBS_HANDLER(UVERBS_METHOD_SRQ_CREATE)(
37         struct uverbs_attr_bundle *attrs)
38 {
39         struct ib_usrq_object *obj = container_of(
40                 uverbs_attr_get_uobject(attrs, UVERBS_ATTR_CREATE_SRQ_HANDLE),
41                 typeof(*obj), uevent.uobject);
42         struct ib_pd *pd =
43                 uverbs_attr_get_obj(attrs, UVERBS_ATTR_CREATE_SRQ_PD_HANDLE);
44         struct ib_srq_init_attr attr = {};
45         struct ib_uobject *xrcd_uobj;
46         struct ib_srq *srq;
47         u64 user_handle;
48         int ret;
49
50         ret = uverbs_copy_from(&attr.attr.max_sge, attrs,
51                                UVERBS_ATTR_CREATE_SRQ_MAX_SGE);
52         if (!ret)
53                 ret = uverbs_copy_from(&attr.attr.max_wr, attrs,
54                                        UVERBS_ATTR_CREATE_SRQ_MAX_WR);
55         if (!ret)
56                 ret = uverbs_copy_from(&attr.attr.srq_limit, attrs,
57                                        UVERBS_ATTR_CREATE_SRQ_LIMIT);
58         if (!ret)
59                 ret = uverbs_copy_from(&user_handle, attrs,
60                                        UVERBS_ATTR_CREATE_SRQ_USER_HANDLE);
61         if (!ret)
62                 ret = uverbs_get_const(&attr.srq_type, attrs,
63                                        UVERBS_ATTR_CREATE_SRQ_TYPE);
64         if (ret)
65                 return ret;
66
67         if (ib_srq_has_cq(attr.srq_type)) {
68                 attr.ext.cq = uverbs_attr_get_obj(attrs,
69                                         UVERBS_ATTR_CREATE_SRQ_CQ_HANDLE);
70                 if (IS_ERR(attr.ext.cq))
71                         return PTR_ERR(attr.ext.cq);
72         }
73
74         switch (attr.srq_type) {
75         case IB_UVERBS_SRQT_XRC:
76                 xrcd_uobj = uverbs_attr_get_uobject(attrs,
77                                         UVERBS_ATTR_CREATE_SRQ_XRCD_HANDLE);
78                 if (IS_ERR(xrcd_uobj))
79                         return PTR_ERR(xrcd_uobj);
80
81                 attr.ext.xrc.xrcd = (struct ib_xrcd *)xrcd_uobj->object;
82                 if (!attr.ext.xrc.xrcd)
83                         return -EINVAL;
84                 obj->uxrcd = container_of(xrcd_uobj, struct ib_uxrcd_object,
85                                           uobject);
86                 atomic_inc(&obj->uxrcd->refcnt);
87                 break;
88         case IB_UVERBS_SRQT_TM:
89                 ret = uverbs_copy_from(&attr.ext.tag_matching.max_num_tags,
90                                        attrs,
91                                        UVERBS_ATTR_CREATE_SRQ_MAX_NUM_TAGS);
92                 if (ret)
93                         return ret;
94                 break;
95         case IB_UVERBS_SRQT_BASIC:
96                 break;
97         default:
98                 return -EINVAL;
99         }
100
101         obj->uevent.event_file = ib_uverbs_get_async_event(attrs,
102                                         UVERBS_ATTR_CREATE_SRQ_EVENT_FD);
103         INIT_LIST_HEAD(&obj->uevent.event_list);
104         attr.event_handler = ib_uverbs_srq_event_handler;
105         obj->uevent.uobject.user_handle = user_handle;
106
107         srq = ib_create_srq_user(pd, &attr, obj, &attrs->driver_udata);
108         if (IS_ERR(srq)) {
109                 ret = PTR_ERR(srq);
110                 goto err;
111         }
112
113         obj->uevent.uobject.object = srq;
114         uverbs_finalize_uobj_create(attrs, UVERBS_ATTR_CREATE_SRQ_HANDLE);
115
116         ret = uverbs_copy_to(attrs, UVERBS_ATTR_CREATE_SRQ_RESP_MAX_WR,
117                              &attr.attr.max_wr,
118                              sizeof(attr.attr.max_wr));
119         if (ret)
120                 return ret;
121
122         ret = uverbs_copy_to(attrs, UVERBS_ATTR_CREATE_SRQ_RESP_MAX_SGE,
123                              &attr.attr.max_sge,
124                              sizeof(attr.attr.max_sge));
125         if (ret)
126                 return ret;
127
128         if (attr.srq_type == IB_SRQT_XRC) {
129                 ret = uverbs_copy_to(attrs,
130                                      UVERBS_ATTR_CREATE_SRQ_RESP_SRQ_NUM,
131                                      &srq->ext.xrc.srq_num,
132                                      sizeof(srq->ext.xrc.srq_num));
133                 if (ret)
134                         return ret;
135         }
136
137         return 0;
138 err:
139         if (obj->uevent.event_file)
140                 uverbs_uobject_put(&obj->uevent.event_file->uobj);
141         if (attr.srq_type == IB_SRQT_XRC)
142                 atomic_dec(&obj->uxrcd->refcnt);
143         return ret;
144 };
145
146 DECLARE_UVERBS_NAMED_METHOD(
147         UVERBS_METHOD_SRQ_CREATE,
148         UVERBS_ATTR_IDR(UVERBS_ATTR_CREATE_SRQ_HANDLE,
149                         UVERBS_OBJECT_SRQ,
150                         UVERBS_ACCESS_NEW,
151                         UA_MANDATORY),
152         UVERBS_ATTR_IDR(UVERBS_ATTR_CREATE_SRQ_PD_HANDLE,
153                         UVERBS_OBJECT_PD,
154                         UVERBS_ACCESS_READ,
155                         UA_MANDATORY),
156         UVERBS_ATTR_CONST_IN(UVERBS_ATTR_CREATE_SRQ_TYPE,
157                              enum ib_uverbs_srq_type,
158                              UA_MANDATORY),
159         UVERBS_ATTR_PTR_IN(UVERBS_ATTR_CREATE_SRQ_USER_HANDLE,
160                            UVERBS_ATTR_TYPE(u64),
161                            UA_MANDATORY),
162         UVERBS_ATTR_PTR_IN(UVERBS_ATTR_CREATE_SRQ_MAX_WR,
163                            UVERBS_ATTR_TYPE(u32),
164                            UA_MANDATORY),
165         UVERBS_ATTR_PTR_IN(UVERBS_ATTR_CREATE_SRQ_MAX_SGE,
166                            UVERBS_ATTR_TYPE(u32),
167                            UA_MANDATORY),
168         UVERBS_ATTR_PTR_IN(UVERBS_ATTR_CREATE_SRQ_LIMIT,
169                            UVERBS_ATTR_TYPE(u32),
170                            UA_MANDATORY),
171         UVERBS_ATTR_IDR(UVERBS_ATTR_CREATE_SRQ_XRCD_HANDLE,
172                         UVERBS_OBJECT_XRCD,
173                         UVERBS_ACCESS_READ,
174                         UA_OPTIONAL),
175         UVERBS_ATTR_IDR(UVERBS_ATTR_CREATE_SRQ_CQ_HANDLE,
176                         UVERBS_OBJECT_CQ,
177                         UVERBS_ACCESS_READ,
178                         UA_OPTIONAL),
179         UVERBS_ATTR_PTR_IN(UVERBS_ATTR_CREATE_SRQ_MAX_NUM_TAGS,
180                            UVERBS_ATTR_TYPE(u32),
181                            UA_OPTIONAL),
182         UVERBS_ATTR_FD(UVERBS_ATTR_CREATE_SRQ_EVENT_FD,
183                        UVERBS_OBJECT_ASYNC_EVENT,
184                        UVERBS_ACCESS_READ,
185                        UA_OPTIONAL),
186         UVERBS_ATTR_PTR_OUT(UVERBS_ATTR_CREATE_SRQ_RESP_MAX_WR,
187                             UVERBS_ATTR_TYPE(u32),
188                             UA_MANDATORY),
189         UVERBS_ATTR_PTR_OUT(UVERBS_ATTR_CREATE_SRQ_RESP_MAX_SGE,
190                             UVERBS_ATTR_TYPE(u32),
191                             UA_MANDATORY),
192         UVERBS_ATTR_PTR_OUT(UVERBS_ATTR_CREATE_SRQ_RESP_SRQ_NUM,
193                            UVERBS_ATTR_TYPE(u32),
194                            UA_OPTIONAL),
195         UVERBS_ATTR_UHW());
196
197 static int UVERBS_HANDLER(UVERBS_METHOD_SRQ_DESTROY)(
198         struct uverbs_attr_bundle *attrs)
199 {
200         struct ib_uobject *uobj =
201                 uverbs_attr_get_uobject(attrs, UVERBS_ATTR_DESTROY_SRQ_HANDLE);
202         struct ib_usrq_object *obj =
203                 container_of(uobj, struct ib_usrq_object, uevent.uobject);
204         struct ib_uverbs_destroy_srq_resp resp = {
205                 .events_reported = obj->uevent.events_reported
206         };
207
208         return uverbs_copy_to(attrs, UVERBS_ATTR_DESTROY_SRQ_RESP, &resp,
209                               sizeof(resp));
210 }
211
212 DECLARE_UVERBS_NAMED_METHOD(
213         UVERBS_METHOD_SRQ_DESTROY,
214         UVERBS_ATTR_IDR(UVERBS_ATTR_DESTROY_SRQ_HANDLE,
215                         UVERBS_OBJECT_SRQ,
216                         UVERBS_ACCESS_DESTROY,
217                         UA_MANDATORY),
218         UVERBS_ATTR_PTR_OUT(UVERBS_ATTR_DESTROY_SRQ_RESP,
219                             UVERBS_ATTR_TYPE(struct ib_uverbs_destroy_srq_resp),
220                             UA_MANDATORY));
221
222 DECLARE_UVERBS_NAMED_OBJECT(
223         UVERBS_OBJECT_SRQ,
224         UVERBS_TYPE_ALLOC_IDR_SZ(sizeof(struct ib_usrq_object),
225                                  uverbs_free_srq),
226         &UVERBS_METHOD(UVERBS_METHOD_SRQ_CREATE),
227         &UVERBS_METHOD(UVERBS_METHOD_SRQ_DESTROY)
228 );
229
230 const struct uapi_definition uverbs_def_obj_srq[] = {
231         UAPI_DEF_CHAIN_OBJ_TREE_NAMED(UVERBS_OBJECT_SRQ,
232                                       UAPI_DEF_OBJ_NEEDS_FN(destroy_srq)),
233         {}
234 };