[PATCH 4/6] drm: trace: Add crtc state trace events

Sean Paul sean at poorly.run
Thu Nov 7 21:03:03 UTC 2019


From: Sean Paul <seanpaul at chromium.org>

Add tracing which tracks important crtc_state events through the atomic
core.

Signed-off-by: Sean Paul <seanpaul at chromium.org>
---
 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



More information about the dri-devel mailing list