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

Commit 69f45047 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: ksgl: Add debugfs file to show active GPU events"

parents fa5d7f45 2fe7641c
Loading
Loading
Loading
Loading
+5 −3
Original line number Diff line number Diff line
@@ -436,6 +436,7 @@ int kgsl_context_init(struct kgsl_device_private *dev_priv,
{
	int ret = 0, id;
	struct kgsl_device *device = dev_priv->device;
	char name[64];

	idr_preload(GFP_KERNEL);
	write_lock(&device->context_lock);
@@ -474,7 +475,8 @@ int kgsl_context_init(struct kgsl_device_private *dev_priv,
	if (ret)
		goto fail_free_id;

	kgsl_add_event_group(&context->events, context);
	snprintf(name, sizeof(name), "context-%d", id);
	kgsl_add_event_group(&context->events, context, name);

	return 0;
fail_free_id:
@@ -4258,8 +4260,8 @@ int kgsl_device_platform_probe(struct kgsl_device *device)

	device->events_wq = create_workqueue("kgsl-events");

	kgsl_add_event_group(&device->global_events, NULL);
	kgsl_add_event_group(&device->iommu_events, NULL);
	kgsl_add_event_group(&device->global_events, NULL, "global");
	kgsl_add_event_group(&device->iommu_events, NULL, "iommu");

	/* Initalize the snapshot engine */
	kgsl_device_snapshot_init(device);
+3 −1
Original line number Diff line number Diff line
@@ -206,6 +206,7 @@ struct kgsl_event {
 * @events: List of active GPU events
 * @group: Node for the master group list
 * @processed: Last processed timestamp
 * @name: String name for the group (for the debugfs file)
 */
struct kgsl_event_group {
	struct kgsl_context *context;
@@ -213,6 +214,7 @@ struct kgsl_event_group {
	struct list_head events;
	struct list_head group;
	unsigned int processed;
	char name[64];
};

/**
@@ -589,7 +591,7 @@ void kgsl_events_exit(void);

void kgsl_del_event_group(struct kgsl_event_group *group);
void kgsl_add_event_group(struct kgsl_event_group *group,
		struct kgsl_context *context);
		struct kgsl_context *context, const char *name);

void kgsl_cancel_events_timestamp(struct kgsl_device *device,
		struct kgsl_event_group *group, unsigned int timestamp);
+69 −1
Original line number Diff line number Diff line
@@ -14,8 +14,10 @@
#include <linux/slab.h>
#include <linux/list.h>
#include <linux/workqueue.h>
#include <linux/debugfs.h>
#include <kgsl_device.h>

#include "kgsl_debugfs.h"
#include "kgsl_trace.h"

/*
@@ -23,6 +25,7 @@
 * so frequently
 */
static struct kmem_cache *events_cache;
static struct dentry *events_dentry;

static inline void signal_event(struct kgsl_device *device,
		struct kgsl_event *event, int result)
@@ -266,19 +269,74 @@ EXPORT_SYMBOL(kgsl_del_event_group);
 * group: Pointer to the new group to add to the list
 */
void kgsl_add_event_group(struct kgsl_event_group *group,
		struct kgsl_context *context)
		struct kgsl_context *context, const char *name)
{
	spin_lock_init(&group->lock);
	INIT_LIST_HEAD(&group->events);

	group->context = context;

	if (name)
		strlcpy(group->name, name, sizeof(group->name));

	write_lock(&group_lock);
	list_add_tail(&group->group, &group_list);
	write_unlock(&group_lock);
}
EXPORT_SYMBOL(kgsl_add_event_group);

static void events_debugfs_print_group(struct seq_file *s,
		struct kgsl_event_group *group)
{
	struct kgsl_event *event;
	unsigned int retired;

	spin_lock(&group->lock);

	seq_printf(s, "%s: last=%d\n", group->name, group->processed);

	list_for_each_entry(event, &group->events, node) {

		kgsl_readtimestamp(event->device, group->context,
			KGSL_TIMESTAMP_RETIRED, &retired);

		seq_printf(s, "\t%d:%d age=%lu func=%ps [retired=%d]\n",
			group->context ? group->context->id : 0,
			event->timestamp, jiffies  - event->created,
			event->func, retired);
	}
	spin_unlock(&group->lock);
}

static int events_debugfs_print(struct seq_file *s, void *unused)
{
	struct kgsl_event_group *group;

	seq_puts(s, "event groups:\n");
	seq_puts(s, "--------------\n");

	read_lock(&group_lock);
	list_for_each_entry(group, &group_list, group) {
		events_debugfs_print_group(s, group);
		seq_puts(s, "\n");
	}
	read_unlock(&group_lock);

	return 0;
}

static int events_debugfs_open(struct inode *inode, struct file *file)
{
	return single_open(file, events_debugfs_print, NULL);
}

static const struct file_operations events_fops = {
	.open = events_debugfs_open,
	.read = seq_read,
	.llseek = seq_lseek,
	.release = single_release,
};

/**
 * kgsl_events_exit() - Destroy the event kmem cache on module exit
 */
@@ -286,6 +344,8 @@ void kgsl_events_exit(void)
{
	if (events_cache)
		kmem_cache_destroy(events_cache);

	debugfs_remove(events_dentry);
}

/**
@@ -293,5 +353,13 @@ void kgsl_events_exit(void)
 */
void __init kgsl_events_init(void)
{
	struct dentry *debugfs_dir = kgsl_get_debugfs_dir();
	events_cache = KMEM_CACHE(kgsl_event, 0);

	events_dentry = debugfs_create_file("events", 0444, debugfs_dir, NULL,
		&events_fops);

	/* Failure to create a debugfs entry is non fatal */
	if (IS_ERR(events_dentry))
		events_dentry = NULL;
}