aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/infiniband/hw/ipath/ipath_srq.c42
1 files changed, 25 insertions, 17 deletions
diff --git a/drivers/infiniband/hw/ipath/ipath_srq.c b/drivers/infiniband/hw/ipath/ipath_srq.c
index 40c36ec19016..434da6270f65 100644
--- a/drivers/infiniband/hw/ipath/ipath_srq.c
+++ b/drivers/infiniband/hw/ipath/ipath_srq.c
@@ -211,11 +211,11 @@ int ipath_modify_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr,
211 struct ib_udata *udata) 211 struct ib_udata *udata)
212{ 212{
213 struct ipath_srq *srq = to_isrq(ibsrq); 213 struct ipath_srq *srq = to_isrq(ibsrq);
214 struct ipath_rwq *wq;
214 int ret = 0; 215 int ret = 0;
215 216
216 if (attr_mask & IB_SRQ_MAX_WR) { 217 if (attr_mask & IB_SRQ_MAX_WR) {
217 struct ipath_rwq *owq; 218 struct ipath_rwq *owq;
218 struct ipath_rwq *wq;
219 struct ipath_rwqe *p; 219 struct ipath_rwqe *p;
220 u32 sz, size, n, head, tail; 220 u32 sz, size, n, head, tail;
221 221
@@ -236,27 +236,20 @@ int ipath_modify_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr,
236 goto bail; 236 goto bail;
237 } 237 }
238 238
239 /* 239 /* Check that we can write the offset to mmap. */
240 * Return the address of the RWQ as the offset to mmap.
241 * See ipath_mmap() for details.
242 */
243 if (udata && udata->inlen >= sizeof(__u64)) { 240 if (udata && udata->inlen >= sizeof(__u64)) {
244 __u64 offset_addr; 241 __u64 offset_addr;
245 __u64 offset = (__u64) wq; 242 __u64 offset = 0;
246 243
247 ret = ib_copy_from_udata(&offset_addr, udata, 244 ret = ib_copy_from_udata(&offset_addr, udata,
248 sizeof(offset_addr)); 245 sizeof(offset_addr));
249 if (ret) { 246 if (ret)
250 vfree(wq); 247 goto bail_free;
251 goto bail;
252 }
253 udata->outbuf = (void __user *) offset_addr; 248 udata->outbuf = (void __user *) offset_addr;
254 ret = ib_copy_to_udata(udata, &offset, 249 ret = ib_copy_to_udata(udata, &offset,
255 sizeof(offset)); 250 sizeof(offset));
256 if (ret) { 251 if (ret)
257 vfree(wq); 252 goto bail_free;
258 goto bail;
259 }
260 } 253 }
261 254
262 spin_lock_irq(&srq->rq.lock); 255 spin_lock_irq(&srq->rq.lock);
@@ -277,10 +270,8 @@ int ipath_modify_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr,
277 else 270 else
278 n -= tail; 271 n -= tail;
279 if (size <= n) { 272 if (size <= n) {
280 spin_unlock_irq(&srq->rq.lock);
281 vfree(wq);
282 ret = -EINVAL; 273 ret = -EINVAL;
283 goto bail; 274 goto bail_unlock;
284 } 275 }
285 n = 0; 276 n = 0;
286 p = wq->wq; 277 p = wq->wq;
@@ -314,6 +305,18 @@ int ipath_modify_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr,
314 u32 s = sizeof(struct ipath_rwq) + size * sz; 305 u32 s = sizeof(struct ipath_rwq) + size * sz;
315 306
316 ipath_update_mmap_info(dev, ip, s, wq); 307 ipath_update_mmap_info(dev, ip, s, wq);
308
309 /*
310 * Return the offset to mmap.
311 * See ipath_mmap() for details.
312 */
313 if (udata && udata->inlen >= sizeof(__u64)) {
314 ret = ib_copy_to_udata(udata, &ip->offset,
315 sizeof(ip->offset));
316 if (ret)
317 goto bail;
318 }
319
317 spin_lock_irq(&dev->pending_lock); 320 spin_lock_irq(&dev->pending_lock);
318 if (list_empty(&ip->pending_mmaps)) 321 if (list_empty(&ip->pending_mmaps))
319 list_add(&ip->pending_mmaps, 322 list_add(&ip->pending_mmaps,
@@ -328,7 +331,12 @@ int ipath_modify_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr,
328 srq->limit = attr->srq_limit; 331 srq->limit = attr->srq_limit;
329 spin_unlock_irq(&srq->rq.lock); 332 spin_unlock_irq(&srq->rq.lock);
330 } 333 }
334 goto bail;
331 335
336bail_unlock:
337 spin_unlock_irq(&srq->rq.lock);
338bail_free:
339 vfree(wq);
332bail: 340bail:
333 return ret; 341 return ret;
334} 342}