hc
2024-01-03 2f7c68cb55ecb7331f2381deb497c27155f32faf
kernel/drivers/infiniband/sw/rdmavt/srq.c
....@@ -48,10 +48,11 @@
4848 #include <linux/err.h>
4949 #include <linux/slab.h>
5050 #include <linux/vmalloc.h>
51
+#include <rdma/uverbs_ioctl.h>
5152
5253 #include "srq.h"
5354 #include "vt.h"
54
-
55
+#include "qp.h"
5556 /**
5657 * rvt_driver_srq_init - init srq resources on a per driver basis
5758 * @rdi: rvt dev structure
....@@ -70,29 +71,24 @@
7071 * @srq_init_attr: the attributes of the SRQ
7172 * @udata: data from libibverbs when creating a user SRQ
7273 *
73
- * Return: Allocated srq object
74
+ * Return: 0 on success
7475 */
75
-struct ib_srq *rvt_create_srq(struct ib_pd *ibpd,
76
- struct ib_srq_init_attr *srq_init_attr,
77
- struct ib_udata *udata)
76
+int rvt_create_srq(struct ib_srq *ibsrq, struct ib_srq_init_attr *srq_init_attr,
77
+ struct ib_udata *udata)
7878 {
79
- struct rvt_dev_info *dev = ib_to_rvt(ibpd->device);
80
- struct rvt_srq *srq;
79
+ struct rvt_dev_info *dev = ib_to_rvt(ibsrq->device);
80
+ struct rvt_srq *srq = ibsrq_to_rvtsrq(ibsrq);
8181 u32 sz;
82
- struct ib_srq *ret;
82
+ int ret;
8383
8484 if (srq_init_attr->srq_type != IB_SRQT_BASIC)
85
- return ERR_PTR(-EOPNOTSUPP);
85
+ return -EOPNOTSUPP;
8686
8787 if (srq_init_attr->attr.max_sge == 0 ||
8888 srq_init_attr->attr.max_sge > dev->dparms.props.max_srq_sge ||
8989 srq_init_attr->attr.max_wr == 0 ||
9090 srq_init_attr->attr.max_wr > dev->dparms.props.max_srq_wr)
91
- return ERR_PTR(-EINVAL);
92
-
93
- srq = kzalloc_node(sizeof(*srq), GFP_KERNEL, dev->dparms.node);
94
- if (!srq)
95
- return ERR_PTR(-ENOMEM);
91
+ return -EINVAL;
9692
9793 /*
9894 * Need to use vmalloc() if we want to support large #s of entries.
....@@ -101,12 +97,9 @@
10197 srq->rq.max_sge = srq_init_attr->attr.max_sge;
10298 sz = sizeof(struct ib_sge) * srq->rq.max_sge +
10399 sizeof(struct rvt_rwqe);
104
- srq->rq.wq = udata ?
105
- vmalloc_user(sizeof(struct rvt_rwq) + srq->rq.size * sz) :
106
- vzalloc_node(sizeof(struct rvt_rwq) + srq->rq.size * sz,
107
- dev->dparms.node);
108
- if (!srq->rq.wq) {
109
- ret = ERR_PTR(-ENOMEM);
100
+ if (rvt_alloc_rq(&srq->rq, srq->rq.size * sz,
101
+ dev->dparms.node, udata)) {
102
+ ret = -ENOMEM;
110103 goto bail_srq;
111104 }
112105
....@@ -115,23 +108,18 @@
115108 * See rvt_mmap() for details.
116109 */
117110 if (udata && udata->outlen >= sizeof(__u64)) {
118
- int err;
119111 u32 s = sizeof(struct rvt_rwq) + srq->rq.size * sz;
120112
121
- srq->ip =
122
- rvt_create_mmap_info(dev, s, ibpd->uobject->context,
123
- srq->rq.wq);
124
- if (!srq->ip) {
125
- ret = ERR_PTR(-ENOMEM);
113
+ srq->ip = rvt_create_mmap_info(dev, s, udata, srq->rq.wq);
114
+ if (IS_ERR(srq->ip)) {
115
+ ret = PTR_ERR(srq->ip);
126116 goto bail_wq;
127117 }
128118
129
- err = ib_copy_to_udata(udata, &srq->ip->offset,
119
+ ret = ib_copy_to_udata(udata, &srq->ip->offset,
130120 sizeof(srq->ip->offset));
131
- if (err) {
132
- ret = ERR_PTR(err);
121
+ if (ret)
133122 goto bail_ip;
134
- }
135123 }
136124
137125 /*
....@@ -143,7 +131,7 @@
143131 spin_lock(&dev->n_srqs_lock);
144132 if (dev->n_srqs_allocated == dev->dparms.props.max_srq) {
145133 spin_unlock(&dev->n_srqs_lock);
146
- ret = ERR_PTR(-ENOMEM);
134
+ ret = -ENOMEM;
147135 goto bail_ip;
148136 }
149137
....@@ -156,14 +144,13 @@
156144 spin_unlock_irq(&dev->pending_lock);
157145 }
158146
159
- return &srq->ibsrq;
147
+ return 0;
160148
161149 bail_ip:
162150 kfree(srq->ip);
163151 bail_wq:
164
- vfree(srq->rq.wq);
152
+ rvt_free_rq(&srq->rq);
165153 bail_srq:
166
- kfree(srq);
167154 return ret;
168155 }
169156
....@@ -182,11 +169,12 @@
182169 {
183170 struct rvt_srq *srq = ibsrq_to_rvtsrq(ibsrq);
184171 struct rvt_dev_info *dev = ib_to_rvt(ibsrq->device);
185
- struct rvt_rwq *wq;
172
+ struct rvt_rq tmp_rq = {};
186173 int ret = 0;
187174
188175 if (attr_mask & IB_SRQ_MAX_WR) {
189
- struct rvt_rwq *owq;
176
+ struct rvt_krwq *okwq = NULL;
177
+ struct rvt_rwq *owq = NULL;
190178 struct rvt_rwqe *p;
191179 u32 sz, size, n, head, tail;
192180
....@@ -195,17 +183,12 @@
195183 ((attr_mask & IB_SRQ_LIMIT) ?
196184 attr->srq_limit : srq->limit) > attr->max_wr)
197185 return -EINVAL;
198
-
199186 sz = sizeof(struct rvt_rwqe) +
200187 srq->rq.max_sge * sizeof(struct ib_sge);
201188 size = attr->max_wr + 1;
202
- wq = udata ?
203
- vmalloc_user(sizeof(struct rvt_rwq) + size * sz) :
204
- vzalloc_node(sizeof(struct rvt_rwq) + size * sz,
205
- dev->dparms.node);
206
- if (!wq)
189
+ if (rvt_alloc_rq(&tmp_rq, size * sz, dev->dparms.node,
190
+ udata))
207191 return -ENOMEM;
208
-
209192 /* Check that we can write the offset to mmap. */
210193 if (udata && udata->inlen >= sizeof(__u64)) {
211194 __u64 offset_addr;
....@@ -223,14 +206,20 @@
223206 goto bail_free;
224207 }
225208
226
- spin_lock_irq(&srq->rq.lock);
209
+ spin_lock_irq(&srq->rq.kwq->c_lock);
227210 /*
228211 * validate head and tail pointer values and compute
229212 * the number of remaining WQEs.
230213 */
231
- owq = srq->rq.wq;
232
- head = owq->head;
233
- tail = owq->tail;
214
+ if (udata) {
215
+ owq = srq->rq.wq;
216
+ head = RDMA_READ_UAPI_ATOMIC(owq->head);
217
+ tail = RDMA_READ_UAPI_ATOMIC(owq->tail);
218
+ } else {
219
+ okwq = srq->rq.kwq;
220
+ head = okwq->head;
221
+ tail = okwq->tail;
222
+ }
234223 if (head >= srq->rq.size || tail >= srq->rq.size) {
235224 ret = -EINVAL;
236225 goto bail_unlock;
....@@ -245,7 +234,7 @@
245234 goto bail_unlock;
246235 }
247236 n = 0;
248
- p = wq->wq;
237
+ p = tmp_rq.kwq->curr_wq;
249238 while (tail != head) {
250239 struct rvt_rwqe *wqe;
251240 int i;
....@@ -260,22 +249,29 @@
260249 if (++tail >= srq->rq.size)
261250 tail = 0;
262251 }
263
- srq->rq.wq = wq;
252
+ srq->rq.kwq = tmp_rq.kwq;
253
+ if (udata) {
254
+ srq->rq.wq = tmp_rq.wq;
255
+ RDMA_WRITE_UAPI_ATOMIC(tmp_rq.wq->head, n);
256
+ RDMA_WRITE_UAPI_ATOMIC(tmp_rq.wq->tail, 0);
257
+ } else {
258
+ tmp_rq.kwq->head = n;
259
+ tmp_rq.kwq->tail = 0;
260
+ }
264261 srq->rq.size = size;
265
- wq->head = n;
266
- wq->tail = 0;
267262 if (attr_mask & IB_SRQ_LIMIT)
268263 srq->limit = attr->srq_limit;
269
- spin_unlock_irq(&srq->rq.lock);
264
+ spin_unlock_irq(&srq->rq.kwq->c_lock);
270265
271266 vfree(owq);
267
+ kvfree(okwq);
272268
273269 if (srq->ip) {
274270 struct rvt_mmap_info *ip = srq->ip;
275271 struct rvt_dev_info *dev = ib_to_rvt(srq->ibsrq.device);
276272 u32 s = sizeof(struct rvt_rwq) + size * sz;
277273
278
- rvt_update_mmap_info(dev, ip, s, wq);
274
+ rvt_update_mmap_info(dev, ip, s, tmp_rq.wq);
279275
280276 /*
281277 * Return the offset to mmap.
....@@ -299,19 +295,19 @@
299295 spin_unlock_irq(&dev->pending_lock);
300296 }
301297 } else if (attr_mask & IB_SRQ_LIMIT) {
302
- spin_lock_irq(&srq->rq.lock);
298
+ spin_lock_irq(&srq->rq.kwq->c_lock);
303299 if (attr->srq_limit >= srq->rq.size)
304300 ret = -EINVAL;
305301 else
306302 srq->limit = attr->srq_limit;
307
- spin_unlock_irq(&srq->rq.lock);
303
+ spin_unlock_irq(&srq->rq.kwq->c_lock);
308304 }
309305 return ret;
310306
311307 bail_unlock:
312
- spin_unlock_irq(&srq->rq.lock);
308
+ spin_unlock_irq(&srq->rq.kwq->c_lock);
313309 bail_free:
314
- vfree(wq);
310
+ rvt_free_rq(&tmp_rq);
315311 return ret;
316312 }
317313
....@@ -335,9 +331,8 @@
335331 * rvt_destroy_srq - destory an srq
336332 * @ibsrq: srq object to destroy
337333 *
338
- * Return always 0
339334 */
340
-int rvt_destroy_srq(struct ib_srq *ibsrq)
335
+int rvt_destroy_srq(struct ib_srq *ibsrq, struct ib_udata *udata)
341336 {
342337 struct rvt_srq *srq = ibsrq_to_rvtsrq(ibsrq);
343338 struct rvt_dev_info *dev = ib_to_rvt(ibsrq->device);
....@@ -347,9 +342,6 @@
347342 spin_unlock(&dev->n_srqs_lock);
348343 if (srq->ip)
349344 kref_put(&srq->ip->ref, rvt_release_mmap_info);
350
- else
351
- vfree(srq->rq.wq);
352
- kfree(srq);
353
-
345
+ kvfree(srq->rq.kwq);
354346 return 0;
355347 }