MGS-6197 [#imx-2532] GPU crash when changing gpu_govern mode
authorNicușor Cîțu <nicusor.citu@nxp.com>
Wed, 21 Apr 2021 14:59:27 +0000 (17:59 +0300)
committerNicușor Cîțu <nicusor.citu@nxp.com>
Wed, 12 May 2021 11:27:26 +0000 (14:27 +0300)
Move the suspend semaphore inside the suspend/resume routines.

Signed-off-by: Nicușor Cîțu <nicusor.citu@nxp.com>
drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.c
drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.h
drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_driver.c
drivers/mxc/gpu-viv/hal/os/linux/kernel/platform/freescale/gc_hal_kernel_platform_imx.c

index 710a892..3e91767 100644 (file)
@@ -2968,6 +2968,10 @@ gckGALDEVICE_Suspend(
 
     gcmkHEADER_ARG("Device=%p", Device);
 
+    /* Acquire the suspend semaphore. */
+    gcmkONERROR(gckOS_AcquireSemaphore(Device->os, Device->suspendSemaphore));
+    Device->suspendSemaphoreAcquired = gcvTRUE;
+
     for (i = 0; i < gcdMAX_GPU_COUNT; i++)
     {
         if (Device->kernels[i] == gcvNULL)
@@ -3044,6 +3048,14 @@ OnError:
         Device->statesStored[i] = gcvPOWER_INVALID;
     }
 
+    /* Release the suspend semaphore. */
+    if (Device->suspendSemaphoreAcquired)
+    {
+        gcmkVERIFY_OK(gckOS_ReleaseSemaphore(Device->os,
+                Device->suspendSemaphore));
+        Device->suspendSemaphoreAcquired = gcvFALSE;
+    }
+
     gcmkFOOTER();
     return status;
 }
@@ -3106,12 +3118,12 @@ gckGALDEVICE_Resume(
 #if gcdENABLE_VG
         if (i == gcvCORE_VG)
         {
-            gcmkERR_RETURN(gckVGHARDWARE_SetPowerState(hardware, gcvPOWER_ON));
+            gcmkONERROR(gckVGHARDWARE_SetPowerState(hardware, gcvPOWER_ON));
         }
         else
 #endif
         {
-            gcmkERR_RETURN(gckHARDWARE_SetPowerState(hardware, gcvPOWER_ON));
+            gcmkONERROR(gckHARDWARE_SetPowerState(hardware, gcvPOWER_ON));
         }
 
         /* Convert global state to corresponding internal state. */
@@ -3138,18 +3150,27 @@ gckGALDEVICE_Resume(
 #if gcdENABLE_VG
         if (i == gcvCORE_VG)
         {
-            gcmkERR_RETURN(gckVGHARDWARE_SetPowerState(hardware, state));
+            gcmkONERROR(gckVGHARDWARE_SetPowerState(hardware, state));
         }
         else
 #endif
         {
-            gcmkERR_RETURN(gckHARDWARE_SetPowerState(hardware, state));
+            gcmkONERROR(gckHARDWARE_SetPowerState(hardware, state));
         }
 
         /* Reset stored state. */
         Device->statesStored[i] = gcvPOWER_INVALID;
     }
 
+OnError:
+    /* Release the suspend semaphore. */
+    if (Device->suspendSemaphoreAcquired)
+    {
+        gcmkVERIFY_OK(gckOS_ReleaseSemaphore(Device->os,
+                Device->suspendSemaphore));
+        Device->suspendSemaphoreAcquired = gcvFALSE;
+    }
+
     gcmkFOOTER();
     return status;
 }
index 45e70fa..422bfd9 100644 (file)
@@ -132,6 +132,7 @@ typedef struct _gckGALDEVICE
     /* States before suspend. */
     gceCHIPPOWERSTATE   statesStored[gcdMAX_GPU_COUNT];
     gctPOINTER          suspendSemaphore;
+    gctBOOL             suspendSemaphoreAcquired;
 
     gcsDEBUGFS_DIR      debugfsDir;
 
index 338ebb5..0e005e0 100644 (file)
@@ -1402,7 +1402,6 @@ static int gpu_remove(struct platform_device *pdev)
 static int gpu_suspend(struct platform_device *dev, pm_message_t state)
 {
     gceSTATUS status;
-    gctBOOL sem_acquired = gcvFALSE;
     gckGALDEVICE device = platform_get_drvdata(dev);
 
     if (!device)
@@ -1410,26 +1409,13 @@ static int gpu_suspend(struct platform_device *dev, pm_message_t state)
         return -1;
     }
 
-    /* Acquire the suspend management semaphore. */
-    gcmkONERROR(gckOS_AcquireSemaphore(device->os,
-            device->suspendSemaphore));
-
-    sem_acquired = gcvTRUE;
-
     /* Power off the GPU. */
-    gcmkONERROR(gckGALDEVICE_Suspend(device, gcvPOWER_OFF));
-
-    return 0;
+    status = gckGALDEVICE_Suspend(device, gcvPOWER_OFF);
 
-OnError:
-    /* Release the suspend semaphore. */
-    if (sem_acquired)
-    {
-        gcmkVERIFY_OK(gckOS_ReleaseSemaphore(device->os,
-                device->suspendSemaphore));
-    }
+    if (gcmIS_ERROR(status))
+        return -1;
 
-    return -1;
+    return 0;
 }
 
 static int gpu_resume(struct platform_device *dev)
@@ -1445,9 +1431,6 @@ static int gpu_resume(struct platform_device *dev)
     /* Resume GPU to previous state. */
     status = gckGALDEVICE_Resume(device);
 
-    /* Release the suspend semaphore. */
-    gcmkVERIFY_OK(gckOS_ReleaseSemaphore(device->os, device->suspendSemaphore));
-
     if (gcmIS_ERROR(status))
         return -1;
 
index 1d7cbe8..f093069 100644 (file)
@@ -556,7 +556,6 @@ static ssize_t gpu_govern_store(struct device_driver *dev, const char *buf, size
     int i;
     gckGALDEVICE device = platform_get_drvdata(pdevice);
     gctBOOL mutex_acquired = gcvFALSE;
-    gctBOOL sem_acquired = gcvFALSE;
     gceSTATUS status;
 
     if (!device)
@@ -582,10 +581,6 @@ static ssize_t gpu_govern_store(struct device_driver *dev, const char *buf, size
             gcvINFINITE));
     mutex_acquired = gcvTRUE;
 
-    /* Acquire the suspend semaphore. */
-    gcmkONERROR(gckOS_AcquireSemaphore(device->os, device->suspendSemaphore));
-    sem_acquired = gcvTRUE;
-
     /* Suspend the GPU. */
     gcmkONERROR(gckGALDEVICE_Suspend(device, gcvPOWER_SUSPEND));
 
@@ -616,13 +611,6 @@ static ssize_t gpu_govern_store(struct device_driver *dev, const char *buf, size
     gcmVERIFY_OK(gckGALDEVICE_Resume(device));
 
 OnError:
-    /* Release the suspend semaphore. */
-    if (sem_acquired)
-    {
-        gcmkVERIFY_OK(gckOS_ReleaseSemaphore(device->os,
-                device->suspendSemaphore));
-    }
-
     /* Release the commit mutex. */
     if (mutex_acquired)
     {