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 | |
| 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>
| -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 | } |
