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

Commit a6f622b1 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: kgsl: Do not suppress page faults due to UCHE overfetch"

parents 84d6b4b0 1615787f
Loading
Loading
Loading
Loading
+0 −48
Original line number Diff line number Diff line
@@ -686,48 +686,6 @@ static void _check_if_freed(struct kgsl_iommu_context *ctx,
	}
}

static bool
kgsl_iommu_uche_overfetch(struct kgsl_process_private *private,
		uint64_t faultaddr)
{
	int id;
	struct kgsl_mem_entry *entry = NULL;

	spin_lock(&private->mem_lock);
	idr_for_each_entry(&private->mem_idr, entry, id) {
		struct kgsl_memdesc *m = &entry->memdesc;

		if ((faultaddr >= (m->gpuaddr + m->size))
				&& (faultaddr < (m->gpuaddr + m->size + 64))) {
			spin_unlock(&private->mem_lock);
			return true;
		}
	}
	spin_unlock(&private->mem_lock);
	return false;
}

/*
 * Read pagefaults where the faulting address lies within the first 64 bytes
 * of a page (UCHE line size is 64 bytes) and the fault page is preceded by a
 * valid allocation are considered likely due to UCHE overfetch and suppressed.
 */

static bool kgsl_iommu_suppress_pagefault(uint64_t faultaddr, int write,
					struct kgsl_context *context)
{
	/*
	 * If there is no context associated with the pagefault then this
	 * could be a fault on a global buffer. We do not suppress faults
	 * on global buffers as they are mainly accessed by the CP bypassing
	 * the UCHE. Also, write pagefaults are never suppressed.
	 */
	if (!context || write)
		return false;

	return kgsl_iommu_uche_overfetch(context->proc_priv, faultaddr);
}

static int kgsl_iommu_fault_handler(struct iommu_domain *domain,
	struct device *dev, unsigned long addr, int flags, void *token)
{
@@ -788,12 +746,6 @@ static int kgsl_iommu_fault_handler(struct iommu_domain *domain,
	else if (flags & IOMMU_FAULT_TRANSACTION_STALLED)
		fault_type = "transaction stalled";

	if (kgsl_iommu_suppress_pagefault(addr, write, context)) {
		iommu->pagefault_suppression_count++;
		kgsl_context_put(context);
		return ret;
	}

	if (context != NULL) {
		/* save pagefault timestamp for GFT */
		set_bit(KGSL_CONTEXT_PRIV_PAGEFAULT, &context->priv);
+0 −3
Original line number Diff line number Diff line
@@ -110,8 +110,6 @@ struct kgsl_iommu_context {
 * @clks: Array of pointers to IOMMU clocks
 * @smmu_info: smmu info used in a5xx preemption
 * @protect: register protection settings for the iommu.
 * @pagefault_suppression_count: Total number of pagefaults
 *				 suppressed since boot.
 */
struct kgsl_iommu {
	struct kgsl_iommu_context ctx[KGSL_IOMMU_CONTEXT_MAX];
@@ -123,7 +121,6 @@ struct kgsl_iommu {
	struct clk *clks[KGSL_IOMMU_MAX_CLKS];
	struct kgsl_memdesc smmu_info;
	struct kgsl_protected_registers protect;
	u32 pagefault_suppression_count;
};

/*