From: Russell King <rmk+ker...@arm.linux.org.uk>

Tracking the current context on a system wide level is incorrect: if the
context for one GPU core changes, the context does not change on other
GPU cores.  Make the context tracking a per-GPU thing.

Signed-off-by: Russell King <rmk+kernel at arm.linux.org.uk>
---
 drivers/staging/etnaviv/etnaviv_drv.c | 9 +++++++--
 drivers/staging/etnaviv/etnaviv_drv.h | 1 -
 drivers/staging/etnaviv/etnaviv_gpu.c | 5 ++---
 drivers/staging/etnaviv/etnaviv_gpu.h | 1 +
 4 files changed, 10 insertions(+), 6 deletions(-)

diff --git a/drivers/staging/etnaviv/etnaviv_drv.c 
b/drivers/staging/etnaviv/etnaviv_drv.c
index a87de2e79fee..7ec4b224b589 100644
--- a/drivers/staging/etnaviv/etnaviv_drv.c
+++ b/drivers/staging/etnaviv/etnaviv_drv.c
@@ -173,10 +173,15 @@ static void etnaviv_preclose(struct drm_device *dev, 
struct drm_file *file)
 {
        struct etnaviv_drm_private *priv = dev->dev_private;
        struct etnaviv_file_private *ctx = file->driver_priv;
+       unsigned int i;

        mutex_lock(&dev->struct_mutex);
-       if (ctx == priv->lastctx)
-               priv->lastctx = NULL;
+       for (i = 0; i < ETNA_MAX_PIPES; i++) {
+               struct etnaviv_gpu *gpu = priv->gpu[i];
+
+               if (gpu && gpu->lastctx == ctx)
+                       gpu->lastctx = NULL;
+       }
        mutex_unlock(&dev->struct_mutex);

        kfree(ctx);
diff --git a/drivers/staging/etnaviv/etnaviv_drv.h 
b/drivers/staging/etnaviv/etnaviv_drv.h
index 37992342bbf0..f7aff4b2562c 100644
--- a/drivers/staging/etnaviv/etnaviv_drv.h
+++ b/drivers/staging/etnaviv/etnaviv_drv.h
@@ -52,7 +52,6 @@ struct etnaviv_file_private {
 struct etnaviv_drm_private {
        int num_gpus;
        struct etnaviv_gpu *gpu[ETNA_MAX_PIPES];
-       struct etnaviv_file_private *lastctx;

        uint32_t next_fence, completed_fence;
        wait_queue_head_t fence_event;
diff --git a/drivers/staging/etnaviv/etnaviv_gpu.c 
b/drivers/staging/etnaviv/etnaviv_gpu.c
index 9f4e99855517..2dbf25121a07 100644
--- a/drivers/staging/etnaviv/etnaviv_gpu.c
+++ b/drivers/staging/etnaviv/etnaviv_gpu.c
@@ -916,15 +916,14 @@ int etnaviv_gpu_submit(struct etnaviv_gpu *gpu,

        gpu->submitted_fence = submit->fence;

-       if (priv->lastctx != ctx) {
+       if (gpu->lastctx != ctx) {
                gpu->mmu->need_flush = true;
                gpu->switch_context = true;
+               gpu->lastctx = ctx;
        }

        etnaviv_buffer_queue(gpu, event, submit);

-       priv->lastctx = ctx;
-
        for (i = 0; i < submit->nr_bos; i++) {
                struct etnaviv_gem_object *etnaviv_obj = submit->bos[i].obj;

diff --git a/drivers/staging/etnaviv/etnaviv_gpu.h 
b/drivers/staging/etnaviv/etnaviv_gpu.h
index 6b4f241c0ca6..67f6097ba576 100644
--- a/drivers/staging/etnaviv/etnaviv_gpu.h
+++ b/drivers/staging/etnaviv/etnaviv_gpu.h
@@ -87,6 +87,7 @@ struct etnaviv_gpu {
        struct drm_device *drm;
        struct device *dev;
        struct etnaviv_chip_identity identity;
+       struct etnaviv_file_private *lastctx;
        bool switch_context;

        /* 'ring'-buffer: */
-- 
2.5.1

Reply via email to