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:
parent
2103804389
commit
015a6c37e1
3 changed files with 87 additions and 1 deletions
|
@ -459,6 +459,10 @@ static void kgsl_mem_entry_detach_process(struct kgsl_mem_entry *entry)
|
||||||
|
|
||||||
type = kgsl_memdesc_usermem_type(&entry->memdesc);
|
type = kgsl_memdesc_usermem_type(&entry->memdesc);
|
||||||
entry->priv->stats[type].cur -= entry->memdesc.size;
|
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);
|
spin_unlock(&entry->priv->mem_lock);
|
||||||
|
|
||||||
kgsl_mmu_put_gpuaddr(&entry->memdesc);
|
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)
|
kgsl_gpumem_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
|
||||||
{
|
{
|
||||||
struct kgsl_mem_entry *entry = vma->vm_private_data;
|
struct kgsl_mem_entry *entry = vma->vm_private_data;
|
||||||
|
int ret;
|
||||||
|
|
||||||
if (!entry)
|
if (!entry)
|
||||||
return VM_FAULT_SIGBUS;
|
return VM_FAULT_SIGBUS;
|
||||||
if (!entry->memdesc.ops || !entry->memdesc.ops->vmfault)
|
if (!entry->memdesc.ops || !entry->memdesc.ops->vmfault)
|
||||||
return VM_FAULT_SIGBUS;
|
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
|
static void
|
||||||
|
|
|
@ -420,6 +420,7 @@ struct kgsl_context {
|
||||||
* @kobj: Pointer to a kobj for the sysfs directory for this process
|
* @kobj: Pointer to a kobj for the sysfs directory for this process
|
||||||
* @debug_root: Pointer to the debugfs root for this process
|
* @debug_root: Pointer to the debugfs root for this process
|
||||||
* @stats: Memory allocation statistics 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_idr: sync sources created by this process
|
||||||
* @syncsource_lock: Spinlock to protect the syncsource idr
|
* @syncsource_lock: Spinlock to protect the syncsource idr
|
||||||
* @fd_count: Counter for the number of FDs for this process
|
* @fd_count: Counter for the number of FDs for this process
|
||||||
|
@ -441,6 +442,7 @@ struct kgsl_process_private {
|
||||||
uint64_t cur;
|
uint64_t cur;
|
||||||
uint64_t max;
|
uint64_t max;
|
||||||
} stats[KGSL_MEM_ENTRY_MAX];
|
} stats[KGSL_MEM_ENTRY_MAX];
|
||||||
|
uint64_t gpumem_mapped;
|
||||||
struct idr syncsource_idr;
|
struct idr syncsource_idr;
|
||||||
spinlock_t syncsource_lock;
|
spinlock_t syncsource_lock;
|
||||||
int fd_count;
|
int fd_count;
|
||||||
|
|
|
@ -98,6 +98,75 @@ struct mem_entry_stats {
|
||||||
|
|
||||||
static void kgsl_cma_unlock_secure(struct kgsl_memdesc *memdesc);
|
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
|
* 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))
|
&mem_stats[i].max_attr.attr))
|
||||||
WARN(1, "Couldn't create sysfs file '%s'\n",
|
WARN(1, "Couldn't create sysfs file '%s'\n",
|
||||||
mem_stats[i].max_attr.attr.name);
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue