diff options
author | Thomas Hellstrom <thellstrom@vmware.com> | 2010-11-02 09:21:47 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2010-11-08 22:38:32 -0500 |
commit | aa123268c2623c62e33248dafc0572f091689e86 (patch) | |
tree | 8a61fcdcc61849b5b931466bc4560b543bc75527 /drivers/gpu/drm | |
parent | a0ae5864d42b41c411368bd689462bf063c029c8 (diff) |
drm/ttm: Make sure a sync object doesn't disappear while we use it
The sync object may disappear as soon as we release the bo::lock, so
take a reference on it while we use it.
One option would be to call sync_object_flush() before releasing the bo::lock,
but that would put an atomic requirement on that function.
Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r-- | drivers/gpu/drm/ttm/ttm_bo.c | 11 |
1 files changed, 7 insertions, 4 deletions
diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index a32fe41e5e24..340dfb11959d 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c | |||
@@ -458,7 +458,7 @@ static void ttm_bo_cleanup_refs_or_queue(struct ttm_buffer_object *bo) | |||
458 | struct ttm_bo_device *bdev = bo->bdev; | 458 | struct ttm_bo_device *bdev = bo->bdev; |
459 | struct ttm_bo_global *glob = bo->glob; | 459 | struct ttm_bo_global *glob = bo->glob; |
460 | struct ttm_bo_driver *driver; | 460 | struct ttm_bo_driver *driver; |
461 | void *sync_obj; | 461 | void *sync_obj = NULL; |
462 | void *sync_obj_arg; | 462 | void *sync_obj_arg; |
463 | int put_count; | 463 | int put_count; |
464 | int ret; | 464 | int ret; |
@@ -493,17 +493,20 @@ static void ttm_bo_cleanup_refs_or_queue(struct ttm_buffer_object *bo) | |||
493 | spin_lock(&glob->lru_lock); | 493 | spin_lock(&glob->lru_lock); |
494 | } | 494 | } |
495 | queue: | 495 | queue: |
496 | sync_obj = bo->sync_obj; | ||
497 | sync_obj_arg = bo->sync_obj_arg; | ||
498 | driver = bdev->driver; | 496 | driver = bdev->driver; |
497 | if (bo->sync_obj) | ||
498 | sync_obj = driver->sync_obj_ref(bo->sync_obj); | ||
499 | sync_obj_arg = bo->sync_obj_arg; | ||
499 | 500 | ||
500 | kref_get(&bo->list_kref); | 501 | kref_get(&bo->list_kref); |
501 | list_add_tail(&bo->ddestroy, &bdev->ddestroy); | 502 | list_add_tail(&bo->ddestroy, &bdev->ddestroy); |
502 | spin_unlock(&glob->lru_lock); | 503 | spin_unlock(&glob->lru_lock); |
503 | spin_unlock(&bo->lock); | 504 | spin_unlock(&bo->lock); |
504 | 505 | ||
505 | if (sync_obj) | 506 | if (sync_obj) { |
506 | driver->sync_obj_flush(sync_obj, sync_obj_arg); | 507 | driver->sync_obj_flush(sync_obj, sync_obj_arg); |
508 | driver->sync_obj_unref(&sync_obj); | ||
509 | } | ||
507 | schedule_delayed_work(&bdev->wq, | 510 | schedule_delayed_work(&bdev->wq, |
508 | ((HZ / 100) < 1) ? 1 : HZ / 100); | 511 | ((HZ / 100) < 1) ? 1 : HZ / 100); |
509 | } | 512 | } |