diff options
author | Ralph Campbell <ralph.campbell@qlogic.com> | 2007-11-09 18:22:31 -0500 |
---|---|---|
committer | Roland Dreier <rolandd@cisco.com> | 2007-11-20 14:04:41 -0500 |
commit | 14de986a0ba560b54340fd277a3579e95a2d3838 (patch) | |
tree | 853ca35f6c93dfc940cc359009cb315dbb28084e /drivers/infiniband | |
parent | 8a278e6d571ebe10b96f2b53c74f01fd0a3f005a (diff) |
IB/ipath: Fix offset returned to ibv_modify_srq()
The wrong offset was being returned to libipathverbs so that when
ibv_modify_srq() calls mmap(), it always fails.
Signed-off-by: Ralph Campbell <ralph.campbell@qlogic.com>
Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/infiniband')
-rw-r--r-- | drivers/infiniband/hw/ipath/ipath_srq.c | 42 |
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 | ||
336 | bail_unlock: | ||
337 | spin_unlock_irq(&srq->rq.lock); | ||
338 | bail_free: | ||
339 | vfree(wq); | ||
332 | bail: | 340 | bail: |
333 | return ret; | 341 | return ret; |
334 | } | 342 | } |