From: Sean Paul <seanpaul@xxxxxxxxxxxx> Mirror some atomic debug messages which track a state through allocation/clear/check/commit/free Change-Id: I0387ddf4b2f1d84137a5b471e347878c04c6d0af Signed-off-by: Sean Paul <seanpaul@xxxxxxxxxxxx> --- drivers/gpu/drm/drm_atomic.c | 19 +++++--- drivers/gpu/drm/drm_trace.h | 84 ++++++++++++++++++++++++++++++++++++ 2 files changed, 98 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index 14aeaf7363210..93ca64af67f55 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -41,6 +41,7 @@ #include "drm_crtc_internal.h" #include "drm_internal.h" +#include "drm_trace.h" void __drm_crtc_commit_free(struct kref *kref) { @@ -118,10 +119,11 @@ struct drm_atomic_state * drm_atomic_state_alloc(struct drm_device *dev) { struct drm_mode_config *config = &dev->mode_config; + struct drm_atomic_state *state; - if (!config->funcs->atomic_state_alloc) { - struct drm_atomic_state *state; - + if (config->funcs->atomic_state_alloc) { + state = config->funcs->atomic_state_alloc(dev); + } else { state = kzalloc(sizeof(*state), GFP_KERNEL); if (!state) return NULL; @@ -129,10 +131,10 @@ drm_atomic_state_alloc(struct drm_device *dev) kfree(state); return NULL; } - return state; } - return config->funcs->atomic_state_alloc(dev); + drm_trace(atomic, alloc, state); + return state; } EXPORT_SYMBOL(drm_atomic_state_alloc); @@ -239,6 +241,7 @@ void drm_atomic_state_clear(struct drm_atomic_state *state) struct drm_device *dev = state->dev; struct drm_mode_config *config = &dev->mode_config; + drm_trace(atomic, clear, state); if (config->funcs->atomic_state_clear) config->funcs->atomic_state_clear(state); else @@ -261,6 +264,7 @@ void __drm_atomic_state_free(struct kref *ref) drm_atomic_state_clear(state); DRM_DEBUG_ATOMIC("Freeing atomic state %p\n", state); + drm_trace(atomic, free, state); if (config->funcs->atomic_state_free) { config->funcs->atomic_state_free(state); @@ -1145,6 +1149,7 @@ int drm_atomic_check_only(struct drm_atomic_state *state) int i, ret = 0; DRM_DEBUG_ATOMIC("checking %p\n", state); + drm_trace(atomic, check, state); for_each_oldnew_plane_in_state(state, plane, old_plane_state, new_plane_state, i) { ret = drm_atomic_plane_check(old_plane_state, new_plane_state); @@ -1179,6 +1184,7 @@ int drm_atomic_check_only(struct drm_atomic_state *state) if (ret) { DRM_DEBUG_ATOMIC("atomic driver check for %p failed: %d\n", state, ret); + drm_trace_err(atomic, check_failed, state); return ret; } } @@ -1193,6 +1199,7 @@ int drm_atomic_check_only(struct drm_atomic_state *state) } } + drm_trace(atomic, check_passed, state); return 0; } EXPORT_SYMBOL(drm_atomic_check_only); @@ -1221,6 +1228,7 @@ int drm_atomic_commit(struct drm_atomic_state *state) return ret; DRM_DEBUG_ATOMIC("committing %p\n", state); + drm_trace(atomic, commit, state); return config->funcs->atomic_commit(state->dev, state, false); } @@ -1250,6 +1258,7 @@ int drm_atomic_nonblocking_commit(struct drm_atomic_state *state) return ret; DRM_DEBUG_ATOMIC("committing %p nonblocking\n", state); + drm_trace(atomic, commit_nonblock, state); return config->funcs->atomic_commit(state->dev, state, true); } diff --git a/drivers/gpu/drm/drm_trace.h b/drivers/gpu/drm/drm_trace.h index 19e5f04210586..5d56365d0b439 100644 --- a/drivers/gpu/drm/drm_trace.h +++ b/drivers/gpu/drm/drm_trace.h @@ -2,6 +2,9 @@ #if !defined(_DRM_TRACE_H_) || defined(TRACE_HEADER_MULTI_READ) #define _DRM_TRACE_H_ +#include <drm/drm_atomic.h> + +#include <linux/kref.h> #include <linux/stringify.h> #include <linux/types.h> #include <linux/tracepoint.h> @@ -59,6 +62,12 @@ enum drm_trace_event_class { * vblanks and vblank events. */ drm_trace_class_vblank = BIT(1), + + /** + * @drm_trace_class_atomic: This class is used to track the top-level + * atomic state from alloc to free and everywhere in between. + */ + drm_trace_class_atomic = BIT(2), }; /** @@ -150,6 +159,81 @@ DEFINE_EVENT(class_drm_vblank_event, drm_vblank_event_delivered, TP_ARGS(event_class, file, crtc, seq) ); +DECLARE_EVENT_CLASS(class_drm_atomic, + TP_PROTO(unsigned int event_class, + const struct drm_atomic_state *state), + TP_ARGS(event_class, state), + TP_STRUCT__entry( + __field(unsigned int, event_class) + __field(const struct drm_atomic_state *, state) + __field(unsigned int, ref) + __field(bool, allow_modeset) + __field(bool, legacy_cursor_update) + __field(bool, async_update) + __field(bool, duplicated) + __field(unsigned int, num_connector) + __field(unsigned int, num_private_objs) + ), + TP_fast_assign( + __entry->event_class = event_class; + __entry->state = state; /* Do not de-reference! */ + __entry->ref = kref_read(&state->ref); + __entry->allow_modeset = state->allow_modeset; + __entry->legacy_cursor_update = state->legacy_cursor_update; + __entry->async_update = state->async_update; + __entry->duplicated = state->duplicated; + __entry->num_connector = state->num_connector; + __entry->num_private_objs = state->num_private_objs; + ), + TP_printk("state=%pK ref=%d allow_modeset=%d legacy_cursor=%d " + "async_update=%d duplicated=%d num_conn=%d num_priv_objs=%d", + __entry->state, __entry->ref, __entry->allow_modeset, + __entry->legacy_cursor_update, __entry->async_update, + __entry->duplicated, __entry->num_connector, + __entry->num_private_objs) +); +DEFINE_EVENT_PRINT(class_drm_atomic, drm_atomic_alloc, + TP_PROTO(unsigned int event_class, + const struct drm_atomic_state *state), + TP_ARGS(event_class, state), + TP_printk("state=%pK", __entry->state) +); +DEFINE_EVENT(class_drm_atomic, drm_atomic_clear, + TP_PROTO(unsigned int event_class, + const struct drm_atomic_state *state), + TP_ARGS(event_class, state) +); +DEFINE_EVENT(class_drm_atomic, drm_atomic_free, + TP_PROTO(unsigned int event_class, + const struct drm_atomic_state *state), + TP_ARGS(event_class, state) +); +DEFINE_EVENT(class_drm_atomic, drm_atomic_check, + TP_PROTO(unsigned int event_class, + const struct drm_atomic_state *state), + TP_ARGS(event_class, state) +); +DEFINE_EVENT(class_drm_atomic, drm_atomic_commit, + TP_PROTO(unsigned int event_class, + const struct drm_atomic_state *state), + TP_ARGS(event_class, state) +); +DEFINE_EVENT(class_drm_atomic, drm_atomic_commit_nonblock, + TP_PROTO(unsigned int event_class, + const struct drm_atomic_state *state), + TP_ARGS(event_class, state) +); +DEFINE_EVENT(class_drm_atomic, drm_atomic_check_passed, + TP_PROTO(unsigned int event_class, + const struct drm_atomic_state *state), + TP_ARGS(event_class, state) +); +DEFINE_EVENT(class_drm_atomic, drm_atomic_check_failed, + TP_PROTO(unsigned int event_class, + const struct drm_atomic_state *state), + TP_ARGS(event_class, state) +); + #endif /* _DRM_TRACE_H_ */ /* This part must be outside protection */ -- Sean Paul, Software Engineer, Google / Chromium OS _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/dri-devel