mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-09 13:49:24 -04:00
Merge "msm: kgsl: Expose memtype stats through sysfs"
This commit is contained in:
commit
8336f3edcd
2 changed files with 116 additions and 31 deletions
|
|
@ -448,6 +448,7 @@ struct kgsl_process_private {
|
|||
struct kgsl_pagetable *pagetable;
|
||||
struct list_head list;
|
||||
struct kobject kobj;
|
||||
struct kobject kobj_memtype;
|
||||
struct dentry *debug_root;
|
||||
struct {
|
||||
atomic64_t cur;
|
||||
|
|
|
|||
|
|
@ -24,6 +24,41 @@ static bool sharedmem_noretry_flag;
|
|||
|
||||
static DEFINE_MUTEX(kernel_map_global_lock);
|
||||
|
||||
#define MEMTYPE(_type, _name) { \
|
||||
.type = _type, \
|
||||
.attr = { .name = _name, .mode = 0444 } \
|
||||
}
|
||||
|
||||
struct kgsl_memtype {
|
||||
unsigned int type;
|
||||
struct attribute attr;
|
||||
};
|
||||
|
||||
static const struct kgsl_memtype memtypes[] = {
|
||||
MEMTYPE(KGSL_MEMTYPE_OBJECTANY, "any(0)"),
|
||||
MEMTYPE(KGSL_MEMTYPE_FRAMEBUFFER, "framebuffer"),
|
||||
MEMTYPE(KGSL_MEMTYPE_RENDERBUFFER, "renderbuffer"),
|
||||
MEMTYPE(KGSL_MEMTYPE_ARRAYBUFFER, "arraybuffer"),
|
||||
MEMTYPE(KGSL_MEMTYPE_ELEMENTARRAYBUFFER, "elementarraybuffer"),
|
||||
MEMTYPE(KGSL_MEMTYPE_VERTEXARRAYBUFFER, "vertexarraybuffer"),
|
||||
MEMTYPE(KGSL_MEMTYPE_TEXTURE, "texture"),
|
||||
MEMTYPE(KGSL_MEMTYPE_SURFACE, "surface"),
|
||||
MEMTYPE(KGSL_MEMTYPE_EGL_SURFACE, "egl_surface"),
|
||||
MEMTYPE(KGSL_MEMTYPE_GL, "gl"),
|
||||
MEMTYPE(KGSL_MEMTYPE_CL, "cl"),
|
||||
MEMTYPE(KGSL_MEMTYPE_CL_BUFFER_MAP, "cl_buffer_map"),
|
||||
MEMTYPE(KGSL_MEMTYPE_CL_BUFFER_NOMAP, "cl_buffer_nomap"),
|
||||
MEMTYPE(KGSL_MEMTYPE_CL_IMAGE_MAP, "cl_image_map"),
|
||||
MEMTYPE(KGSL_MEMTYPE_CL_IMAGE_NOMAP, "cl_image_nomap"),
|
||||
MEMTYPE(KGSL_MEMTYPE_CL_KERNEL_STACK, "cl_kernel_stack"),
|
||||
MEMTYPE(KGSL_MEMTYPE_COMMAND, "command"),
|
||||
MEMTYPE(KGSL_MEMTYPE_2D, "2d"),
|
||||
MEMTYPE(KGSL_MEMTYPE_EGL_IMAGE, "egl_image"),
|
||||
MEMTYPE(KGSL_MEMTYPE_EGL_SHADOW, "egl_shadow"),
|
||||
MEMTYPE(KGSL_MEMTYPE_MULTISAMPLE, "egl_multisample"),
|
||||
MEMTYPE(KGSL_MEMTYPE_KERNEL, "kernel"),
|
||||
};
|
||||
|
||||
/* An attribute for showing per-process memory statistics */
|
||||
struct kgsl_mem_entry_attribute {
|
||||
struct attribute attr;
|
||||
|
|
@ -183,6 +218,49 @@ static ssize_t mem_entry_sysfs_show(struct kobject *kobj,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static ssize_t memtype_sysfs_show(struct kobject *kobj,
|
||||
struct attribute *attr, char *buf)
|
||||
{
|
||||
struct kgsl_process_private *priv;
|
||||
struct kgsl_memtype *memtype;
|
||||
struct kgsl_mem_entry *entry;
|
||||
u64 size = 0;
|
||||
int id = 0;
|
||||
|
||||
/*
|
||||
* kgsl_process_init_sysfs takes a refcount to the process_private,
|
||||
* which is put when the kobj is released. This implies that priv will
|
||||
* not be freed until this function completes, and no further locking
|
||||
* is needed.
|
||||
*/
|
||||
priv = container_of(kobj, struct kgsl_process_private, kobj_memtype);
|
||||
memtype = container_of(attr, struct kgsl_memtype, attr);
|
||||
|
||||
spin_lock(&priv->mem_lock);
|
||||
for (entry = idr_get_next(&priv->mem_idr, &id); entry;
|
||||
id++, entry = idr_get_next(&priv->mem_idr, &id)) {
|
||||
struct kgsl_memdesc *memdesc;
|
||||
unsigned int type;
|
||||
|
||||
if (kgsl_mem_entry_get(entry) == 0)
|
||||
continue;
|
||||
spin_unlock(&priv->mem_lock);
|
||||
|
||||
memdesc = &entry->memdesc;
|
||||
type = MEMFLAGS(memdesc->flags, KGSL_MEMTYPE_MASK,
|
||||
KGSL_MEMTYPE_SHIFT);
|
||||
|
||||
if (type == memtype->type)
|
||||
size += memdesc->size;
|
||||
|
||||
kgsl_mem_entry_put(entry);
|
||||
spin_lock(&priv->mem_lock);
|
||||
}
|
||||
spin_unlock(&priv->mem_lock);
|
||||
|
||||
return scnprintf(buf, PAGE_SIZE, "%llu\n", size);
|
||||
}
|
||||
|
||||
static void mem_entry_release(struct kobject *kobj)
|
||||
{
|
||||
struct kgsl_process_private *priv;
|
||||
|
|
@ -201,6 +279,14 @@ static struct kobj_type ktype_mem_entry = {
|
|||
.release = &mem_entry_release,
|
||||
};
|
||||
|
||||
static const struct sysfs_ops memtype_sysfs_ops = {
|
||||
.show = memtype_sysfs_show,
|
||||
};
|
||||
|
||||
static struct kobj_type ktype_memtype = {
|
||||
.sysfs_ops = &memtype_sysfs_ops,
|
||||
};
|
||||
|
||||
static struct mem_entry_stats mem_stats[] = {
|
||||
MEM_ENTRY_STAT(KGSL_MEM_ENTRY_KERNEL, kernel),
|
||||
MEM_ENTRY_STAT(KGSL_MEM_ENTRY_USER, user),
|
||||
|
|
@ -220,6 +306,11 @@ kgsl_process_uninit_sysfs(struct kgsl_process_private *private)
|
|||
&mem_stats[i].max_attr.attr);
|
||||
}
|
||||
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(memtypes); i++)
|
||||
sysfs_remove_file(&private->kobj_memtype, &memtypes[i].attr);
|
||||
|
||||
kobject_put(&private->kobj_memtype);
|
||||
kobject_put(&private->kobj);
|
||||
}
|
||||
|
||||
|
|
@ -268,6 +359,21 @@ void kgsl_process_init_sysfs(struct kgsl_device *device,
|
|||
WARN(1, "Couldn't create sysfs file '%s'\n",
|
||||
debug_memstats[i].attr.name);
|
||||
}
|
||||
|
||||
if (kobject_init_and_add(&private->kobj_memtype, &ktype_memtype,
|
||||
&private->kobj, "memtype")) {
|
||||
dev_err(device->dev,
|
||||
"Unable to add memtype sysfs for process %d\n",
|
||||
pid_nr(private->pid));
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(memtypes); i++) {
|
||||
if (sysfs_create_file(&private->kobj_memtype,
|
||||
&memtypes[i].attr))
|
||||
WARN(1, "Couldn't create sysfs file '%s'\n",
|
||||
memtypes[i].attr.name);
|
||||
}
|
||||
}
|
||||
|
||||
static ssize_t memstat_show(struct device *dev,
|
||||
|
|
@ -790,42 +896,20 @@ kgsl_sharedmem_writeq(const struct kgsl_memdesc *memdesc,
|
|||
wmb();
|
||||
}
|
||||
|
||||
static const char * const memtype_str[] = {
|
||||
[KGSL_MEMTYPE_OBJECTANY] = "any(0)",
|
||||
[KGSL_MEMTYPE_FRAMEBUFFER] = "framebuffer",
|
||||
[KGSL_MEMTYPE_RENDERBUFFER] = "renderbuffer",
|
||||
[KGSL_MEMTYPE_ARRAYBUFFER] = "arraybuffer",
|
||||
[KGSL_MEMTYPE_ELEMENTARRAYBUFFER] = "elementarraybuffer",
|
||||
[KGSL_MEMTYPE_VERTEXARRAYBUFFER] = "vertexarraybuffer",
|
||||
[KGSL_MEMTYPE_TEXTURE] = "texture",
|
||||
[KGSL_MEMTYPE_SURFACE] = "surface",
|
||||
[KGSL_MEMTYPE_EGL_SURFACE] = "egl_surface",
|
||||
[KGSL_MEMTYPE_GL] = "gl",
|
||||
[KGSL_MEMTYPE_CL] = "cl",
|
||||
[KGSL_MEMTYPE_CL_BUFFER_MAP] = "cl_buffer_map",
|
||||
[KGSL_MEMTYPE_CL_BUFFER_NOMAP] = "cl_buffer_nomap",
|
||||
[KGSL_MEMTYPE_CL_IMAGE_MAP] = "cl_image_map",
|
||||
[KGSL_MEMTYPE_CL_IMAGE_NOMAP] = "cl_image_nomap",
|
||||
[KGSL_MEMTYPE_CL_KERNEL_STACK] = "cl_kernel_stack",
|
||||
[KGSL_MEMTYPE_COMMAND] = "command",
|
||||
[KGSL_MEMTYPE_2D] = "2d",
|
||||
[KGSL_MEMTYPE_EGL_IMAGE] = "egl_image",
|
||||
[KGSL_MEMTYPE_EGL_SHADOW] = "egl_shadow",
|
||||
[KGSL_MEMTYPE_MULTISAMPLE] = "egl_multisample",
|
||||
/* KGSL_MEMTYPE_KERNEL handled below, to avoid huge array */
|
||||
};
|
||||
|
||||
void kgsl_get_memory_usage(char *name, size_t name_size, uint64_t memflags)
|
||||
{
|
||||
unsigned int type = MEMFLAGS(memflags, KGSL_MEMTYPE_MASK,
|
||||
KGSL_MEMTYPE_SHIFT);
|
||||
int i;
|
||||
|
||||
if (type == KGSL_MEMTYPE_KERNEL)
|
||||
strlcpy(name, "kernel", name_size);
|
||||
else if (type < ARRAY_SIZE(memtype_str) && memtype_str[type] != NULL)
|
||||
strlcpy(name, memtype_str[type], name_size);
|
||||
else
|
||||
snprintf(name, name_size, "VK/others(%3d)", type);
|
||||
for (i = 0; i < ARRAY_SIZE(memtypes); i++) {
|
||||
if (memtypes[i].type == type) {
|
||||
strlcpy(name, memtypes[i].attr.name, name_size);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
snprintf(name, name_size, "VK/others(%3d)", type);
|
||||
}
|
||||
|
||||
int kgsl_memdesc_sg_dma(struct kgsl_memdesc *memdesc,
|
||||
|
|
|
|||
Loading…
Reference in a new issue