From ed72e07dc8e1caf6637f96aaeb9f3360ce5b8116 Mon Sep 17 00:00:00 2001 From: Jeremy Gebben Date: Tue, 25 Sep 2012 10:57:38 -0600 Subject: [PATCH] msm: kgsl: add per-process memory info to debugfs Add a file for each process in debugfs named, kgsl/proc//mem which contains information about all memory allocations the process has made. Change-Id: Ice3f039d92cc1b1cdb5a6192808441ddfdf8abfb Signed-off-by: Jeremy Gebben --- drivers/gpu/msm/kgsl.c | 2 + drivers/gpu/msm/kgsl_debugfs.c | 73 ++++++++++++++++++++++++++++++++++ drivers/gpu/msm/kgsl_debugfs.h | 6 +++ drivers/gpu/msm/kgsl_device.h | 1 + 4 files changed, 82 insertions(+) diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c index 5ba844a2da9..997c0dc2637 100644 --- a/drivers/gpu/msm/kgsl.c +++ b/drivers/gpu/msm/kgsl.c @@ -722,6 +722,7 @@ kgsl_get_process_private(struct kgsl_device_private *cur_dev_priv) list_add(&private->list, &kgsl_driver.process_list); kgsl_process_init_sysfs(private); + kgsl_process_init_debugfs(private); out: mutex_unlock(&kgsl_driver.process_mutex); @@ -744,6 +745,7 @@ kgsl_put_process_private(struct kgsl_device *device, goto unlock; kgsl_process_uninit_sysfs(private); + debugfs_remove_recursive(private->debug_root); list_del(&private->list); diff --git a/drivers/gpu/msm/kgsl_debugfs.c b/drivers/gpu/msm/kgsl_debugfs.c index 545d2b39f37..40ed7cab874 100644 --- a/drivers/gpu/msm/kgsl_debugfs.c +++ b/drivers/gpu/msm/kgsl_debugfs.c @@ -16,6 +16,7 @@ #include "kgsl.h" #include "kgsl_device.h" +#include "kgsl_sharedmem.h" /*default log levels is error for everything*/ #define KGSL_LOG_LEVEL_DEFAULT 3 @@ -23,6 +24,7 @@ struct dentry *kgsl_debugfs_dir; static struct dentry *pm_d_debugfs; +struct dentry *proc_d_debugfs; static int pm_dump_set(void *data, u64 val) { @@ -146,9 +148,80 @@ void kgsl_device_debugfs_init(struct kgsl_device *device) } +static const char * const memtype_strings[] = { + "gpumem", + "pmem", + "ashmem", + "usermap", + "ion", +}; + +static const char *memtype_str(int memtype) +{ + if (memtype < ARRAY_SIZE(memtype_strings)) + return memtype_strings[memtype]; + return "unknown"; +} + +static int process_mem_print(struct seq_file *s, void *unused) +{ + struct kgsl_mem_entry *entry; + struct rb_node *node; + struct kgsl_process_private *private = s->private; + char flags[3]; + char usage[16]; + + spin_lock(&private->mem_lock); + seq_printf(s, "%8s %8s %5s %10s %16s %5s\n", + "gpuaddr", "size", "flags", "type", "usage", "sglen"); + for (node = rb_first(&private->mem_rb); node; node = rb_next(node)) { + struct kgsl_memdesc *m; + + entry = rb_entry(node, struct kgsl_mem_entry, node); + m = &entry->memdesc; + + flags[0] = m->priv & KGSL_MEMFLAGS_GLOBAL ? 'g' : '-'; + flags[1] = m->priv & KGSL_MEMFLAGS_GPUREADONLY ? 'r' : '-'; + flags[2] = '\0'; + + kgsl_get_memory_usage(usage, sizeof(usage), m->priv); + + seq_printf(s, "%08x %8d %5s %10s %16s %5d\n", + m->gpuaddr, m->size, flags, + memtype_str(entry->memtype), usage, m->sglen); + } + spin_unlock(&private->mem_lock); + return 0; +} + +static int process_mem_open(struct inode *inode, struct file *file) +{ + return single_open(file, process_mem_print, inode->i_private); +} + +static const struct file_operations process_mem_fops = { + .open = process_mem_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +void +kgsl_process_init_debugfs(struct kgsl_process_private *private) +{ + unsigned char name[16]; + + snprintf(name, sizeof(name), "%d", private->pid); + + private->debug_root = debugfs_create_dir(name, proc_d_debugfs); + debugfs_create_file("mem", 0400, private->debug_root, private, + &process_mem_fops); +} + void kgsl_core_debugfs_init(void) { kgsl_debugfs_dir = debugfs_create_dir("kgsl", 0); + proc_d_debugfs = debugfs_create_dir("proc", kgsl_debugfs_dir); } void kgsl_core_debugfs_close(void) diff --git a/drivers/gpu/msm/kgsl_debugfs.h b/drivers/gpu/msm/kgsl_debugfs.h index 5e10988076d..898c4e94b8f 100644 --- a/drivers/gpu/msm/kgsl_debugfs.h +++ b/drivers/gpu/msm/kgsl_debugfs.h @@ -15,6 +15,7 @@ #define _KGSL_DEBUGFS_H struct kgsl_device; +struct kgsl_process_private; #ifdef CONFIG_DEBUG_FS void kgsl_core_debugfs_init(void); @@ -28,11 +29,16 @@ static inline struct dentry *kgsl_get_debugfs_dir(void) return kgsl_debugfs_dir; } +int kgsl_process_init_debugfs(struct kgsl_process_private *); #else static inline void kgsl_core_debugfs_init(void) { } static inline void kgsl_device_debugfs_init(struct kgsl_device *device) { } static inline void kgsl_core_debugfs_close(void) { } static inline struct dentry *kgsl_get_debugfs_dir(void) { return NULL; } +static inline int kgsl_process_init_debugfs(struct kgsl_process_private *) +{ + return 0; +} #endif diff --git a/drivers/gpu/msm/kgsl_device.h b/drivers/gpu/msm/kgsl_device.h index dc597f5ffc4..4394118ad22 100644 --- a/drivers/gpu/msm/kgsl_device.h +++ b/drivers/gpu/msm/kgsl_device.h @@ -251,6 +251,7 @@ struct kgsl_process_private { struct kgsl_pagetable *pagetable; struct list_head list; struct kobject kobj; + struct dentry *debug_root; struct { unsigned int cur;