Author: dumbbell
Date: Sun Aug 25 14:47:22 2013
New Revision: 254863
URL: http://svnweb.freebsd.org/changeset/base/254863

Log:
  drm/ttm: Import Linux commit 5e45d7dfd74100d622f9cdc70bfd1f9fae1671de
  
  Author: Maarten Lankhorst <maarten.lankho...@canonical.com>
  Date:   Tue Jan 15 14:57:05 2013 +0100
  
      drm/ttm: add ttm_bo_reserve_slowpath
  
      Instead of dropping everything, waiting for the bo to be unreserved
      and trying over, a better strategy would be to do a blocking wait.
  
      This can be mapped a lot better to a mutex_lock-like call.
  
      Signed-off-by: Maarten Lankhorst <maarten.lankho...@canonical.com>
      Reviewed-by: Jerome Glisse <jgli...@redhat.com>
  
  Approved by:  kib@

Modified:
  head/sys/dev/drm2/ttm/ttm_bo.c
  head/sys/dev/drm2/ttm/ttm_bo_driver.h

Modified: head/sys/dev/drm2/ttm/ttm_bo.c
==============================================================================
--- head/sys/dev/drm2/ttm/ttm_bo.c      Sun Aug 25 14:41:22 2013        
(r254862)
+++ head/sys/dev/drm2/ttm/ttm_bo.c      Sun Aug 25 14:47:22 2013        
(r254863)
@@ -293,6 +293,56 @@ int ttm_bo_reserve(struct ttm_buffer_obj
        return ret;
 }
 
+int ttm_bo_reserve_slowpath_nolru(struct ttm_buffer_object *bo,
+                                 bool interruptible, uint32_t sequence)
+{
+       bool wake_up = false;
+       int ret;
+
+       while (unlikely(atomic_xchg(&bo->reserved, 1) != 0)) {
+               if (bo->seq_valid && sequence == bo->val_seq) {
+                       DRM_ERROR(
+                           "%s: bo->seq_valid && sequence == bo->val_seq",
+                           __func__);
+               }
+
+               ret = ttm_bo_wait_unreserved_locked(bo, interruptible);
+
+               if (unlikely(ret))
+                       return ret;
+       }
+
+       if ((bo->val_seq - sequence < (1 << 31)) || !bo->seq_valid)
+               wake_up = true;
+
+       /**
+        * Wake up waiters that may need to recheck for deadlock,
+        * if we decreased the sequence number.
+        */
+       bo->val_seq = sequence;
+       bo->seq_valid = true;
+       if (wake_up)
+               wakeup(bo);
+
+       return 0;
+}
+
+int ttm_bo_reserve_slowpath(struct ttm_buffer_object *bo,
+                           bool interruptible, uint32_t sequence)
+{
+       struct ttm_bo_global *glob = bo->glob;
+       int put_count, ret;
+
+       ret = ttm_bo_reserve_slowpath_nolru(bo, interruptible, sequence);
+       if (likely(!ret)) {
+               mtx_lock(&glob->lru_lock);
+               put_count = ttm_bo_del_from_lru(bo);
+               mtx_unlock(&glob->lru_lock);
+               ttm_bo_list_ref_sub(bo, put_count, true);
+       }
+       return ret;
+}
+
 void ttm_bo_unreserve_locked(struct ttm_buffer_object *bo)
 {
        ttm_bo_add_to_lru(bo);

Modified: head/sys/dev/drm2/ttm/ttm_bo_driver.h
==============================================================================
--- head/sys/dev/drm2/ttm/ttm_bo_driver.h       Sun Aug 25 14:41:22 2013        
(r254862)
+++ head/sys/dev/drm2/ttm/ttm_bo_driver.h       Sun Aug 25 14:47:22 2013        
(r254863)
@@ -822,6 +822,36 @@ extern int ttm_bo_reserve(struct ttm_buf
                          bool interruptible,
                          bool no_wait, bool use_sequence, uint32_t sequence);
 
+/**
+ * ttm_bo_reserve_slowpath_nolru:
+ * @bo: A pointer to a struct ttm_buffer_object.
+ * @interruptible: Sleep interruptible if waiting.
+ * @sequence: Set (@bo)->sequence to this value after lock
+ *
+ * This is called after ttm_bo_reserve returns -EAGAIN and we backed off
+ * from all our other reservations. Because there are no other reservations
+ * held by us, this function cannot deadlock any more.
+ *
+ * Will not remove reserved buffers from the lru lists.
+ * Otherwise identical to ttm_bo_reserve_slowpath.
+ */
+extern int ttm_bo_reserve_slowpath_nolru(struct ttm_buffer_object *bo,
+                                        bool interruptible,
+                                        uint32_t sequence);
+
+
+/**
+ * ttm_bo_reserve_slowpath:
+ * @bo: A pointer to a struct ttm_buffer_object.
+ * @interruptible: Sleep interruptible if waiting.
+ * @sequence: Set (@bo)->sequence to this value after lock
+ *
+ * This is called after ttm_bo_reserve returns -EAGAIN and we backed off
+ * from all our other reservations. Because there are no other reservations
+ * held by us, this function cannot deadlock any more.
+ */
+extern int ttm_bo_reserve_slowpath(struct ttm_buffer_object *bo,
+                                  bool interruptible, uint32_t sequence);
 
 /**
  * ttm_bo_reserve_nolru:
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to