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

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

Merge "msm: kgsl: Get names of all fences"

parents 76b53633 0ebbdcdc
Loading
Loading
Loading
Loading
+6 −3
Original line number Diff line number Diff line
/* Copyright (c) 2002,2008-2017, The Linux Foundation. All rights reserved.
/* Copyright (c) 2002,2008-2018, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -137,8 +137,11 @@ static void sync_event_print(struct seq_file *s,
		break;
	}
	case KGSL_CMD_SYNCPOINT_TYPE_FENCE: {
		seq_printf(s, "sync: [%pK] %s", sync_event->handle,
				sync_event->fence_name);
		int i;

		for (i = 0; i < sync_event->info.num_fences; i++)
			seq_printf(s, "sync: %s",
				sync_event->info.fences[i].name);
		break;
	}
	default:
+1 −1
Original line number Diff line number Diff line
@@ -2018,7 +2018,7 @@ static long gpuobj_free_on_fence(struct kgsl_device_private *dev_priv,
	}

	handle = kgsl_sync_fence_async_wait(event.fd,
		gpuobj_free_fence_func, entry, NULL, 0);
		gpuobj_free_fence_func, entry, NULL);

	if (IS_ERR(handle)) {
		kgsl_mem_entry_unset_pend(entry);
+37 −11
Original line number Diff line number Diff line
/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -43,6 +43,17 @@
static struct kmem_cache *memobjs_cache;
static struct kmem_cache *sparseobjs_cache;

static void free_fence_names(struct kgsl_drawobj_sync *syncobj)
{
	unsigned int i;

	for (i = 0; i < syncobj->numsyncs; i++) {
		struct kgsl_drawobj_sync_event *event = &syncobj->synclist[i];

		if (event->type == KGSL_CMD_SYNCPOINT_TYPE_FENCE)
			kfree(event->info.fences);
	}
}

void kgsl_drawobj_destroy_object(struct kref *kref)
{
@@ -55,6 +66,7 @@ void kgsl_drawobj_destroy_object(struct kref *kref)
	switch (drawobj->type) {
	case SYNCOBJ_TYPE:
		syncobj = SYNCOBJ(drawobj);
		free_fence_names(syncobj);
		kfree(syncobj->synclist);
		kfree(syncobj);
		break;
@@ -94,13 +106,18 @@ void kgsl_dump_syncpoints(struct kgsl_device *device,
				retired);
			break;
		}
		case KGSL_CMD_SYNCPOINT_TYPE_FENCE:
			dev_err(device->dev, "  fence: %s\n",
					event->fence_name);
		case KGSL_CMD_SYNCPOINT_TYPE_FENCE: {
			int j;
			struct event_fence_info *info = &event->info;

			for (j = 0; j < info->num_fences; j++)
				dev_err(device->dev, "[%d]  fence: %s\n",
					i, info->fences[j].name);
			break;
		}
		}
	}
}

static void syncobj_timer(unsigned long data)
{
@@ -146,12 +163,17 @@ static void syncobj_timer(unsigned long data)
			dev_err(device->dev, "       [%d] TIMESTAMP %d:%d\n",
				i, event->context->id, event->timestamp);
			break;
		case KGSL_CMD_SYNCPOINT_TYPE_FENCE:
		case KGSL_CMD_SYNCPOINT_TYPE_FENCE: {
			int j;
			struct event_fence_info *info = &event->info;

			for (j = 0; j < info->num_fences; j++)
				dev_err(device->dev, "       [%d] FENCE %s\n",
					i, event->fence_name);
					i, info->fences[j].name);
			break;
		}
		}
	}

	kgsl_drawobj_put(drawobj);
	dev_err(device->dev, "--gpu syncpoint deadlock print end--\n");
@@ -332,8 +354,11 @@ EXPORT_SYMBOL(kgsl_drawobj_destroy);
static bool drawobj_sync_fence_func(void *priv)
{
	struct kgsl_drawobj_sync_event *event = priv;
	int i;

	trace_syncpoint_fence_expire(event->syncobj, event->fence_name);
	for (i = 0; i < event->info.num_fences; i++)
		trace_syncpoint_fence_expire(event->syncobj,
			event->info.fences[i].name);

	/*
	 * Only call kgsl_drawobj_put() if it's not marked for cancellation
@@ -359,7 +384,7 @@ static int drawobj_add_sync_fence(struct kgsl_device *device,
	struct kgsl_cmd_syncpoint_fence *sync = priv;
	struct kgsl_drawobj *drawobj = DRAWOBJ(syncobj);
	struct kgsl_drawobj_sync_event *event;
	unsigned int id;
	unsigned int id, i;

	kref_get(&drawobj->refcount);

@@ -377,7 +402,7 @@ static int drawobj_add_sync_fence(struct kgsl_device *device,

	event->handle = kgsl_sync_fence_async_wait(sync->fd,
				drawobj_sync_fence_func, event,
				event->fence_name, sizeof(event->fence_name));
				&event->info);

	if (IS_ERR_OR_NULL(event->handle)) {
		int ret = PTR_ERR(event->handle);
@@ -397,7 +422,8 @@ static int drawobj_add_sync_fence(struct kgsl_device *device,
		return ret;
	}

	trace_syncpoint_fence(syncobj, event->fence_name);
	for (i = 0; i < event->info.num_fences; i++)
		trace_syncpoint_fence(syncobj, event->info.fences[i].name);

	return 0;
}
+12 −3
Original line number Diff line number Diff line
/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -107,6 +107,15 @@ struct kgsl_drawobj_sync {

#define KGSL_FENCE_NAME_LEN 74

struct fence_info {
	char name[KGSL_FENCE_NAME_LEN];
};

struct event_fence_info {
	struct fence_info *fences;
	int num_fences;
};

/**
 * struct kgsl_drawobj_sync_event
 * @id: identifer (positiion within the pending bitmap)
@@ -116,8 +125,8 @@ struct kgsl_drawobj_sync {
 *           register this event
 * @timestamp: Pending timestamp for the event
 * @handle: Pointer to a sync fence handle
 * @fence_name: A fence name string to describe the fence
 * @device: Pointer to the KGSL device
 * @info: structure to hold info about the fence
 */
struct kgsl_drawobj_sync_event {
	unsigned int id;
@@ -126,8 +135,8 @@ struct kgsl_drawobj_sync_event {
	struct kgsl_context *context;
	unsigned int timestamp;
	struct kgsl_sync_fence_cb *handle;
	char fence_name[KGSL_FENCE_NAME_LEN];
	struct kgsl_device *device;
	struct event_fence_info info;
};

/**
+40 −14
Original line number Diff line number Diff line
@@ -438,27 +438,54 @@ static void kgsl_sync_fence_callback(struct fence *fence, struct fence_cb *cb)
	}
}

static void kgsl_get_fence_name(struct fence *fence,
	char *fence_name, int name_len)
static void kgsl_get_fence_names(struct fence *fence,
	struct event_fence_info *info_ptr)
{
	char *ptr = fence_name;
	char *last = fence_name + name_len;
	unsigned int num_fences;
	struct fence **fences;
	struct fence_array *array;
	int i;

	ptr +=  snprintf(ptr, last - ptr, "%s %s",
			fence->ops->get_driver_name(fence),
			fence->ops->get_timeline_name(fence));
	if (!info_ptr)
		return;

	array = to_fence_array(fence);

	if (array != NULL) {
		num_fences = array->num_fences;
		fences = array->fences;
	} else {
		num_fences = 1;
		fences = &fence;
	}

	if ((ptr + 2) >= last)
	info_ptr->fences = kcalloc(num_fences, sizeof(struct fence_info),
			GFP_ATOMIC);
	if (info_ptr->fences == NULL)
		return;

	if (fence->ops->fence_value_str) {
		ptr += snprintf(ptr, last - ptr, ": ");
		fence->ops->fence_value_str(fence, ptr, last - ptr);
	info_ptr->num_fences = num_fences;

	for (i = 0; i < num_fences; i++) {
		struct fence *f = fences[i];
		struct fence_info *fi = &info_ptr->fences[i];
		int len;

		len =  scnprintf(fi->name, sizeof(fi->name), "%s %s",
			f->ops->get_driver_name(f),
			f->ops->get_timeline_name(f));

		if (f->ops->fence_value_str) {
			len += scnprintf(fi->name + len, sizeof(fi->name) - len,
				": ");
			f->ops->fence_value_str(f, fi->name + len,
				sizeof(fi->name) - len);
		}
	}
}

struct kgsl_sync_fence_cb *kgsl_sync_fence_async_wait(int fd,
	bool (*func)(void *priv), void *priv, char *fence_name, int name_len)
	bool (*func)(void *priv), void *priv, struct event_fence_info *info_ptr)
{
	struct kgsl_sync_fence_cb *kcb;
	struct fence *fence;
@@ -479,8 +506,7 @@ struct kgsl_sync_fence_cb *kgsl_sync_fence_async_wait(int fd,
	kcb->priv = priv;
	kcb->func = func;

	if (fence_name)
		kgsl_get_fence_name(fence, fence_name, name_len);
	kgsl_get_fence_names(fence, info_ptr);

	/* if status then error or signaled */
	status = fence_add_callback(fence, &kcb->fence_cb,
Loading