diff options
author | Daniel Vetter <daniel.vetter@ffwll.ch> | 2012-12-11 15:52:30 -0500 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2013-01-20 09:57:56 -0500 |
commit | 0ae6d7bc0e70dafc1739d50b2b8d9d7c61968395 (patch) | |
tree | 34f34e14b0cf7cd9eb68cdb72cb63a3157889ab1 | |
parent | 59ad1465423d968f06f243bc52cc3b1a320a27cf (diff) |
drm/nouveau: try to protect nbo->pin_refcount
... by moving the bo_pin/bo_unpin manipulation of the pin_refcount
under the protection of the ttm reservation lock. pin/unpin seems
to get called from all over the place, so atm this is completely racy.
After this patch there are only a few places in cleanup functions
left which access ->pin_refcount without locking. But I'm hoping that
those are safe and some other code invariant guarantees that this
won't blow up.
In any case, I only need to fix up pin/unpin to make ->pageflip work
safely, so let's keep it at that.
Add a comment to the header to explain the new locking rule.
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_bo.c | 22 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_bo.h | 2 |
2 files changed, 13 insertions, 11 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 69d7b1d0b9d6..64d6e3047dee 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c | |||
@@ -300,17 +300,18 @@ nouveau_bo_pin(struct nouveau_bo *nvbo, uint32_t memtype) | |||
300 | struct ttm_buffer_object *bo = &nvbo->bo; | 300 | struct ttm_buffer_object *bo = &nvbo->bo; |
301 | int ret; | 301 | int ret; |
302 | 302 | ||
303 | ret = ttm_bo_reserve(bo, false, false, false, 0); | ||
304 | if (ret) | ||
305 | goto out; | ||
306 | |||
303 | if (nvbo->pin_refcnt && !(memtype & (1 << bo->mem.mem_type))) { | 307 | if (nvbo->pin_refcnt && !(memtype & (1 << bo->mem.mem_type))) { |
304 | NV_ERROR(drm, "bo %p pinned elsewhere: 0x%08x vs 0x%08x\n", bo, | 308 | NV_ERROR(drm, "bo %p pinned elsewhere: 0x%08x vs 0x%08x\n", bo, |
305 | 1 << bo->mem.mem_type, memtype); | 309 | 1 << bo->mem.mem_type, memtype); |
306 | return -EINVAL; | 310 | ret = -EINVAL; |
311 | goto out; | ||
307 | } | 312 | } |
308 | 313 | ||
309 | if (nvbo->pin_refcnt++) | 314 | if (nvbo->pin_refcnt++) |
310 | return 0; | ||
311 | |||
312 | ret = ttm_bo_reserve(bo, false, false, false, 0); | ||
313 | if (ret) | ||
314 | goto out; | 315 | goto out; |
315 | 316 | ||
316 | nouveau_bo_placement_set(nvbo, memtype, 0); | 317 | nouveau_bo_placement_set(nvbo, memtype, 0); |
@@ -328,10 +329,8 @@ nouveau_bo_pin(struct nouveau_bo *nvbo, uint32_t memtype) | |||
328 | break; | 329 | break; |
329 | } | 330 | } |
330 | } | 331 | } |
331 | ttm_bo_unreserve(bo); | ||
332 | out: | 332 | out: |
333 | if (unlikely(ret)) | 333 | ttm_bo_unreserve(bo); |
334 | nvbo->pin_refcnt--; | ||
335 | return ret; | 334 | return ret; |
336 | } | 335 | } |
337 | 336 | ||
@@ -342,13 +341,13 @@ nouveau_bo_unpin(struct nouveau_bo *nvbo) | |||
342 | struct ttm_buffer_object *bo = &nvbo->bo; | 341 | struct ttm_buffer_object *bo = &nvbo->bo; |
343 | int ret; | 342 | int ret; |
344 | 343 | ||
345 | if (--nvbo->pin_refcnt) | ||
346 | return 0; | ||
347 | |||
348 | ret = ttm_bo_reserve(bo, false, false, false, 0); | 344 | ret = ttm_bo_reserve(bo, false, false, false, 0); |
349 | if (ret) | 345 | if (ret) |
350 | return ret; | 346 | return ret; |
351 | 347 | ||
348 | if (--nvbo->pin_refcnt) | ||
349 | goto out; | ||
350 | |||
352 | nouveau_bo_placement_set(nvbo, bo->mem.placement, 0); | 351 | nouveau_bo_placement_set(nvbo, bo->mem.placement, 0); |
353 | 352 | ||
354 | ret = nouveau_bo_validate(nvbo, false, false); | 353 | ret = nouveau_bo_validate(nvbo, false, false); |
@@ -365,6 +364,7 @@ nouveau_bo_unpin(struct nouveau_bo *nvbo) | |||
365 | } | 364 | } |
366 | } | 365 | } |
367 | 366 | ||
367 | out: | ||
368 | ttm_bo_unreserve(bo); | 368 | ttm_bo_unreserve(bo); |
369 | return ret; | 369 | return ret; |
370 | } | 370 | } |
diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.h b/drivers/gpu/drm/nouveau/nouveau_bo.h index 25ca37989d2c..81d00fe03b56 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.h +++ b/drivers/gpu/drm/nouveau/nouveau_bo.h | |||
@@ -28,6 +28,8 @@ struct nouveau_bo { | |||
28 | struct nouveau_drm_tile *tile; | 28 | struct nouveau_drm_tile *tile; |
29 | 29 | ||
30 | struct drm_gem_object *gem; | 30 | struct drm_gem_object *gem; |
31 | |||
32 | /* protect by the ttm reservation lock */ | ||
31 | int pin_refcnt; | 33 | int pin_refcnt; |
32 | 34 | ||
33 | struct ttm_bo_kmap_obj dma_buf_vmap; | 35 | struct ttm_bo_kmap_obj dma_buf_vmap; |