From 38eedef680c0cd261b5e756dd476a44441beb6f3 Mon Sep 17 00:00:00 2001 From: gkiranku Date: Fri, 3 Jul 2020 14:49:38 +0530 Subject: [PATCH] msm: kgsl: Avoid race of fault handler and recovery There is a possibility of cx gdsc off timeout when stall on fault is enabled. smmu fault handler is blocked on device mutex to keep cx vote and dispatcher trying to turn it off for recovery. To avoid this race condition, return from fault handler when there is contention for device mutex. Change-Id: Ia895152f8cf1ce9bdcfecf256558ba291dabc978 Signed-off-by: gkiranku --- drivers/gpu/msm/kgsl_iommu.c | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/msm/kgsl_iommu.c b/drivers/gpu/msm/kgsl_iommu.c index 83788070b516..56c29edc5565 100644 --- a/drivers/gpu/msm/kgsl_iommu.c +++ b/drivers/gpu/msm/kgsl_iommu.c @@ -608,6 +608,7 @@ static int kgsl_iommu_fault_handler(struct iommu_domain *domain, unsigned int no_page_fault_log = 0; char *fault_type = "unknown"; char *comm = "unknown"; + bool skip_fault = false; struct kgsl_process_private *private; static DEFINE_RATELIMIT_STATE(_rs, @@ -648,14 +649,22 @@ static int kgsl_iommu_fault_handler(struct iommu_domain *domain, * Turn off GPU IRQ so we don't get faults from it too. * The device mutex must be held to change power state */ - mutex_lock(&device->mutex); + if (mutex_trylock(&device->mutex)) { + if (gmu_core_isenabled(device)) + kgsl_pwrctrl_irq(device, KGSL_PWRFLAGS_OFF); + else + kgsl_pwrctrl_change_state(device, + KGSL_STATE_AWARE); - if (gmu_core_isenabled(device)) - kgsl_pwrctrl_irq(device, KGSL_PWRFLAGS_OFF); - else - kgsl_pwrctrl_change_state(device, KGSL_STATE_AWARE); - - mutex_unlock(&device->mutex); + mutex_unlock(&device->mutex); + } else + /* + * skip_fault: If there is contention on device mutex, + * don't attempt to fault on stall. set skip_fault to + * true then return by printing the fault info and + * decrement refcount of private. + */ + skip_fault = true; } contextidr = KGSL_IOMMU_GET_CTX_REG(ctx, KGSL_IOMMU_CTX_CONTEXTIDR); @@ -731,7 +740,7 @@ static int kgsl_iommu_fault_handler(struct iommu_domain *domain, * that has faulted, this is better for debugging as it will stall * the GPU and trigger a snapshot. Return EBUSY error. */ - if (test_bit(KGSL_FT_PAGEFAULT_GPUHALT_ENABLE, + if (!skip_fault && test_bit(KGSL_FT_PAGEFAULT_GPUHALT_ENABLE, &adreno_dev->ft_pf_policy) && (flags & IOMMU_FAULT_TRANSACTION_STALLED)) { uint32_t sctlr_val;