Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 25 Aug 2013 14:47:22 +0000 (UTC)
From:      Jean-Sebastien Pedron <dumbbell@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r254863 - head/sys/dev/drm2/ttm
Message-ID:  <201308251447.r7PElMhR045172@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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.lankhorst@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.lankhorst@canonical.com>
      Reviewed-by: Jerome Glisse <jglisse@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:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201308251447.r7PElMhR045172>