drm/ttm: fix fence locking in ttm_buffer_object_transfer, 2nd try
[cascardo/linux.git] / drivers / gpu / drm / ttm / ttm_bo_util.c
index 44420fc..8be35c8 100644 (file)
@@ -429,7 +429,7 @@ static int ttm_buffer_object_transfer(struct ttm_buffer_object *bo,
        struct ttm_bo_device *bdev = bo->bdev;
        struct ttm_bo_driver *driver = bdev->driver;
 
-       fbo = kzalloc(sizeof(*fbo), GFP_KERNEL);
+       fbo = kmalloc(sizeof(*fbo), GFP_KERNEL);
        if (!fbo)
                return -ENOMEM;
 
@@ -448,7 +448,12 @@ static int ttm_buffer_object_transfer(struct ttm_buffer_object *bo,
        fbo->vm_node = NULL;
        atomic_set(&fbo->cpu_writers, 0);
 
-       fbo->sync_obj = driver->sync_obj_ref(bo->sync_obj);
+       spin_lock(&bdev->fence_lock);
+       if (bo->sync_obj)
+               fbo->sync_obj = driver->sync_obj_ref(bo->sync_obj);
+       else
+               fbo->sync_obj = NULL;
+       spin_unlock(&bdev->fence_lock);
        kref_init(&fbo->list_kref);
        kref_init(&fbo->kref);
        fbo->destroy = &ttm_transfered_destroy;
@@ -661,13 +666,11 @@ int ttm_bo_move_accel_cleanup(struct ttm_buffer_object *bo,
                 */
 
                set_bit(TTM_BO_PRIV_FLAG_MOVING, &bo->priv_flags);
-
-               /* ttm_buffer_object_transfer accesses bo->sync_obj */
-               ret = ttm_buffer_object_transfer(bo, &ghost_obj);
                spin_unlock(&bdev->fence_lock);
                if (tmp_obj)
                        driver->sync_obj_unref(&tmp_obj);
 
+               ret = ttm_buffer_object_transfer(bo, &ghost_obj);
                if (ret)
                        return ret;