diff mbox

[RFC,068/111] staging: etnaviv: fix fence wrapping for gem objects

Message ID 1427988653-754-69-git-send-email-l.stach@pengutronix.de (mailing list archive)
State New, archived
Headers show

Commit Message

Lucas Stach April 2, 2015, 3:30 p.m. UTC
From: Russell King <rmk+kernel@arm.linux.org.uk>

Gem objects compared fences using simple <= tests.  This is
problematical when the fences wrap past (uint32_t)~0.  Resolve this
by using our helpers.

However, this is complicated by the use of '0' to indicate that the
fence has not been set (eg, because we are not writing to an object.)
Carry the access flags into the object and use them when determining
of the object can be retired.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 drivers/staging/etnaviv/etnaviv_drv.h |  2 +-
 drivers/staging/etnaviv/etnaviv_gem.c | 11 +++++++----
 drivers/staging/etnaviv/etnaviv_gem.h |  1 +
 drivers/staging/etnaviv/etnaviv_gpu.c | 16 ++++++++--------
 4 files changed, 17 insertions(+), 13 deletions(-)
diff mbox

Patch

diff --git a/drivers/staging/etnaviv/etnaviv_drv.h b/drivers/staging/etnaviv/etnaviv_drv.h
index 59aa4666d2cc..47aa74b36235 100644
--- a/drivers/staging/etnaviv/etnaviv_drv.h
+++ b/drivers/staging/etnaviv/etnaviv_drv.h
@@ -97,7 +97,7 @@  void *etnaviv_gem_vaddr_locked(struct drm_gem_object *obj);
 void *msm_gem_vaddr(struct drm_gem_object *obj);
 dma_addr_t etnaviv_gem_paddr_locked(struct drm_gem_object *obj);
 void etnaviv_gem_move_to_active(struct drm_gem_object *obj,
-		struct etnaviv_gpu *gpu, bool write, uint32_t fence);
+		struct etnaviv_gpu *gpu, uint32_t access, uint32_t fence);
 void etnaviv_gem_move_to_inactive(struct drm_gem_object *obj);
 int etnaviv_gem_cpu_prep(struct drm_gem_object *obj, uint32_t op,
 		struct timespec *timeout);
diff --git a/drivers/staging/etnaviv/etnaviv_gem.c b/drivers/staging/etnaviv/etnaviv_gem.c
index 4e28c57b2409..2f2bf5619ffd 100644
--- a/drivers/staging/etnaviv/etnaviv_gem.c
+++ b/drivers/staging/etnaviv/etnaviv_gem.c
@@ -405,16 +405,18 @@  dma_addr_t etnaviv_gem_paddr_locked(struct drm_gem_object *obj)
 }
 
 void etnaviv_gem_move_to_active(struct drm_gem_object *obj,
-		struct etnaviv_gpu *gpu, bool write, uint32_t fence)
+	struct etnaviv_gpu *gpu, uint32_t access, uint32_t fence)
 {
 	struct etnaviv_gem_object *etnaviv_obj = to_etnaviv_bo(obj);
 
 	etnaviv_obj->gpu = gpu;
 
-	if (write)
-		etnaviv_obj->write_fence = fence;
-	else
+	if (access & ETNA_SUBMIT_BO_READ)
 		etnaviv_obj->read_fence = fence;
+	if (access & ETNA_SUBMIT_BO_WRITE)
+		etnaviv_obj->write_fence = fence;
+
+	etnaviv_obj->access |= access;
 
 	list_del_init(&etnaviv_obj->mm_list);
 	list_add_tail(&etnaviv_obj->mm_list, &gpu->active_list);
@@ -431,6 +433,7 @@  void etnaviv_gem_move_to_inactive(struct drm_gem_object *obj)
 	etnaviv_obj->gpu = NULL;
 	etnaviv_obj->read_fence = 0;
 	etnaviv_obj->write_fence = 0;
+	etnaviv_obj->access = 0;
 	list_del_init(&etnaviv_obj->mm_list);
 	list_add_tail(&etnaviv_obj->mm_list, &priv->inactive_list);
 }
diff --git a/drivers/staging/etnaviv/etnaviv_gem.h b/drivers/staging/etnaviv/etnaviv_gem.h
index add616338a9f..7844c073ee61 100644
--- a/drivers/staging/etnaviv/etnaviv_gem.h
+++ b/drivers/staging/etnaviv/etnaviv_gem.h
@@ -46,6 +46,7 @@  struct etnaviv_gem_object {
 	 */
 	struct list_head mm_list;
 	struct etnaviv_gpu *gpu;     /* non-null if active */
+	uint32_t access;
 	uint32_t read_fence, write_fence;
 
 	/* Transiently in the process of submit ioctl, objects associated
diff --git a/drivers/staging/etnaviv/etnaviv_gpu.c b/drivers/staging/etnaviv/etnaviv_gpu.c
index 0e230b220f15..4b3d8a004374 100644
--- a/drivers/staging/etnaviv/etnaviv_gpu.c
+++ b/drivers/staging/etnaviv/etnaviv_gpu.c
@@ -845,8 +845,10 @@  static void retire_worker(struct work_struct *work)
 		obj = list_first_entry(&gpu->active_list,
 				struct etnaviv_gem_object, mm_list);
 
-		if ((obj->read_fence <= fence) &&
-				(obj->write_fence <= fence)) {
+		if ((!(obj->access & ETNA_SUBMIT_BO_READ) ||
+		     fence_after_eq(fence, obj->read_fence)) &&
+		    (!(obj->access & ETNA_SUBMIT_BO_WRITE) ||
+		     fence_after_eq(fence, obj->write_fence))) {
 			/* move to inactive: */
 			etnaviv_gem_move_to_inactive(&obj->base);
 			etnaviv_gem_put_iova(&obj->base);
@@ -917,13 +919,11 @@  int etnaviv_gpu_submit(struct etnaviv_gpu *gpu,
 						    &iova);
 		}
 
-		if (submit->bos[i].flags & ETNA_SUBMIT_BO_READ)
+		if (submit->bos[i].flags & (ETNA_SUBMIT_BO_READ |
+					    ETNA_SUBMIT_BO_WRITE))
 			etnaviv_gem_move_to_active(&etnaviv_obj->base, gpu,
-						   false, submit->fence);
-
-		if (submit->bos[i].flags & ETNA_SUBMIT_BO_WRITE)
-			etnaviv_gem_move_to_active(&etnaviv_obj->base, gpu,
-						   true, submit->fence);
+						   submit->bos[i].flags,
+						   submit->fence);
 	}
 	hangcheck_timer_reset(gpu);