mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-13 16:16:15 -04:00
msm: kgsl: Log context information on ENOSPC
There can be maximum of 200 contexts per process and 800 contexts in total. Whenever the limit is exhausted, an -ENOSPC error is returned. With this change, more information is logged: total number of contexts, number of attached and detached contexts for all processes. Change-Id: If714b5375f1d4ce0551fcb8d156ef5129dbafa6c Signed-off-by: Kamal Agrawal <kamaagra@codeaurora.org>
This commit is contained in:
parent
376dd78d67
commit
d9b8457ddd
5 changed files with 71 additions and 14 deletions
|
|
@ -61,3 +61,11 @@ config QCOM_KGSL_IDLE_TIMEOUT
|
|||
long the GPU will go into slumber. A higher value will mean that
|
||||
the GPU is powered ON for a longer duration which will have
|
||||
power costs.
|
||||
|
||||
config QCOM_KGSL_CONTEXT_DEBUG
|
||||
bool "Log kgsl context information for all processes"
|
||||
depends on QCOM_KGSL
|
||||
help
|
||||
When enabled, total number of KGSL contexts, number of attached and
|
||||
detached contexts are dumped into kernel log for all the processes.
|
||||
This gives insight about the number of contexts held by each process.
|
||||
|
|
|
|||
|
|
@ -718,7 +718,7 @@ static void setup_fault_process(struct kgsl_device *device,
|
|||
if (kgsl_mmu_is_perprocess(&device->mmu)) {
|
||||
struct kgsl_process_private *tmp;
|
||||
|
||||
spin_lock(&kgsl_driver.proclist_lock);
|
||||
read_lock(&kgsl_driver.proclist_lock);
|
||||
list_for_each_entry(tmp, &kgsl_driver.process_list, list) {
|
||||
u64 pt_ttbr0;
|
||||
|
||||
|
|
@ -729,7 +729,7 @@ static void setup_fault_process(struct kgsl_device *device,
|
|||
break;
|
||||
}
|
||||
}
|
||||
spin_unlock(&kgsl_driver.proclist_lock);
|
||||
read_unlock(&kgsl_driver.proclist_lock);
|
||||
}
|
||||
done:
|
||||
snapshot->process = process;
|
||||
|
|
|
|||
|
|
@ -500,6 +500,52 @@ static void kgsl_mem_entry_detach_process(struct kgsl_mem_entry *entry)
|
|||
entry->priv = NULL;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_QCOM_KGSL_CONTEXT_DEBUG
|
||||
static void kgsl_context_debug_info(struct kgsl_device *device)
|
||||
{
|
||||
struct kgsl_context *context;
|
||||
struct kgsl_process_private *p;
|
||||
int next;
|
||||
/*
|
||||
* Keep an interval between consecutive logging to avoid
|
||||
* flooding the kernel log
|
||||
*/
|
||||
static DEFINE_RATELIMIT_STATE(_rs, 10 * HZ, 1);
|
||||
|
||||
if (!__ratelimit(&_rs))
|
||||
return;
|
||||
|
||||
dev_info(device->dev, "KGSL active contexts:\n");
|
||||
dev_info(device->dev, "pid process total attached detached\n");
|
||||
|
||||
read_lock(&kgsl_driver.proclist_lock);
|
||||
read_lock(&device->context_lock);
|
||||
|
||||
list_for_each_entry(p, &kgsl_driver.process_list, list) {
|
||||
int total_contexts = 0, num_detached = 0;
|
||||
|
||||
idr_for_each_entry(&device->context_idr, context, next) {
|
||||
if (context->proc_priv == p) {
|
||||
total_contexts++;
|
||||
if (kgsl_context_detached(context))
|
||||
num_detached++;
|
||||
}
|
||||
}
|
||||
|
||||
dev_info(device->dev, "%-8u %-15.15s %-8d %-10d %-10d\n",
|
||||
pid_nr(p->pid), p->comm, total_contexts,
|
||||
total_contexts - num_detached, num_detached);
|
||||
}
|
||||
|
||||
read_unlock(&device->context_lock);
|
||||
read_unlock(&kgsl_driver.proclist_lock);
|
||||
}
|
||||
#else
|
||||
static void kgsl_context_debug_info(struct kgsl_device *device)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* kgsl_context_dump() - dump information about a draw context
|
||||
* @device: KGSL device that owns the context
|
||||
|
|
@ -572,6 +618,7 @@ int kgsl_context_init(struct kgsl_device_private *dev_priv,
|
|||
"Per process context limit reached for pid %u\n",
|
||||
pid_nr(dev_priv->process_priv->pid));
|
||||
spin_unlock(&proc_priv->ctxt_count_lock);
|
||||
kgsl_context_debug_info(device);
|
||||
return -ENOSPC;
|
||||
}
|
||||
|
||||
|
|
@ -591,10 +638,12 @@ int kgsl_context_init(struct kgsl_device_private *dev_priv,
|
|||
}
|
||||
|
||||
if (id < 0) {
|
||||
if (id == -ENOSPC)
|
||||
if (id == -ENOSPC) {
|
||||
dev_warn(device->dev,
|
||||
"cannot have more than %zu contexts due to memstore limitation\n",
|
||||
KGSL_MEMSTORE_MAX);
|
||||
kgsl_context_debug_info(device);
|
||||
}
|
||||
atomic_dec(&proc_priv->ctxt_count);
|
||||
return id;
|
||||
}
|
||||
|
|
@ -818,7 +867,7 @@ struct kgsl_process_private *kgsl_process_private_find(pid_t pid)
|
|||
{
|
||||
struct kgsl_process_private *p, *private = NULL;
|
||||
|
||||
spin_lock(&kgsl_driver.proclist_lock);
|
||||
read_lock(&kgsl_driver.proclist_lock);
|
||||
list_for_each_entry(p, &kgsl_driver.process_list, list) {
|
||||
if (pid_nr(p->pid) == pid) {
|
||||
if (kgsl_process_private_get(p))
|
||||
|
|
@ -826,7 +875,7 @@ struct kgsl_process_private *kgsl_process_private_find(pid_t pid)
|
|||
break;
|
||||
}
|
||||
}
|
||||
spin_unlock(&kgsl_driver.proclist_lock);
|
||||
read_unlock(&kgsl_driver.proclist_lock);
|
||||
|
||||
return private;
|
||||
}
|
||||
|
|
@ -936,9 +985,9 @@ static void kgsl_process_private_close(struct kgsl_device_private *dev_priv,
|
|||
kgsl_mmu_detach_pagetable(private->pagetable);
|
||||
|
||||
/* Remove the process struct from the master list */
|
||||
spin_lock(&kgsl_driver.proclist_lock);
|
||||
write_lock(&kgsl_driver.proclist_lock);
|
||||
list_del(&private->list);
|
||||
spin_unlock(&kgsl_driver.proclist_lock);
|
||||
write_unlock(&kgsl_driver.proclist_lock);
|
||||
|
||||
/*
|
||||
* Unlock the mutex before releasing the memory and the debugfs
|
||||
|
|
@ -974,9 +1023,9 @@ static struct kgsl_process_private *kgsl_process_private_open(
|
|||
kgsl_process_init_sysfs(device, private);
|
||||
kgsl_process_init_debugfs(private);
|
||||
|
||||
spin_lock(&kgsl_driver.proclist_lock);
|
||||
write_lock(&kgsl_driver.proclist_lock);
|
||||
list_add(&private->list, &kgsl_driver.process_list);
|
||||
spin_unlock(&kgsl_driver.proclist_lock);
|
||||
write_unlock(&kgsl_driver.proclist_lock);
|
||||
}
|
||||
|
||||
done:
|
||||
|
|
@ -4057,7 +4106,7 @@ static const struct file_operations kgsl_fops = {
|
|||
|
||||
struct kgsl_driver kgsl_driver = {
|
||||
.process_mutex = __MUTEX_INITIALIZER(kgsl_driver.process_mutex),
|
||||
.proclist_lock = __SPIN_LOCK_UNLOCKED(kgsl_driver.proclist_lock),
|
||||
.proclist_lock = __RW_LOCK_UNLOCKED(kgsl_driver.proclist_lock),
|
||||
.ptlock = __SPIN_LOCK_UNLOCKED(kgsl_driver.ptlock),
|
||||
.devlock = __MUTEX_INITIALIZER(kgsl_driver.devlock),
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -125,7 +125,7 @@ struct kgsl_driver {
|
|||
struct list_head pagetable_list;
|
||||
spinlock_t ptlock;
|
||||
struct mutex process_mutex;
|
||||
spinlock_t proclist_lock;
|
||||
rwlock_t proclist_lock;
|
||||
struct mutex devlock;
|
||||
struct {
|
||||
atomic_long_t vmalloc;
|
||||
|
|
|
|||
|
|
@ -538,7 +538,7 @@ static struct kgsl_process_private *kgsl_iommu_get_process(u64 ptbase)
|
|||
struct kgsl_process_private *p;
|
||||
struct kgsl_iommu_pt *iommu_pt;
|
||||
|
||||
spin_lock(&kgsl_driver.proclist_lock);
|
||||
read_lock(&kgsl_driver.proclist_lock);
|
||||
|
||||
list_for_each_entry(p, &kgsl_driver.process_list, list) {
|
||||
iommu_pt = p->pagetable->priv;
|
||||
|
|
@ -546,12 +546,12 @@ static struct kgsl_process_private *kgsl_iommu_get_process(u64 ptbase)
|
|||
if (!kgsl_process_private_get(p))
|
||||
p = NULL;
|
||||
|
||||
spin_unlock(&kgsl_driver.proclist_lock);
|
||||
read_unlock(&kgsl_driver.proclist_lock);
|
||||
return p;
|
||||
}
|
||||
}
|
||||
|
||||
spin_unlock(&kgsl_driver.proclist_lock);
|
||||
read_unlock(&kgsl_driver.proclist_lock);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue