Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 38eedef6 authored by gkiranku's avatar gkiranku
Browse files

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: default avatargkiranku <gkiranku@codeaurora.org>
parent a8241c9e
Loading
Loading
Loading
Loading
+18 −9
Original line number Diff line number Diff line
@@ -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);
				kgsl_pwrctrl_change_state(device,
							KGSL_STATE_AWARE);

			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;