From ea9443b6f8fa426975a428fd7078f11c9c3998a0 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Nicu=C8=99or=20C=C3=AE=C8=9Bu?= Date: Wed, 21 Apr 2021 10:54:20 +0300 Subject: [PATCH] MGS-6197 [#imx-2532] GPU crash when changing gpu_govern mode MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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 --- .../freescale/gc_hal_kernel_platform_imx.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) 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; } -- 2.17.1