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-head mailing list