svn commit: r254868 - head/sys/dev/drm2/ttm
Jean-Sebastien Pedron
dumbbell at FreeBSD.org
Sun Aug 25 14:58:45 UTC 2013
Author: dumbbell
Date: Sun Aug 25 14:58:44 2013
New Revision: 254868
URL: http://svnweb.freebsd.org/changeset/base/254868
Log:
drm/ttm: Import Linux commit ff7c60c580d9722f820d85c9c58ca55ecc1ee7c4
Author: Daniel Vetter <daniel.vetter at 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 at 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 at gmail.com>
Cc: Jerome Glisse <jglisse at redhat.com>
Cc: Maarten Lankhorst <maarten.lankhorst at canonical.com>
Signed-off-by: Daniel Vetter <daniel.vetter at ffwll.ch>
Signed-off-by: Dave Airlie <airlied at redhat.com>
Approved by: kib@
Modified:
head/sys/dev/drm2/ttm/ttm_bo_util.c
Modified: head/sys/dev/drm2/ttm/ttm_bo_util.c
==============================================================================
--- head/sys/dev/drm2/ttm/ttm_bo_util.c Sun Aug 25 14:56:14 2013 (r254867)
+++ head/sys/dev/drm2/ttm/ttm_bo_util.c Sun Aug 25 14:58:44 2013 (r254868)
@@ -400,11 +400,13 @@ static void ttm_transfered_destroy(struc
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_bu
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
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
*/
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;
More information about the svn-src-all
mailing list