[Openchrome-devel] drm-openchrome: drivers/gpu/drm

James Simmons jsimmons at kemper.freedesktop.org
Sat Mar 2 09:46:01 PST 2013


 drivers/gpu/drm/via/via_drv.c    |    2 +-
 drivers/gpu/drm/via/via_drv.h    |    2 +-
 drivers/gpu/drm/via/via_fence.c  |   39 +++++++++++++++++----------------------
 drivers/gpu/drm/via/via_fence.h  |   14 ++++++++------
 drivers/gpu/drm/via/via_h1_dma.c |   22 ++++++++++++----------
 drivers/gpu/drm/via/via_irq.c    |    4 ++--
 drivers/gpu/drm/via/via_ttm.c    |    2 +-
 7 files changed, 42 insertions(+), 43 deletions(-)

New commits:
commit 4befe383e07b2f694f8f35b50da4d86e75f139e0
Author: James Simmons <jsimmons at infradead.org>
Date:   Sat Mar 2 12:45:49 2013 -0500

    Different verison of the gcc compiler caused memory corruption with the way we allocated the via_fence_engines. The solution was to go with the C99 flexable array standard which resolved these problems.

diff --git a/drivers/gpu/drm/via/via_drv.c b/drivers/gpu/drm/via/via_drv.c
index e6d1e28..c0d100c 100644
--- a/drivers/gpu/drm/via/via_drv.c
+++ b/drivers/gpu/drm/via/via_drv.c
@@ -248,7 +248,7 @@ static int via_driver_unload(struct drm_device *dev)
 	if (drm_core_check_feature(dev, DRIVER_MODESET))
 		via_modeset_fini(dev);
 
-	via_fence_pool_fini(&dev_priv->dma_fences);
+	via_fence_pool_fini(dev_priv->dma_fences);
 
 	drm_vblank_cleanup(dev);
 
diff --git a/drivers/gpu/drm/via/via_drv.h b/drivers/gpu/drm/via/via_drv.h
index 8b21218..70bc2ee 100644
--- a/drivers/gpu/drm/via/via_drv.h
+++ b/drivers/gpu/drm/via/via_drv.h
@@ -135,7 +135,7 @@ struct drm_via_private {
 	int *irq_map;
 
 	/* fence handling */
-	struct via_fence_pool dma_fences;
+	struct via_fence_pool *dma_fences;
 	int desc_size;
 
 	wait_queue_head_t decoder_queue[VIA_NR_XVMC_LOCKS];
diff --git a/drivers/gpu/drm/via/via_fence.c b/drivers/gpu/drm/via/via_fence.c
index 63b07aa..ac521ea 100644
--- a/drivers/gpu/drm/via/via_fence.c
+++ b/drivers/gpu/drm/via/via_fence.c
@@ -187,21 +187,19 @@ via_fence_ref(void *sync_obj)
 /* We assert 30 * sizeof(uint32_t) is enough for emit fence sequence */
 #define FENCE_CMD_BUFFER (256 * sizeof(uint32_t))
 
-int
-via_fence_pool_init(struct via_fence_pool *pool, char *name, int num_engines,
-			int domain, struct drm_device *dev)
+struct via_fence_pool *
+via_fence_pool_init(struct drm_device *dev, char *name, int domain,
+			int num_engines)
 {
-	int size = sizeof(num_engines * sizeof(struct via_fence_engine *));
 	struct drm_via_private *dev_priv = dev->dev_private;
-	struct via_fence_engine *eng;
-	int ret = 0, i;
-	void *par;
-
-	par = kzalloc(size, GFP_KERNEL);
-	if (!par)
-		return -ENOMEM;
+	struct via_fence_pool *pool = NULL;
+	int ret = 0, size, i;
+	void *par = NULL;
 
-	pool->engines = par;
+	size = sizeof(*pool) + num_engines * sizeof(*pool->engines);
+	pool = kzalloc(size, GFP_KERNEL);
+	if (!pool)
+		return ERR_PTR(-ENOMEM);
 
 	/* allocate fence sync bo */
 	ret = ttm_allocate_kernel_buffer(&dev_priv->bdev, PAGE_SIZE, 16,
@@ -231,15 +229,12 @@ via_fence_pool_init(struct via_fence_pool *pool, char *name, int num_engines,
 	}
 
 	for (i = 0; i < pool->num_engines; i++) {
-		eng = kzalloc(sizeof(*eng), GFP_KERNEL);
-		if (!eng)
-			goto out_err;
+		struct via_fence_engine *eng = &pool->engines[i];
 
 		INIT_WORK(&eng->fence_work, via_fence_work);
 		eng->read_seq = par + VIA_FENCE_SIZE * i;
 		eng->pool = pool;
 		eng->index = i;
-		pool->engines[i] = eng;
 	}
 
 	pool->fence_wq = alloc_workqueue(name, 0, 0);
@@ -248,9 +243,11 @@ via_fence_pool_init(struct via_fence_pool *pool, char *name, int num_engines,
 
 	ret = drm_ht_create(&pool->pending, 12);
 out_err:
-	if (ret)
+	if (ret) {
 		via_fence_pool_fini(pool);
-	return ret;
+		pool = ERR_PTR(ret);
+	}
+	return pool;
 }
 
 void
@@ -264,10 +261,8 @@ via_fence_pool_fini(struct via_fence_pool *pool)
 	flush_workqueue(pool->fence_wq);
 	destroy_workqueue(pool->fence_wq);
 
-	for (i = 0; i < pool->num_engines; i++) {
-		cancel_work_sync(&pool->engines[i]->fence_work);
-		kfree(pool->engines[i]);
-	}
+	for (i = 0; i < pool->num_engines; i++)
+		cancel_work_sync(&pool->engines[i].fence_work);
 
 	kfree(pool->cmd_buffer);
 
diff --git a/drivers/gpu/drm/via/via_fence.h b/drivers/gpu/drm/via/via_fence.h
index be3553d..eb4f462 100644
--- a/drivers/gpu/drm/via/via_fence.h
+++ b/drivers/gpu/drm/via/via_fence.h
@@ -36,6 +36,7 @@ struct via_fence_engine {
 	/* virtual address for getting seq value */
 	void *read_seq;
 
+	/* which engine we are */
 	int index;
 };
 
@@ -54,12 +55,12 @@ struct via_fence_pool {
 	struct drm_open_hash pending;
 	struct drm_device *dev;
 
-	struct via_fence_engine **engines;
-	unsigned int num_engines;
-
 	void (*fence_signaled)(struct via_fence_engine *eng);
 	void (*fence_cleanup)(struct via_fence *fence);
 	int (*fence_emit)(struct via_fence *fence);
+
+	unsigned int num_engines;
+	struct via_fence_engine engines[];
 };
 
 struct via_fence {
@@ -87,9 +88,10 @@ extern void *via_fence_ref(void *sync_obj);
 extern struct via_fence *
 via_fence_create_and_emit(struct via_fence_pool *pool, void *data,
 				unsigned int engine);
-extern int
-via_fence_pool_init(struct via_fence_pool *pool, char *name, int num_engines,
-			int domain, struct drm_device *dev);
+
+extern struct via_fence_pool *
+via_fence_pool_init(struct drm_device *dev, char *name, int domain,
+			int num_engines);
 extern void via_fence_pool_fini(struct via_fence_pool *pool);
 
 #endif
diff --git a/drivers/gpu/drm/via/via_h1_dma.c b/drivers/gpu/drm/via/via_h1_dma.c
index d2e8521..45c9e6e 100644
--- a/drivers/gpu/drm/via/via_h1_dma.c
+++ b/drivers/gpu/drm/via/via_h1_dma.c
@@ -191,7 +191,7 @@ via_h1_dma_fence_signaled(struct via_fence_engine *eng)
 static int
 via_h1_dma_emit(struct via_fence *fence)
 {
-	struct via_fence_engine *eng = fence->pool->engines[fence->engine];
+	struct via_fence_engine *eng = &fence->pool->engines[fence->engine];
 	unsigned long offset = VIA_FENCE_SIZE * eng->index;
 	struct drm_via_sg_info *vsg = fence->priv;
 	int ret = 0;
@@ -211,17 +211,19 @@ int
 via_dmablit_init(struct drm_device *dev)
 {
 	struct drm_via_private *dev_priv = dev->dev_private;
-	struct via_fence_pool *pool = &dev_priv->dma_fences;
-	int ret;
+	struct via_fence_pool *pool;
 
 	pci_set_master(dev->pdev);
 
-	ret = via_fence_pool_init(pool, "viadrm_dma", 4, TTM_PL_FLAG_VRAM, dev);
-	if (!ret) {
-		pool->fence_signaled = via_h1_dma_fence_signaled;
-		pool->fence_cleanup = via_free_sg_info;
-		pool->fence_emit = via_h1_dma_emit;
-	}
+	pool = via_fence_pool_init(dev, "viadrm_dma", TTM_PL_FLAG_VRAM, 4);
+	if (IS_ERR(pool))
+		return PTR_ERR(pool);
+
+	pool->fence_signaled = via_h1_dma_fence_signaled;
+	pool->fence_cleanup = via_free_sg_info;
+	pool->fence_emit = via_h1_dma_emit;
+
+	dev_priv->dma_fences = pool;
 	dev_priv->desc_size = sizeof(struct via_h1_header);
-	return ret;
+	return 0;
 }
diff --git a/drivers/gpu/drm/via/via_irq.c b/drivers/gpu/drm/via/via_irq.c
index b0f8ea1..e68245d 100644
--- a/drivers/gpu/drm/via/via_irq.c
+++ b/drivers/gpu/drm/via/via_irq.c
@@ -136,9 +136,9 @@ irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS)
 			ret = IRQ_HANDLED;
 
 			if (dev_priv->irq_map[drm_via_irq_dma0_td] == i)
-				eng = dev_priv->dma_fences.engines[0];
+				eng = &dev_priv->dma_fences->engines[0];
 			else if (dev_priv->irq_map[drm_via_irq_dma1_td] == i)
-				eng = dev_priv->dma_fences.engines[1];
+				eng = &dev_priv->dma_fences->engines[1];
 
 			if (eng)
 				queue_work(eng->pool->fence_wq, &eng->fence_work);
diff --git a/drivers/gpu/drm/via/via_ttm.c b/drivers/gpu/drm/via/via_ttm.c
index 17a4610..5d6aead 100644
--- a/drivers/gpu/drm/via/via_ttm.c
+++ b/drivers/gpu/drm/via/via_ttm.c
@@ -283,7 +283,7 @@ via_move_blit(struct ttm_buffer_object *bo, bool evict, bool no_wait_gpu,
 	if (unlikely(IS_ERR(vsg)))
 		return PTR_ERR(vsg);
 
-	fence = via_fence_create_and_emit(&dev_priv->dma_fences, vsg, 0);
+	fence = via_fence_create_and_emit(dev_priv->dma_fences, vsg, 0);
 	if (unlikely(IS_ERR(fence)))
 		return PTR_ERR(fence);
 	return ttm_bo_move_accel_cleanup(bo, (void *)fence, evict, no_wait_gpu, new_mem);


More information about the Openchrome-devel mailing list