From: Nicușor Cîțu Date: Wed, 21 Apr 2021 07:54:20 +0000 (+0300) Subject: MGS-6197 [#imx-2532] GPU crash when changing gpu_govern mode X-Git-Tag: rel_imx_5.10.35_2.0.0-somdevices.0~82 X-Git-Url: https://git.somdevices.com/?a=commitdiff_plain;h=ea9443b6f8fa426975a428fd7078f11c9c3998a0;p=linux.git MGS-6197 [#imx-2532] GPU crash when changing gpu_govern mode The suspend will acquire the global semaphore, and a later gcvPOWER_ON_AUTO determined by a new commit will wait for global semaphore until a GPU resume (power ON) release the global semaphore, then the gcvPOWER_ON_AUTO will continue to run. But during the stress test, the sequence might change. For example: 1. GPU goes to suspend; if a new commit comes then gcvPOWER_ON_AUTO will wait for global semaphore. 2. GPU goes to resume, a global power ON will release the global semaphore, gcvPOWER_ON_AUTO acquire the global semaphore successfully but will release it by itself because gcvPOWER_ON_AUTO is not a global state and it won't occupy a global semaphore. 3. The next GPU suspend will also acquire the global semaphore successfully. As the GPU suspend and gcvPOWER_ON_AUTO are in two threads, there is a certain probability that suspend is executed first, then gcvPOWER_ON_AUTO, so that the later GPU stall (from suspend) will occur at the same time with new commit abd will cause the GPU hang. Suggested-by: Zhe Pan Signed-off-by: Nicușor Cîțu --- diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/platform/freescale/gc_hal_kernel_platform_imx.c b/drivers/mxc/gpu-viv/hal/os/linux/kernel/platform/freescale/gc_hal_kernel_platform_imx.c index cc2b368e6e13..1d7cbe84fa80 100644 --- a/drivers/mxc/gpu-viv/hal/os/linux/kernel/platform/freescale/gc_hal_kernel_platform_imx.c +++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/platform/freescale/gc_hal_kernel_platform_imx.c @@ -555,6 +555,7 @@ static ssize_t gpu_govern_store(struct device_driver *dev, const char *buf, size int core = gcvCORE_MAJOR; int i; gckGALDEVICE device = platform_get_drvdata(pdevice); + gctBOOL mutex_acquired = gcvFALSE; gctBOOL sem_acquired = gcvFALSE; gceSTATUS status; @@ -576,9 +577,13 @@ static ssize_t gpu_govern_store(struct device_driver *dev, const char *buf, size return count; } + /* Get the device commit mutex. */ + gcmkONERROR(gckOS_AcquireMutex(device->os, device->device->commitMutex, + gcvINFINITE)); + mutex_acquired = gcvTRUE; + /* Acquire the suspend semaphore. */ gcmkONERROR(gckOS_AcquireSemaphore(device->os, device->suspendSemaphore)); - sem_acquired = gcvTRUE; /* Suspend the GPU. */ @@ -618,6 +623,13 @@ OnError: device->suspendSemaphore)); } + /* Release the commit mutex. */ + if (mutex_acquired) + { + gcmkVERIFY_OK(gckOS_ReleaseMutex(device->os, + device->device->commitMutex)); + } + return count; }