From: Sean Paul <seanpaul@xxxxxxxxxxxx> Add tracing which tracks important crtc_state events through the atomic core. Signed-off-by: Sean Paul <seanpaul@xxxxxxxxxxxx> --- drivers/gpu/drm/drm_atomic.c | 14 +++++ drivers/gpu/drm/drm_trace.h | 109 +++++++++++++++++++++++++++++++++++ 2 files changed, 123 insertions(+) diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index 93ca64af67f55..955650729115d 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -319,6 +319,7 @@ drm_atomic_get_crtc_state(struct drm_atomic_state *state, DRM_DEBUG_ATOMIC("Added [CRTC:%d:%s] %p state to %p\n", crtc->base.id, crtc->name, crtc_state, state); + drm_trace(crtc, add, crtc_state); return crtc_state; } @@ -340,6 +341,8 @@ static int drm_atomic_crtc_check(const struct drm_crtc_state *old_crtc_state, if (new_crtc_state->active && !new_crtc_state->enable) { DRM_DEBUG_ATOMIC("[CRTC:%d:%s] active without enabled\n", crtc->base.id, crtc->name); + drm_trace_err(crtc, check_fail_active_not_enabled, + new_crtc_state); return -EINVAL; } @@ -350,6 +353,7 @@ static int drm_atomic_crtc_check(const struct drm_crtc_state *old_crtc_state, WARN_ON(new_crtc_state->enable && !new_crtc_state->mode_blob)) { DRM_DEBUG_ATOMIC("[CRTC:%d:%s] enabled without mode blob\n", crtc->base.id, crtc->name); + drm_trace_err(crtc, check_fail_enable_no_mode, new_crtc_state); return -EINVAL; } @@ -357,6 +361,7 @@ static int drm_atomic_crtc_check(const struct drm_crtc_state *old_crtc_state, WARN_ON(!new_crtc_state->enable && new_crtc_state->mode_blob)) { DRM_DEBUG_ATOMIC("[CRTC:%d:%s] disabled with mode blob\n", crtc->base.id, crtc->name); + drm_trace_err(crtc, check_fail_mode_no_enable, new_crtc_state); return -EINVAL; } @@ -374,9 +379,12 @@ static int drm_atomic_crtc_check(const struct drm_crtc_state *old_crtc_state, !new_crtc_state->active && !old_crtc_state->active) { DRM_DEBUG_ATOMIC("[CRTC:%d:%s] requesting event but off\n", crtc->base.id, crtc->name); + drm_trace_err(crtc, check_fail_event_not_active, + new_crtc_state); return -EINVAL; } + drm_trace(crtc, check_passed, new_crtc_state); return 0; } @@ -1057,6 +1065,8 @@ drm_atomic_add_affected_connectors(struct drm_atomic_state *state, DRM_DEBUG_ATOMIC("Adding all current connectors for [CRTC:%d:%s] to %p\n", crtc->base.id, crtc->name, state); + drm_trace(crtc, add_affected_connectors, crtc_state); + /* * Changed connectors are already in @state, so only need to look @@ -1111,6 +1121,7 @@ drm_atomic_add_affected_planes(struct drm_atomic_state *state, DRM_DEBUG_ATOMIC("Adding all current planes for [CRTC:%d:%s] to %p\n", crtc->base.id, crtc->name, state); + drm_trace(crtc, add_affected_planes, old_crtc_state); drm_for_each_plane_mask(plane, state->dev, old_crtc_state->plane_mask) { struct drm_plane_state *plane_state = @@ -1165,6 +1176,7 @@ int drm_atomic_check_only(struct drm_atomic_state *state) if (ret) { DRM_DEBUG_ATOMIC("[CRTC:%d:%s] atomic core check failed\n", crtc->base.id, crtc->name); + drm_trace_err(crtc, check_failed, new_crtc_state); return ret; } } @@ -1194,6 +1206,8 @@ int drm_atomic_check_only(struct drm_atomic_state *state) if (drm_atomic_crtc_needs_modeset(new_crtc_state)) { DRM_DEBUG_ATOMIC("[CRTC:%d:%s] requires full modeset\n", crtc->base.id, crtc->name); + drm_trace_err(crtc, check_fail_modeset_required, + new_crtc_state); return -EINVAL; } } diff --git a/drivers/gpu/drm/drm_trace.h b/drivers/gpu/drm/drm_trace.h index 5d56365d0b439..91880f650a7b3 100644 --- a/drivers/gpu/drm/drm_trace.h +++ b/drivers/gpu/drm/drm_trace.h @@ -3,6 +3,7 @@ #define _DRM_TRACE_H_ #include <drm/drm_atomic.h> +#include <drm/drm_crtc.h> #include <linux/kref.h> #include <linux/stringify.h> @@ -68,6 +69,12 @@ enum drm_trace_event_class { * atomic state from alloc to free and everywhere in between. */ drm_trace_class_atomic = BIT(2), + + /** + * @drm_trace_class_crtc: This class is used to track crtc state through + * the atomic core and helpers. + */ + drm_trace_class_crtc = BIT(3), }; /** @@ -234,6 +241,108 @@ DEFINE_EVENT(class_drm_atomic, drm_atomic_check_failed, TP_ARGS(event_class, state) ); +DECLARE_EVENT_CLASS(class_drm_crtc, + TP_PROTO(unsigned int event_class, const struct drm_crtc_state *state), + TP_ARGS(event_class, state), + TP_STRUCT__entry( + __field(unsigned int, event_class) + __field(const struct drm_atomic_state *, state) + __field(const struct drm_crtc_state *, crtc_state) + __field(const struct drm_crtc_commit *, commit) + __field(uint32_t, crtc_id) + __field(bool, enable) + __field(bool, active) + __field(bool, planes_changed) + __field(bool, mode_changed) + __field(bool, active_changed) + __field(bool, connectors_changed) + __field(bool, zpos_changed) + __field(bool, color_mgmt_changed) + __field(bool, no_vblank) + __field(bool, async_flip) + __field(bool, vrr_enabled) + __field(bool, self_refresh_active) + __field(u32, plane_mask) + __field(u32, connector_mask) + __field(u32, encoder_mask) + ), + TP_fast_assign( + __entry->event_class = event_class; + __entry->state = state->state; + __entry->crtc_state = state; + __entry->crtc_id = state->crtc->base.id; + __entry->commit = state->commit; + __entry->enable = state->enable; + __entry->active = state->active; + __entry->planes_changed = state->planes_changed; + __entry->mode_changed = state->mode_changed; + __entry->active_changed = state->active_changed; + __entry->connectors_changed = state->connectors_changed; + __entry->zpos_changed = state->zpos_changed; + __entry->color_mgmt_changed = state->color_mgmt_changed; + __entry->no_vblank = state->no_vblank; + __entry->async_flip = state->async_flip; + __entry->vrr_enabled = state->vrr_enabled; + __entry->self_refresh_active = state->self_refresh_active; + __entry->plane_mask = state->plane_mask; + __entry->connector_mask = state->connector_mask; + __entry->encoder_mask = state->encoder_mask; + ), + TP_printk("crtc_id=%u crtc_state=%pK state=%pK commit=%pK changed(" + "planes=%d mode=%d active=%d conn=%d zpos=%d color_mgmt=%d) " + "state(enable=%d active=%d async_flip=%d vrr_enabled=%d " + "self_refresh_active=%d no_vblank=%d) mask(plane=%x conn=%x " + "enc=%x)", + __entry->crtc_id, __entry->crtc_state, __entry->state, + __entry->commit, __entry->planes_changed, + __entry->mode_changed, __entry->active_changed, + __entry->connectors_changed, __entry->zpos_changed, + __entry->color_mgmt_changed, __entry->enable, __entry->active, + __entry->async_flip, __entry->vrr_enabled, + __entry->self_refresh_active, __entry->no_vblank, + __entry->plane_mask, __entry->connector_mask, + __entry->encoder_mask) +); +DEFINE_EVENT(class_drm_crtc, drm_crtc_add, + TP_PROTO(unsigned int event_class, const struct drm_crtc_state *state), + TP_ARGS(event_class, state) +); +DEFINE_EVENT(class_drm_crtc, drm_crtc_check_passed, + TP_PROTO(unsigned int event_class, const struct drm_crtc_state *state), + TP_ARGS(event_class, state) +); +DEFINE_EVENT(class_drm_crtc, drm_crtc_check_failed, + TP_PROTO(unsigned int event_class, const struct drm_crtc_state *state), + TP_ARGS(event_class, state) +); +DEFINE_EVENT(class_drm_crtc, drm_crtc_check_fail_active_not_enabled, + TP_PROTO(unsigned int event_class, const struct drm_crtc_state *state), + TP_ARGS(event_class, state) +); +DEFINE_EVENT(class_drm_crtc, drm_crtc_check_fail_enable_no_mode, + TP_PROTO(unsigned int event_class, const struct drm_crtc_state *state), + TP_ARGS(event_class, state) +); +DEFINE_EVENT(class_drm_crtc, drm_crtc_check_fail_mode_no_enable, + TP_PROTO(unsigned int event_class, const struct drm_crtc_state *state), + TP_ARGS(event_class, state) +); +DEFINE_EVENT(class_drm_crtc, drm_crtc_check_fail_event_not_active, + TP_PROTO(unsigned int event_class, const struct drm_crtc_state *state), + TP_ARGS(event_class, state) +); +DEFINE_EVENT(class_drm_crtc, drm_crtc_check_fail_modeset_required, + TP_PROTO(unsigned int event_class, const struct drm_crtc_state *state), + TP_ARGS(event_class, state) +); +DEFINE_EVENT(class_drm_crtc, drm_crtc_add_affected_connectors, + TP_PROTO(unsigned int event_class, const struct drm_crtc_state *state), + TP_ARGS(event_class, state) +); +DEFINE_EVENT(class_drm_crtc, drm_crtc_add_affected_planes, + TP_PROTO(unsigned int event_class, const struct drm_crtc_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