Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4c25b27d authored by Amit Kushwaha's avatar Amit Kushwaha Committed by Gerrit - the friendly Code Review server
Browse files

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: default avatarAmit Kushwaha <kushwaha@codeaurora.org>
Signed-off-by: default avatarArchana Sriram <apsrir@codeaurora.org>
Signed-off-by: default avatarRaghu Ananya Arabolu <rarabolu@codeaurora.org>
parent f6ebc9f7
Loading
Loading
Loading
Loading
+10 −1
Original line number Diff line number Diff line
@@ -501,6 +501,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);
@@ -4206,13 +4210,18 @@ static int
kgsl_gpumem_vm_fault(struct vm_fault *vmf)
{
	struct kgsl_mem_entry *entry = vmf->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, vmf->vma, vmf);
	ret = entry->memdesc.ops->vmfault(&entry->memdesc, vmf->vma, vmf);
	if ((ret == 0) || (ret == VM_FAULT_NOPAGE))
		entry->priv->gpumem_mapped += PAGE_SIZE;

	return ret;
}

static void
+2 −0
Original line number Diff line number Diff line
@@ -432,6 +432,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
@@ -453,6 +454,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;
+76 −0
Original line number Diff line number Diff line
@@ -88,6 +88,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
 */
@@ -211,6 +280,13 @@ void kgsl_process_init_sysfs(struct kgsl_device *device,
				"Unable to create sysfs files for process %d\n",
				private->pid);
	}

	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);
	}
}

static ssize_t memstat_show(struct device *dev,