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 <jsimm...@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);
_______________________________________________
Openchrome-devel mailing list
Openchrome-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/openchrome-devel

Reply via email to