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.vet...@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.vet...@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 <airl...@gmail.com>
      Cc: Jerome Glisse <jgli...@redhat.com>
      Cc: Maarten Lankhorst <maarten.lankho...@canonical.com>
      Signed-off-by: Daniel Vetter <daniel.vet...@ffwll.ch>
      Signed-off-by: Dave Airlie <airl...@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;
 
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to