msm: kgsl: create sysfs entries to expose memory usage

Added sysfs entries to show kgsl memory usage statistics.
gpumem_mapped: kgsl memory mapped in the process address space.
gpumem_unmapped: kgsl allocated memory but not mapped in process.
imported_mem: graphics memory not allocated by the kgsl.

Below is the sysfs path for new entries:
/sys/class/kgsl/kgsl/proc/<pid>/

Change-Id: I08c2014d28dc0ca1e2b54ebf966d00143b303b54
Signed-off-by: Amit Kushwaha <kushwaha@codeaurora.org>
This commit is contained in:
Amit Kushwaha 2018-04-09 20:41:14 +05:30 committed by Timi
parent 2103804389
commit 015a6c37e1
3 changed files with 87 additions and 1 deletions

View file

@ -459,6 +459,10 @@ static void kgsl_mem_entry_detach_process(struct kgsl_mem_entry *entry)
type = kgsl_memdesc_usermem_type(&entry->memdesc);
entry->priv->stats[type].cur -= entry->memdesc.size;
if (type != KGSL_MEM_ENTRY_ION)
entry->priv->gpumem_mapped -= entry->memdesc.mapsize;
spin_unlock(&entry->priv->mem_lock);
kgsl_mmu_put_gpuaddr(&entry->memdesc);
@ -4237,13 +4241,18 @@ static int
kgsl_gpumem_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
{
struct kgsl_mem_entry *entry = vma->vm_private_data;
int ret;
if (!entry)
return VM_FAULT_SIGBUS;
if (!entry->memdesc.ops || !entry->memdesc.ops->vmfault)
return VM_FAULT_SIGBUS;
return entry->memdesc.ops->vmfault(&entry->memdesc, vma, vmf);
ret = entry->memdesc.ops->vmfault(&entry->memdesc, vma, vmf);
if ((ret == 0) || (ret == VM_FAULT_NOPAGE))
entry->priv->gpumem_mapped += PAGE_SIZE;
return ret;
}
static void

View file

@ -420,6 +420,7 @@ struct kgsl_context {
* @kobj: Pointer to a kobj for the sysfs directory for this process
* @debug_root: Pointer to the debugfs root for this process
* @stats: Memory allocation statistics for this process
* @gpumem_mapped: KGSL memory mapped in the process address space
* @syncsource_idr: sync sources created by this process
* @syncsource_lock: Spinlock to protect the syncsource idr
* @fd_count: Counter for the number of FDs for this process
@ -441,6 +442,7 @@ struct kgsl_process_private {
uint64_t cur;
uint64_t max;
} stats[KGSL_MEM_ENTRY_MAX];
uint64_t gpumem_mapped;
struct idr syncsource_idr;
spinlock_t syncsource_lock;
int fd_count;

View file

@ -98,6 +98,75 @@ struct mem_entry_stats {
static void kgsl_cma_unlock_secure(struct kgsl_memdesc *memdesc);
static ssize_t
imported_mem_show(struct kgsl_process_private *priv,
int type, char *buf)
{
struct kgsl_mem_entry *entry;
uint64_t imported_mem = 0;
int id = 0;
spin_lock(&priv->mem_lock);
for (entry = idr_get_next(&priv->mem_idr, &id); entry;
id++, entry = idr_get_next(&priv->mem_idr, &id)) {
int egl_surface_count = 0, egl_image_count = 0;
struct kgsl_memdesc *m;
if (kgsl_mem_entry_get(entry) == 0)
continue;
spin_unlock(&priv->mem_lock);
m = &entry->memdesc;
if (kgsl_memdesc_usermem_type(m) == KGSL_MEM_ENTRY_ION) {
kgsl_get_egl_counts(entry, &egl_surface_count,
&egl_image_count);
if (kgsl_memdesc_get_memtype(m) ==
KGSL_MEMTYPE_EGL_SURFACE)
imported_mem += m->size;
else if (egl_surface_count == 0) {
uint64_t size = m->size;
do_div(size, (egl_image_count ?
egl_image_count : 1));
imported_mem += size;
}
}
kgsl_mem_entry_put(entry);
spin_lock(&priv->mem_lock);
}
spin_unlock(&priv->mem_lock);
return scnprintf(buf, PAGE_SIZE, "%llu\n", imported_mem);
}
static ssize_t
gpumem_mapped_show(struct kgsl_process_private *priv,
int type, char *buf)
{
return scnprintf(buf, PAGE_SIZE, "%llu\n",
priv->gpumem_mapped);
}
static ssize_t
gpumem_unmapped_show(struct kgsl_process_private *priv, int type, char *buf)
{
if (priv->gpumem_mapped > priv->stats[type].cur)
return -EIO;
return scnprintf(buf, PAGE_SIZE, "%llu\n",
priv->stats[type].cur - priv->gpumem_mapped);
}
static struct kgsl_mem_entry_attribute debug_memstats[] = {
__MEM_ENTRY_ATTR(0, imported_mem, imported_mem_show),
__MEM_ENTRY_ATTR(0, gpumem_mapped, gpumem_mapped_show),
__MEM_ENTRY_ATTR(KGSL_MEM_ENTRY_KERNEL, gpumem_unmapped,
gpumem_unmapped_show),
};
/**
* Show the current amount of memory allocated for the given memtype
*/
@ -220,7 +289,13 @@ void kgsl_process_init_sysfs(struct kgsl_device *device,
&mem_stats[i].max_attr.attr))
WARN(1, "Couldn't create sysfs file '%s'\n",
mem_stats[i].max_attr.attr.name);
}
for (i = 0; i < ARRAY_SIZE(debug_memstats); i++) {
if (sysfs_create_file(&private->kobj,
&debug_memstats[i].attr))
WARN(1, "Couldn't create sysfs file '%s'\n",
debug_memstats[i].attr.name);
}
}