summaryrefslogtreecommitdiff
path: root/drivers/gpu/msm
diff options
context:
space:
mode:
authorSushmita Susheelendra <ssusheel@codeaurora.org>2016-01-15 11:42:46 -0700
committerDavid Keitel <dkeitel@codeaurora.org>2016-03-23 21:21:18 -0700
commit6941d8cd4831de963f901e6e8d80819a75304ee2 (patch)
tree581df948dc564388fa6863f1e7ee4a4514a308e4 /drivers/gpu/msm
parent53ae191724fa6d2ed08819c6885d775514104b6c (diff)
msm: kgsl: Use fault context to retrieve process information
Instead of looking up the process by pagetable base and name, use the fault context to extract the pid and other process specific information. This works for both the per-process and global pagetable configurations and also reduces some locking. This also reports the correct pid and task name in the global pagetable configuration. CRs-Fixed: 971753 Change-Id: I9c869527c3d1b2606f3d12234163935d6f5e43a9 Signed-off-by: Sushmita Susheelendra <ssusheel@codeaurora.org>
Diffstat (limited to 'drivers/gpu/msm')
-rw-r--r--drivers/gpu/msm/kgsl_iommu.c38
-rw-r--r--drivers/gpu/msm/kgsl_mmu.c22
-rw-r--r--drivers/gpu/msm/kgsl_mmu.h1
-rw-r--r--drivers/gpu/msm/kgsl_snapshot.c18
4 files changed, 21 insertions, 58 deletions
diff --git a/drivers/gpu/msm/kgsl_iommu.c b/drivers/gpu/msm/kgsl_iommu.c
index 7fc28fa27d41..fb5eba5bbd01 100644
--- a/drivers/gpu/msm/kgsl_iommu.c
+++ b/drivers/gpu/msm/kgsl_iommu.c
@@ -390,11 +390,10 @@ static void _get_entries(struct kgsl_process_private *private,
}
static void _find_mem_entries(struct kgsl_mmu *mmu, uint64_t faultaddr,
- phys_addr_t ptbase, struct _mem_entry *preventry,
- struct _mem_entry *nextentry)
+ struct _mem_entry *preventry, struct _mem_entry *nextentry,
+ struct kgsl_context *context)
{
- struct kgsl_process_private *private = NULL, *p;
- int id = kgsl_mmu_get_ptname_from_ptbase(mmu, ptbase);
+ struct kgsl_process_private *private;
memset(preventry, 0, sizeof(*preventry));
memset(nextentry, 0, sizeof(*nextentry));
@@ -402,22 +401,11 @@ static void _find_mem_entries(struct kgsl_mmu *mmu, uint64_t faultaddr,
/* Set the maximum possible size as an initial value */
nextentry->gpuaddr = (uint64_t) -1;
- mutex_lock(&kgsl_driver.process_mutex);
- list_for_each_entry(p, &kgsl_driver.process_list, list) {
- if (p->pagetable && (p->pagetable->name == id)) {
- if (kgsl_process_private_get(p))
- private = p;
- break;
- }
- }
- mutex_unlock(&kgsl_driver.process_mutex);
-
- if (private != NULL) {
+ if (context) {
+ private = context->proc_priv;
spin_lock(&private->mem_lock);
_get_entries(private, faultaddr, preventry, nextentry);
spin_unlock(&private->mem_lock);
-
- kgsl_process_private_put(private);
}
}
@@ -467,6 +455,7 @@ static int kgsl_iommu_fault_handler(struct iommu_domain *domain,
struct kgsl_iommu_context *ctx;
u64 ptbase;
u32 contextidr;
+ pid_t tid = 0;
pid_t ptname;
struct _mem_entry prev, next;
int write;
@@ -507,9 +496,7 @@ static int kgsl_iommu_fault_handler(struct iommu_domain *domain,
if (context != NULL) {
/* save pagefault timestamp for GFT */
set_bit(KGSL_CONTEXT_PRIV_PAGEFAULT, &context->priv);
-
- kgsl_context_put(context);
- context = NULL;
+ tid = context->tid;
}
ctx->fault = 1;
@@ -535,7 +522,8 @@ static int kgsl_iommu_fault_handler(struct iommu_domain *domain,
ptbase = KGSL_IOMMU_GET_CTX_REG_Q(ctx, TTBR0);
contextidr = KGSL_IOMMU_GET_CTX_REG(ctx, CONTEXTIDR);
- ptname = kgsl_mmu_get_ptname_from_ptbase(mmu, ptbase);
+ ptname = MMU_FEATURE(mmu, KGSL_MMU_GLOBAL_PAGETABLE) ?
+ KGSL_MMU_GLOBAL_PT : tid;
if (test_bit(KGSL_FT_PAGEFAULT_LOG_ONE_PER_PAGE,
&adreno_dev->ft_pf_policy))
@@ -556,8 +544,7 @@ static int kgsl_iommu_fault_handler(struct iommu_domain *domain,
KGSL_LOG_DUMP(ctx->kgsldev,
"---- nearby memory ----\n");
- _find_mem_entries(mmu, addr, ptbase, &prev, &next);
-
+ _find_mem_entries(mmu, addr, &prev, &next, context);
if (prev.gpuaddr)
_print_entry(ctx->kgsldev, &prev);
else
@@ -570,13 +557,11 @@ static int kgsl_iommu_fault_handler(struct iommu_domain *domain,
_print_entry(ctx->kgsldev, &next);
else
KGSL_LOG_DUMP(ctx->kgsldev, "*EMPTY*\n");
-
}
}
trace_kgsl_mmu_pagefault(ctx->kgsldev, addr,
- kgsl_mmu_get_ptname_from_ptbase(mmu, ptbase),
- write ? "write" : "read");
+ ptname, write ? "write" : "read");
/*
* We do not want the h/w to resume fetching data from an iommu
@@ -602,6 +587,7 @@ static int kgsl_iommu_fault_handler(struct iommu_domain *domain,
adreno_dispatcher_schedule(device);
}
+ kgsl_context_put(context);
return ret;
}
diff --git a/drivers/gpu/msm/kgsl_mmu.c b/drivers/gpu/msm/kgsl_mmu.c
index e99104bbc671..61947c8025d7 100644
--- a/drivers/gpu/msm/kgsl_mmu.c
+++ b/drivers/gpu/msm/kgsl_mmu.c
@@ -217,28 +217,6 @@ kgsl_mmu_detach_pagetable(struct kgsl_pagetable *pagetable)
pagetable_remove_sysfs_objects(pagetable);
}
-int
-kgsl_mmu_get_ptname_from_ptbase(struct kgsl_mmu *mmu, u64 pt_base)
-{
- struct kgsl_pagetable *pt;
- int ptid = -1;
-
- if (!MMU_OP_VALID(mmu, mmu_pt_equal))
- return KGSL_MMU_GLOBAL_PT;
-
- spin_lock(&kgsl_driver.ptlock);
- list_for_each_entry(pt, &kgsl_driver.pagetable_list, list) {
- if (mmu->mmu_ops->mmu_pt_equal(mmu, pt, pt_base)) {
- ptid = (int) pt->name;
- break;
- }
- }
- spin_unlock(&kgsl_driver.ptlock);
-
- return ptid;
-}
-EXPORT_SYMBOL(kgsl_mmu_get_ptname_from_ptbase);
-
struct kgsl_pagetable *kgsl_mmu_get_pt_from_ptname(struct kgsl_mmu *mmu,
int ptname)
{
diff --git a/drivers/gpu/msm/kgsl_mmu.h b/drivers/gpu/msm/kgsl_mmu.h
index 90882e4ab8c7..21a3470fcb55 100644
--- a/drivers/gpu/msm/kgsl_mmu.h
+++ b/drivers/gpu/msm/kgsl_mmu.h
@@ -166,7 +166,6 @@ int kgsl_mmu_unmap(struct kgsl_pagetable *pagetable,
void kgsl_mmu_put_gpuaddr(struct kgsl_pagetable *pagetable,
struct kgsl_memdesc *memdesc);
unsigned int kgsl_virtaddr_to_physaddr(void *virtaddr);
-int kgsl_mmu_get_ptname_from_ptbase(struct kgsl_mmu *mmu, u64 pt_base);
unsigned int kgsl_mmu_log_fault_addr(struct kgsl_mmu *mmu,
u64 ttbr0, uint64_t addr);
enum kgsl_mmutype kgsl_mmu_get_mmutype(struct kgsl_device *device);
diff --git a/drivers/gpu/msm/kgsl_snapshot.c b/drivers/gpu/msm/kgsl_snapshot.c
index efaa612fe2c6..69ae2e3fd2d7 100644
--- a/drivers/gpu/msm/kgsl_snapshot.c
+++ b/drivers/gpu/msm/kgsl_snapshot.c
@@ -129,11 +129,10 @@ static size_t snapshot_os(struct kgsl_device *device,
{
struct kgsl_snapshot_linux *header = (struct kgsl_snapshot_linux *)buf;
struct kgsl_pwrctrl *pwr = &device->pwrctrl;
- struct task_struct *task;
- pid_t pid;
int ctxtcount = 0;
size_t size = sizeof(*header);
u64 temp_ptbase;
+ struct kgsl_context *context;
/* Figure out how many active contexts there are - these will
* be appended on the end of the structure */
@@ -176,19 +175,20 @@ static size_t snapshot_os(struct kgsl_device *device,
kgsl_sharedmem_readl(&device->memstore, &header->current_context,
KGSL_MEMSTORE_OFFSET(KGSL_MEMSTORE_GLOBAL, current_context));
+ context = kgsl_context_get(device, header->current_context);
/* Get the current PT base */
temp_ptbase = kgsl_mmu_get_current_ttbr0(&device->mmu);
/* Truncate to 32 bits in case LPAE is used */
header->ptbase = (__u32)temp_ptbase;
/* And the PID for the task leader */
- pid = header->pid = kgsl_mmu_get_ptname_from_ptbase(&device->mmu,
- temp_ptbase);
-
- task = find_task_by_vpid(pid);
-
- if (task)
- get_task_comm(header->comm, task);
+ if (context) {
+ header->pid = context->tid;
+ strlcpy(header->comm, context->proc_priv->comm,
+ sizeof(header->comm));
+ kgsl_context_put(context);
+ context = NULL;
+ }
header->ctxtcount = ctxtcount;