Loading drivers/gpu/msm/adreno_debugfs.c +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 Loading Loading @@ -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: Loading drivers/gpu/msm/kgsl.c +1 −1 Original line number Diff line number Diff line Loading @@ -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); Loading drivers/gpu/msm/kgsl_drawobj.c +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 Loading Loading @@ -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) { Loading @@ -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; Loading Loading @@ -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) { Loading Loading @@ -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"); Loading Loading @@ -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 Loading @@ -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); Loading @@ -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); Loading @@ -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; } Loading drivers/gpu/msm/kgsl_drawobj.h +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 Loading Loading @@ -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) Loading @@ -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; Loading @@ -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; }; /** Loading drivers/gpu/msm/kgsl_sync.c +40 −14 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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 Loading
drivers/gpu/msm/adreno_debugfs.c +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 Loading Loading @@ -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: Loading
drivers/gpu/msm/kgsl.c +1 −1 Original line number Diff line number Diff line Loading @@ -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); Loading
drivers/gpu/msm/kgsl_drawobj.c +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 Loading Loading @@ -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) { Loading @@ -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; Loading Loading @@ -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) { Loading Loading @@ -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"); Loading Loading @@ -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 Loading @@ -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); Loading @@ -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); Loading @@ -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; } Loading
drivers/gpu/msm/kgsl_drawobj.h +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 Loading Loading @@ -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) Loading @@ -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; Loading @@ -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; }; /** Loading
drivers/gpu/msm/kgsl_sync.c +40 −14 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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