aboutsummaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorJean-Sébastien Pédron <dumbbell@FreeBSD.org>2013-08-25 14:58:44 +0000
committerJean-Sébastien Pédron <dumbbell@FreeBSD.org>2013-08-25 14:58:44 +0000
commita7fa1c7cc3c4f36aad7b3941f9846efc9edde879 (patch)
tree5de9744544b6d0e9d8b838fd09947d52cacff938 /sys
parent6ee96714c82c75924c4013232d15c624154f158f (diff)
downloadsrc-a7fa1c7cc3c4f36aad7b3941f9846efc9edde879.tar.gz
src-a7fa1c7cc3c4f36aad7b3941f9846efc9edde879.zip
drm/ttm: Import Linux commit ff7c60c580d9722f820d85c9c58ca55ecc1ee7c4
Author: Daniel Vetter <daniel.vetter@ffwll.ch> Date: Mon Jan 14 15:08:14 2013 +0100 drm/ttm: fix fence locking in ttm_buffer_object_transfer, 2nd try This fixes up commit e8e89622ed361c46bf90ba4828e685a8b603f7e5 Author: Daniel Vetter <daniel.vetter@ffwll.ch> Date: Tue Dec 18 22:25:11 2012 +0100 drm/ttm: fix fence locking in ttm_buffer_object_transfer which leaves behind a might_sleep in atomic context, since the fence_lock spinlock is held over a kmalloc(GFP_KERNEL) call. The fix is to revert the above commit and only take the lock where we need it, around the call to ->sync_obj_ref. v2: Fixup things noticed by Maarten Lankhorst: - Brown paper bag locking bug. - No need for kzalloc if we clear the entire thing on the next line. - check for bo->sync_obj (totally unlikely race, but still someone else could have snuck in) and clear fbo->sync_obj if it's cleared already. Reported-by: Dave Airlie <airlied@gmail.com> Cc: Jerome Glisse <jglisse@redhat.com> Cc: Maarten Lankhorst <maarten.lankhorst@canonical.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch> Signed-off-by: Dave Airlie <airlied@redhat.com> Approved by: kib@
Notes
Notes: svn path=/head/; revision=254868
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/drm2/ttm/ttm_bo_util.c19
1 files changed, 11 insertions, 8 deletions
diff --git a/sys/dev/drm2/ttm/ttm_bo_util.c b/sys/dev/drm2/ttm/ttm_bo_util.c
index 395989924e21..aed8e0e4a7e2 100644
--- a/sys/dev/drm2/ttm/ttm_bo_util.c
+++ b/sys/dev/drm2/ttm/ttm_bo_util.c
@@ -400,11 +400,13 @@ static void ttm_transfered_destroy(struct ttm_buffer_object *bo)
static int
ttm_buffer_object_transfer(struct ttm_buffer_object *bo,
- void *sync_obj, struct ttm_buffer_object **new_obj)
+ struct ttm_buffer_object **new_obj)
{
struct ttm_buffer_object *fbo;
+ struct ttm_bo_device *bdev = bo->bdev;
+ struct ttm_bo_driver *driver = bdev->driver;
- fbo = malloc(sizeof(*fbo), M_TTM_TRANSF_OBJ, M_ZERO | M_WAITOK);
+ fbo = malloc(sizeof(*fbo), M_TTM_TRANSF_OBJ, M_WAITOK);
*fbo = *bo;
/**
@@ -419,7 +421,12 @@ ttm_buffer_object_transfer(struct ttm_buffer_object *bo,
fbo->vm_node = NULL;
atomic_set(&fbo->cpu_writers, 0);
- fbo->sync_obj = sync_obj;
+ mtx_lock(&bdev->fence_lock);
+ if (bo->sync_obj)
+ fbo->sync_obj = driver->sync_obj_ref(bo->sync_obj);
+ else
+ fbo->sync_obj = NULL;
+ mtx_unlock(&bdev->fence_lock);
refcount_init(&fbo->list_kref, 1);
refcount_init(&fbo->kref, 1);
fbo->destroy = &ttm_transfered_destroy;
@@ -599,7 +606,6 @@ int ttm_bo_move_accel_cleanup(struct ttm_buffer_object *bo,
int ret;
struct ttm_buffer_object *ghost_obj;
void *tmp_obj = NULL;
- void *sync_obj_ref;
mtx_lock(&bdev->fence_lock);
if (bo->sync_obj) {
@@ -632,14 +638,11 @@ int ttm_bo_move_accel_cleanup(struct ttm_buffer_object *bo,
*/
set_bit(TTM_BO_PRIV_FLAG_MOVING, &bo->priv_flags);
-
- sync_obj_ref = bo->bdev->driver->sync_obj_ref(bo->sync_obj);
mtx_unlock(&bdev->fence_lock);
- /* ttm_buffer_object_transfer accesses bo->sync_obj */
- ret = ttm_buffer_object_transfer(bo, sync_obj_ref, &ghost_obj);
if (tmp_obj)
driver->sync_obj_unref(&tmp_obj);
+ ret = ttm_buffer_object_transfer(bo, &ghost_obj);
if (ret)
return ret;