The pipe gamma registers are single buffered so they should only be updated during the vblank to avoid screen tearing. In fact they really should only be updated between start of vblank and frame start because that is the only time the pipe is guaranteed to be empty. Already at frame start the pipe begins to fill up with data for the next frame. Unfortunately frame start happens ~1 scanline after the start of vblank which in practice doesn't always leave us enough time to finish the gamma update in time (gamma LUTs can be several KiB of data we have to bash into the registers). However we must try our best and so we'll add a vblank work for each pipe from where we can do the gamma update. Additionally we could consider pushing frame start forward to the max of ~4 scanlines after start of vblank. But not sure that's exactly a validated configuration. As it stands the ~100 first pixels tend to make it through with the old gamma values. Even though the vblank worker is running on a high prority thread we still have to contend with C-states. If the CPU happens be in a deep C-state when the vblank interrupt arrives even the irq handler gets delayed massively (I've observed dozens of scanlines worth of latency). To avoid that problem we'll use the qos mechanism to keep the CPU awake while the vblank work is scheduled. With all this hooked up we can finally enjoy near atomic gamma updates. It even works across several pipes from the same atomic commit which previously was a total fail because we did the gamma updates for each pipe serially after waiting for all pipes to have latched the double buffered registers. In the future the DSB should take over this responsibility which will hopefully avoid some of these issues. Kudos to Lyude for finishing the actual vblank workers. Works like the proverbial train toilet. v2: Add missing intel_atomic_state fwd declaration v3: Clean up properly when not scheduling the worker v4: Clean up the rest and add tracepoints v5: s/intel_wait_for_vblank_works/intel_wait_for_vblank_workers/ (Jani,Uma) CC: Lyude Paul <lyude@redhat.com> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20211020223339.669-4-ville.syrjala@linux.intel.com Reviewed-by: Uma Shankar <uma.shankar@intel.com>
1339 lines
36 KiB
C
1339 lines
36 KiB
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
#if !defined(_I915_TRACE_H_) || defined(TRACE_HEADER_MULTI_READ)
|
|
#define _I915_TRACE_H_
|
|
|
|
#include <linux/stringify.h>
|
|
#include <linux/types.h>
|
|
#include <linux/tracepoint.h>
|
|
|
|
#include <drm/drm_drv.h>
|
|
|
|
#include "display/intel_crtc.h"
|
|
#include "display/intel_display_types.h"
|
|
#include "gt/intel_engine.h"
|
|
|
|
#include "i915_drv.h"
|
|
#include "i915_irq.h"
|
|
|
|
#undef TRACE_SYSTEM
|
|
#define TRACE_SYSTEM i915
|
|
#define TRACE_INCLUDE_FILE i915_trace
|
|
|
|
/* watermark/fifo updates */
|
|
|
|
TRACE_EVENT(intel_pipe_enable,
|
|
TP_PROTO(struct intel_crtc *crtc),
|
|
TP_ARGS(crtc),
|
|
|
|
TP_STRUCT__entry(
|
|
__array(u32, frame, 3)
|
|
__array(u32, scanline, 3)
|
|
__field(enum pipe, pipe)
|
|
),
|
|
TP_fast_assign(
|
|
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
|
|
struct intel_crtc *it__;
|
|
for_each_intel_crtc(&dev_priv->drm, it__) {
|
|
__entry->frame[it__->pipe] = intel_crtc_get_vblank_counter(it__);
|
|
__entry->scanline[it__->pipe] = intel_get_crtc_scanline(it__);
|
|
}
|
|
__entry->pipe = crtc->pipe;
|
|
),
|
|
|
|
TP_printk("pipe %c enable, pipe A: frame=%u, scanline=%u, pipe B: frame=%u, scanline=%u, pipe C: frame=%u, scanline=%u",
|
|
pipe_name(__entry->pipe),
|
|
__entry->frame[PIPE_A], __entry->scanline[PIPE_A],
|
|
__entry->frame[PIPE_B], __entry->scanline[PIPE_B],
|
|
__entry->frame[PIPE_C], __entry->scanline[PIPE_C])
|
|
);
|
|
|
|
TRACE_EVENT(intel_pipe_disable,
|
|
TP_PROTO(struct intel_crtc *crtc),
|
|
TP_ARGS(crtc),
|
|
|
|
TP_STRUCT__entry(
|
|
__array(u32, frame, 3)
|
|
__array(u32, scanline, 3)
|
|
__field(enum pipe, pipe)
|
|
),
|
|
|
|
TP_fast_assign(
|
|
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
|
|
struct intel_crtc *it__;
|
|
for_each_intel_crtc(&dev_priv->drm, it__) {
|
|
__entry->frame[it__->pipe] = intel_crtc_get_vblank_counter(it__);
|
|
__entry->scanline[it__->pipe] = intel_get_crtc_scanline(it__);
|
|
}
|
|
__entry->pipe = crtc->pipe;
|
|
),
|
|
|
|
TP_printk("pipe %c disable, pipe A: frame=%u, scanline=%u, pipe B: frame=%u, scanline=%u, pipe C: frame=%u, scanline=%u",
|
|
pipe_name(__entry->pipe),
|
|
__entry->frame[PIPE_A], __entry->scanline[PIPE_A],
|
|
__entry->frame[PIPE_B], __entry->scanline[PIPE_B],
|
|
__entry->frame[PIPE_C], __entry->scanline[PIPE_C])
|
|
);
|
|
|
|
TRACE_EVENT(intel_pipe_crc,
|
|
TP_PROTO(struct intel_crtc *crtc, const u32 *crcs),
|
|
TP_ARGS(crtc, crcs),
|
|
|
|
TP_STRUCT__entry(
|
|
__field(enum pipe, pipe)
|
|
__field(u32, frame)
|
|
__field(u32, scanline)
|
|
__array(u32, crcs, 5)
|
|
),
|
|
|
|
TP_fast_assign(
|
|
__entry->pipe = crtc->pipe;
|
|
__entry->frame = intel_crtc_get_vblank_counter(crtc);
|
|
__entry->scanline = intel_get_crtc_scanline(crtc);
|
|
memcpy(__entry->crcs, crcs, sizeof(__entry->crcs));
|
|
),
|
|
|
|
TP_printk("pipe %c, frame=%u, scanline=%u crc=%08x %08x %08x %08x %08x",
|
|
pipe_name(__entry->pipe), __entry->frame, __entry->scanline,
|
|
__entry->crcs[0], __entry->crcs[1], __entry->crcs[2],
|
|
__entry->crcs[3], __entry->crcs[4])
|
|
);
|
|
|
|
TRACE_EVENT(intel_cpu_fifo_underrun,
|
|
TP_PROTO(struct drm_i915_private *dev_priv, enum pipe pipe),
|
|
TP_ARGS(dev_priv, pipe),
|
|
|
|
TP_STRUCT__entry(
|
|
__field(enum pipe, pipe)
|
|
__field(u32, frame)
|
|
__field(u32, scanline)
|
|
),
|
|
|
|
TP_fast_assign(
|
|
struct intel_crtc *crtc = intel_get_crtc_for_pipe(dev_priv, pipe);
|
|
__entry->pipe = pipe;
|
|
__entry->frame = intel_crtc_get_vblank_counter(crtc);
|
|
__entry->scanline = intel_get_crtc_scanline(crtc);
|
|
),
|
|
|
|
TP_printk("pipe %c, frame=%u, scanline=%u",
|
|
pipe_name(__entry->pipe),
|
|
__entry->frame, __entry->scanline)
|
|
);
|
|
|
|
TRACE_EVENT(intel_pch_fifo_underrun,
|
|
TP_PROTO(struct drm_i915_private *dev_priv, enum pipe pch_transcoder),
|
|
TP_ARGS(dev_priv, pch_transcoder),
|
|
|
|
TP_STRUCT__entry(
|
|
__field(enum pipe, pipe)
|
|
__field(u32, frame)
|
|
__field(u32, scanline)
|
|
),
|
|
|
|
TP_fast_assign(
|
|
enum pipe pipe = pch_transcoder;
|
|
struct intel_crtc *crtc = intel_get_crtc_for_pipe(dev_priv, pipe);
|
|
__entry->pipe = pipe;
|
|
__entry->frame = intel_crtc_get_vblank_counter(crtc);
|
|
__entry->scanline = intel_get_crtc_scanline(crtc);
|
|
),
|
|
|
|
TP_printk("pch transcoder %c, frame=%u, scanline=%u",
|
|
pipe_name(__entry->pipe),
|
|
__entry->frame, __entry->scanline)
|
|
);
|
|
|
|
TRACE_EVENT(intel_memory_cxsr,
|
|
TP_PROTO(struct drm_i915_private *dev_priv, bool old, bool new),
|
|
TP_ARGS(dev_priv, old, new),
|
|
|
|
TP_STRUCT__entry(
|
|
__array(u32, frame, 3)
|
|
__array(u32, scanline, 3)
|
|
__field(bool, old)
|
|
__field(bool, new)
|
|
),
|
|
|
|
TP_fast_assign(
|
|
struct intel_crtc *crtc;
|
|
for_each_intel_crtc(&dev_priv->drm, crtc) {
|
|
__entry->frame[crtc->pipe] = intel_crtc_get_vblank_counter(crtc);
|
|
__entry->scanline[crtc->pipe] = intel_get_crtc_scanline(crtc);
|
|
}
|
|
__entry->old = old;
|
|
__entry->new = new;
|
|
),
|
|
|
|
TP_printk("%s->%s, pipe A: frame=%u, scanline=%u, pipe B: frame=%u, scanline=%u, pipe C: frame=%u, scanline=%u",
|
|
onoff(__entry->old), onoff(__entry->new),
|
|
__entry->frame[PIPE_A], __entry->scanline[PIPE_A],
|
|
__entry->frame[PIPE_B], __entry->scanline[PIPE_B],
|
|
__entry->frame[PIPE_C], __entry->scanline[PIPE_C])
|
|
);
|
|
|
|
TRACE_EVENT(g4x_wm,
|
|
TP_PROTO(struct intel_crtc *crtc, const struct g4x_wm_values *wm),
|
|
TP_ARGS(crtc, wm),
|
|
|
|
TP_STRUCT__entry(
|
|
__field(enum pipe, pipe)
|
|
__field(u32, frame)
|
|
__field(u32, scanline)
|
|
__field(u16, primary)
|
|
__field(u16, sprite)
|
|
__field(u16, cursor)
|
|
__field(u16, sr_plane)
|
|
__field(u16, sr_cursor)
|
|
__field(u16, sr_fbc)
|
|
__field(u16, hpll_plane)
|
|
__field(u16, hpll_cursor)
|
|
__field(u16, hpll_fbc)
|
|
__field(bool, cxsr)
|
|
__field(bool, hpll)
|
|
__field(bool, fbc)
|
|
),
|
|
|
|
TP_fast_assign(
|
|
__entry->pipe = crtc->pipe;
|
|
__entry->frame = intel_crtc_get_vblank_counter(crtc);
|
|
__entry->scanline = intel_get_crtc_scanline(crtc);
|
|
__entry->primary = wm->pipe[crtc->pipe].plane[PLANE_PRIMARY];
|
|
__entry->sprite = wm->pipe[crtc->pipe].plane[PLANE_SPRITE0];
|
|
__entry->cursor = wm->pipe[crtc->pipe].plane[PLANE_CURSOR];
|
|
__entry->sr_plane = wm->sr.plane;
|
|
__entry->sr_cursor = wm->sr.cursor;
|
|
__entry->sr_fbc = wm->sr.fbc;
|
|
__entry->hpll_plane = wm->hpll.plane;
|
|
__entry->hpll_cursor = wm->hpll.cursor;
|
|
__entry->hpll_fbc = wm->hpll.fbc;
|
|
__entry->cxsr = wm->cxsr;
|
|
__entry->hpll = wm->hpll_en;
|
|
__entry->fbc = wm->fbc_en;
|
|
),
|
|
|
|
TP_printk("pipe %c, frame=%u, scanline=%u, wm %d/%d/%d, sr %s/%d/%d/%d, hpll %s/%d/%d/%d, fbc %s",
|
|
pipe_name(__entry->pipe), __entry->frame, __entry->scanline,
|
|
__entry->primary, __entry->sprite, __entry->cursor,
|
|
yesno(__entry->cxsr), __entry->sr_plane, __entry->sr_cursor, __entry->sr_fbc,
|
|
yesno(__entry->hpll), __entry->hpll_plane, __entry->hpll_cursor, __entry->hpll_fbc,
|
|
yesno(__entry->fbc))
|
|
);
|
|
|
|
TRACE_EVENT(vlv_wm,
|
|
TP_PROTO(struct intel_crtc *crtc, const struct vlv_wm_values *wm),
|
|
TP_ARGS(crtc, wm),
|
|
|
|
TP_STRUCT__entry(
|
|
__field(enum pipe, pipe)
|
|
__field(u32, frame)
|
|
__field(u32, scanline)
|
|
__field(u32, level)
|
|
__field(u32, cxsr)
|
|
__field(u32, primary)
|
|
__field(u32, sprite0)
|
|
__field(u32, sprite1)
|
|
__field(u32, cursor)
|
|
__field(u32, sr_plane)
|
|
__field(u32, sr_cursor)
|
|
),
|
|
|
|
TP_fast_assign(
|
|
__entry->pipe = crtc->pipe;
|
|
__entry->frame = intel_crtc_get_vblank_counter(crtc);
|
|
__entry->scanline = intel_get_crtc_scanline(crtc);
|
|
__entry->level = wm->level;
|
|
__entry->cxsr = wm->cxsr;
|
|
__entry->primary = wm->pipe[crtc->pipe].plane[PLANE_PRIMARY];
|
|
__entry->sprite0 = wm->pipe[crtc->pipe].plane[PLANE_SPRITE0];
|
|
__entry->sprite1 = wm->pipe[crtc->pipe].plane[PLANE_SPRITE1];
|
|
__entry->cursor = wm->pipe[crtc->pipe].plane[PLANE_CURSOR];
|
|
__entry->sr_plane = wm->sr.plane;
|
|
__entry->sr_cursor = wm->sr.cursor;
|
|
),
|
|
|
|
TP_printk("pipe %c, frame=%u, scanline=%u, level=%d, cxsr=%d, wm %d/%d/%d/%d, sr %d/%d",
|
|
pipe_name(__entry->pipe), __entry->frame,
|
|
__entry->scanline, __entry->level, __entry->cxsr,
|
|
__entry->primary, __entry->sprite0, __entry->sprite1, __entry->cursor,
|
|
__entry->sr_plane, __entry->sr_cursor)
|
|
);
|
|
|
|
TRACE_EVENT(vlv_fifo_size,
|
|
TP_PROTO(struct intel_crtc *crtc, u32 sprite0_start, u32 sprite1_start, u32 fifo_size),
|
|
TP_ARGS(crtc, sprite0_start, sprite1_start, fifo_size),
|
|
|
|
TP_STRUCT__entry(
|
|
__field(enum pipe, pipe)
|
|
__field(u32, frame)
|
|
__field(u32, scanline)
|
|
__field(u32, sprite0_start)
|
|
__field(u32, sprite1_start)
|
|
__field(u32, fifo_size)
|
|
),
|
|
|
|
TP_fast_assign(
|
|
__entry->pipe = crtc->pipe;
|
|
__entry->frame = intel_crtc_get_vblank_counter(crtc);
|
|
__entry->scanline = intel_get_crtc_scanline(crtc);
|
|
__entry->sprite0_start = sprite0_start;
|
|
__entry->sprite1_start = sprite1_start;
|
|
__entry->fifo_size = fifo_size;
|
|
),
|
|
|
|
TP_printk("pipe %c, frame=%u, scanline=%u, %d/%d/%d",
|
|
pipe_name(__entry->pipe), __entry->frame,
|
|
__entry->scanline, __entry->sprite0_start,
|
|
__entry->sprite1_start, __entry->fifo_size)
|
|
);
|
|
|
|
/* plane updates */
|
|
|
|
TRACE_EVENT(intel_plane_update_noarm,
|
|
TP_PROTO(struct drm_plane *plane, struct intel_crtc *crtc),
|
|
TP_ARGS(plane, crtc),
|
|
|
|
TP_STRUCT__entry(
|
|
__field(enum pipe, pipe)
|
|
__field(u32, frame)
|
|
__field(u32, scanline)
|
|
__array(int, src, 4)
|
|
__array(int, dst, 4)
|
|
__string(name, plane->name)
|
|
),
|
|
|
|
TP_fast_assign(
|
|
__assign_str(name, plane->name);
|
|
__entry->pipe = crtc->pipe;
|
|
__entry->frame = intel_crtc_get_vblank_counter(crtc);
|
|
__entry->scanline = intel_get_crtc_scanline(crtc);
|
|
memcpy(__entry->src, &plane->state->src, sizeof(__entry->src));
|
|
memcpy(__entry->dst, &plane->state->dst, sizeof(__entry->dst));
|
|
),
|
|
|
|
TP_printk("pipe %c, plane %s, frame=%u, scanline=%u, " DRM_RECT_FP_FMT " -> " DRM_RECT_FMT,
|
|
pipe_name(__entry->pipe), __get_str(name),
|
|
__entry->frame, __entry->scanline,
|
|
DRM_RECT_FP_ARG((const struct drm_rect *)__entry->src),
|
|
DRM_RECT_ARG((const struct drm_rect *)__entry->dst))
|
|
);
|
|
|
|
TRACE_EVENT(intel_plane_update_arm,
|
|
TP_PROTO(struct drm_plane *plane, struct intel_crtc *crtc),
|
|
TP_ARGS(plane, crtc),
|
|
|
|
TP_STRUCT__entry(
|
|
__field(enum pipe, pipe)
|
|
__field(u32, frame)
|
|
__field(u32, scanline)
|
|
__array(int, src, 4)
|
|
__array(int, dst, 4)
|
|
__string(name, plane->name)
|
|
),
|
|
|
|
TP_fast_assign(
|
|
__assign_str(name, plane->name);
|
|
__entry->pipe = crtc->pipe;
|
|
__entry->frame = intel_crtc_get_vblank_counter(crtc);
|
|
__entry->scanline = intel_get_crtc_scanline(crtc);
|
|
memcpy(__entry->src, &plane->state->src, sizeof(__entry->src));
|
|
memcpy(__entry->dst, &plane->state->dst, sizeof(__entry->dst));
|
|
),
|
|
|
|
TP_printk("pipe %c, plane %s, frame=%u, scanline=%u, " DRM_RECT_FP_FMT " -> " DRM_RECT_FMT,
|
|
pipe_name(__entry->pipe), __get_str(name),
|
|
__entry->frame, __entry->scanline,
|
|
DRM_RECT_FP_ARG((const struct drm_rect *)__entry->src),
|
|
DRM_RECT_ARG((const struct drm_rect *)__entry->dst))
|
|
);
|
|
|
|
TRACE_EVENT(intel_plane_disable_arm,
|
|
TP_PROTO(struct drm_plane *plane, struct intel_crtc *crtc),
|
|
TP_ARGS(plane, crtc),
|
|
|
|
TP_STRUCT__entry(
|
|
__field(enum pipe, pipe)
|
|
__field(u32, frame)
|
|
__field(u32, scanline)
|
|
__string(name, plane->name)
|
|
),
|
|
|
|
TP_fast_assign(
|
|
__assign_str(name, plane->name);
|
|
__entry->pipe = crtc->pipe;
|
|
__entry->frame = intel_crtc_get_vblank_counter(crtc);
|
|
__entry->scanline = intel_get_crtc_scanline(crtc);
|
|
),
|
|
|
|
TP_printk("pipe %c, plane %s, frame=%u, scanline=%u",
|
|
pipe_name(__entry->pipe), __get_str(name),
|
|
__entry->frame, __entry->scanline)
|
|
);
|
|
|
|
/* fbc */
|
|
|
|
TRACE_EVENT(intel_fbc_activate,
|
|
TP_PROTO(struct intel_crtc *crtc),
|
|
TP_ARGS(crtc),
|
|
|
|
TP_STRUCT__entry(
|
|
__field(enum pipe, pipe)
|
|
__field(u32, frame)
|
|
__field(u32, scanline)
|
|
),
|
|
|
|
TP_fast_assign(
|
|
__entry->pipe = crtc->pipe;
|
|
__entry->frame = intel_crtc_get_vblank_counter(crtc);
|
|
__entry->scanline = intel_get_crtc_scanline(crtc);
|
|
),
|
|
|
|
TP_printk("pipe %c, frame=%u, scanline=%u",
|
|
pipe_name(__entry->pipe), __entry->frame, __entry->scanline)
|
|
);
|
|
|
|
TRACE_EVENT(intel_fbc_deactivate,
|
|
TP_PROTO(struct intel_crtc *crtc),
|
|
TP_ARGS(crtc),
|
|
|
|
TP_STRUCT__entry(
|
|
__field(enum pipe, pipe)
|
|
__field(u32, frame)
|
|
__field(u32, scanline)
|
|
),
|
|
|
|
TP_fast_assign(
|
|
__entry->pipe = crtc->pipe;
|
|
__entry->frame = intel_crtc_get_vblank_counter(crtc);
|
|
__entry->scanline = intel_get_crtc_scanline(crtc);
|
|
),
|
|
|
|
TP_printk("pipe %c, frame=%u, scanline=%u",
|
|
pipe_name(__entry->pipe), __entry->frame, __entry->scanline)
|
|
);
|
|
|
|
TRACE_EVENT(intel_fbc_nuke,
|
|
TP_PROTO(struct intel_crtc *crtc),
|
|
TP_ARGS(crtc),
|
|
|
|
TP_STRUCT__entry(
|
|
__field(enum pipe, pipe)
|
|
__field(u32, frame)
|
|
__field(u32, scanline)
|
|
),
|
|
|
|
TP_fast_assign(
|
|
__entry->pipe = crtc->pipe;
|
|
__entry->frame = intel_crtc_get_vblank_counter(crtc);
|
|
__entry->scanline = intel_get_crtc_scanline(crtc);
|
|
),
|
|
|
|
TP_printk("pipe %c, frame=%u, scanline=%u",
|
|
pipe_name(__entry->pipe), __entry->frame, __entry->scanline)
|
|
);
|
|
|
|
/* pipe updates */
|
|
|
|
TRACE_EVENT(intel_crtc_vblank_work_start,
|
|
TP_PROTO(struct intel_crtc *crtc),
|
|
TP_ARGS(crtc),
|
|
|
|
TP_STRUCT__entry(
|
|
__field(enum pipe, pipe)
|
|
__field(u32, frame)
|
|
__field(u32, scanline)
|
|
),
|
|
|
|
TP_fast_assign(
|
|
__entry->pipe = crtc->pipe;
|
|
__entry->frame = intel_crtc_get_vblank_counter(crtc);
|
|
__entry->scanline = intel_get_crtc_scanline(crtc);
|
|
),
|
|
|
|
TP_printk("pipe %c, frame=%u, scanline=%u",
|
|
pipe_name(__entry->pipe), __entry->frame,
|
|
__entry->scanline)
|
|
);
|
|
|
|
TRACE_EVENT(intel_crtc_vblank_work_end,
|
|
TP_PROTO(struct intel_crtc *crtc),
|
|
TP_ARGS(crtc),
|
|
|
|
TP_STRUCT__entry(
|
|
__field(enum pipe, pipe)
|
|
__field(u32, frame)
|
|
__field(u32, scanline)
|
|
),
|
|
|
|
TP_fast_assign(
|
|
__entry->pipe = crtc->pipe;
|
|
__entry->frame = intel_crtc_get_vblank_counter(crtc);
|
|
__entry->scanline = intel_get_crtc_scanline(crtc);
|
|
),
|
|
|
|
TP_printk("pipe %c, frame=%u, scanline=%u",
|
|
pipe_name(__entry->pipe), __entry->frame,
|
|
__entry->scanline)
|
|
);
|
|
|
|
TRACE_EVENT(intel_pipe_update_start,
|
|
TP_PROTO(struct intel_crtc *crtc),
|
|
TP_ARGS(crtc),
|
|
|
|
TP_STRUCT__entry(
|
|
__field(enum pipe, pipe)
|
|
__field(u32, frame)
|
|
__field(u32, scanline)
|
|
__field(u32, min)
|
|
__field(u32, max)
|
|
),
|
|
|
|
TP_fast_assign(
|
|
__entry->pipe = crtc->pipe;
|
|
__entry->frame = intel_crtc_get_vblank_counter(crtc);
|
|
__entry->scanline = intel_get_crtc_scanline(crtc);
|
|
__entry->min = crtc->debug.min_vbl;
|
|
__entry->max = crtc->debug.max_vbl;
|
|
),
|
|
|
|
TP_printk("pipe %c, frame=%u, scanline=%u, min=%u, max=%u",
|
|
pipe_name(__entry->pipe), __entry->frame,
|
|
__entry->scanline, __entry->min, __entry->max)
|
|
);
|
|
|
|
TRACE_EVENT(intel_pipe_update_vblank_evaded,
|
|
TP_PROTO(struct intel_crtc *crtc),
|
|
TP_ARGS(crtc),
|
|
|
|
TP_STRUCT__entry(
|
|
__field(enum pipe, pipe)
|
|
__field(u32, frame)
|
|
__field(u32, scanline)
|
|
__field(u32, min)
|
|
__field(u32, max)
|
|
),
|
|
|
|
TP_fast_assign(
|
|
__entry->pipe = crtc->pipe;
|
|
__entry->frame = crtc->debug.start_vbl_count;
|
|
__entry->scanline = crtc->debug.scanline_start;
|
|
__entry->min = crtc->debug.min_vbl;
|
|
__entry->max = crtc->debug.max_vbl;
|
|
),
|
|
|
|
TP_printk("pipe %c, frame=%u, scanline=%u, min=%u, max=%u",
|
|
pipe_name(__entry->pipe), __entry->frame,
|
|
__entry->scanline, __entry->min, __entry->max)
|
|
);
|
|
|
|
TRACE_EVENT(intel_pipe_update_end,
|
|
TP_PROTO(struct intel_crtc *crtc, u32 frame, int scanline_end),
|
|
TP_ARGS(crtc, frame, scanline_end),
|
|
|
|
TP_STRUCT__entry(
|
|
__field(enum pipe, pipe)
|
|
__field(u32, frame)
|
|
__field(u32, scanline)
|
|
),
|
|
|
|
TP_fast_assign(
|
|
__entry->pipe = crtc->pipe;
|
|
__entry->frame = frame;
|
|
__entry->scanline = scanline_end;
|
|
),
|
|
|
|
TP_printk("pipe %c, frame=%u, scanline=%u",
|
|
pipe_name(__entry->pipe), __entry->frame,
|
|
__entry->scanline)
|
|
);
|
|
|
|
/* frontbuffer tracking */
|
|
|
|
TRACE_EVENT(intel_frontbuffer_invalidate,
|
|
TP_PROTO(unsigned int frontbuffer_bits, unsigned int origin),
|
|
TP_ARGS(frontbuffer_bits, origin),
|
|
|
|
TP_STRUCT__entry(
|
|
__field(unsigned int, frontbuffer_bits)
|
|
__field(unsigned int, origin)
|
|
),
|
|
|
|
TP_fast_assign(
|
|
__entry->frontbuffer_bits = frontbuffer_bits;
|
|
__entry->origin = origin;
|
|
),
|
|
|
|
TP_printk("frontbuffer_bits=0x%08x, origin=%u",
|
|
__entry->frontbuffer_bits, __entry->origin)
|
|
);
|
|
|
|
TRACE_EVENT(intel_frontbuffer_flush,
|
|
TP_PROTO(unsigned int frontbuffer_bits, unsigned int origin),
|
|
TP_ARGS(frontbuffer_bits, origin),
|
|
|
|
TP_STRUCT__entry(
|
|
__field(unsigned int, frontbuffer_bits)
|
|
__field(unsigned int, origin)
|
|
),
|
|
|
|
TP_fast_assign(
|
|
__entry->frontbuffer_bits = frontbuffer_bits;
|
|
__entry->origin = origin;
|
|
),
|
|
|
|
TP_printk("frontbuffer_bits=0x%08x, origin=%u",
|
|
__entry->frontbuffer_bits, __entry->origin)
|
|
);
|
|
|
|
/* object tracking */
|
|
|
|
TRACE_EVENT(i915_gem_object_create,
|
|
TP_PROTO(struct drm_i915_gem_object *obj),
|
|
TP_ARGS(obj),
|
|
|
|
TP_STRUCT__entry(
|
|
__field(struct drm_i915_gem_object *, obj)
|
|
__field(u64, size)
|
|
),
|
|
|
|
TP_fast_assign(
|
|
__entry->obj = obj;
|
|
__entry->size = obj->base.size;
|
|
),
|
|
|
|
TP_printk("obj=%p, size=0x%llx", __entry->obj, __entry->size)
|
|
);
|
|
|
|
TRACE_EVENT(i915_gem_shrink,
|
|
TP_PROTO(struct drm_i915_private *i915, unsigned long target, unsigned flags),
|
|
TP_ARGS(i915, target, flags),
|
|
|
|
TP_STRUCT__entry(
|
|
__field(int, dev)
|
|
__field(unsigned long, target)
|
|
__field(unsigned, flags)
|
|
),
|
|
|
|
TP_fast_assign(
|
|
__entry->dev = i915->drm.primary->index;
|
|
__entry->target = target;
|
|
__entry->flags = flags;
|
|
),
|
|
|
|
TP_printk("dev=%d, target=%lu, flags=%x",
|
|
__entry->dev, __entry->target, __entry->flags)
|
|
);
|
|
|
|
TRACE_EVENT(i915_vma_bind,
|
|
TP_PROTO(struct i915_vma *vma, unsigned flags),
|
|
TP_ARGS(vma, flags),
|
|
|
|
TP_STRUCT__entry(
|
|
__field(struct drm_i915_gem_object *, obj)
|
|
__field(struct i915_address_space *, vm)
|
|
__field(u64, offset)
|
|
__field(u64, size)
|
|
__field(unsigned, flags)
|
|
),
|
|
|
|
TP_fast_assign(
|
|
__entry->obj = vma->obj;
|
|
__entry->vm = vma->vm;
|
|
__entry->offset = vma->node.start;
|
|
__entry->size = vma->node.size;
|
|
__entry->flags = flags;
|
|
),
|
|
|
|
TP_printk("obj=%p, offset=0x%016llx size=0x%llx%s vm=%p",
|
|
__entry->obj, __entry->offset, __entry->size,
|
|
__entry->flags & PIN_MAPPABLE ? ", mappable" : "",
|
|
__entry->vm)
|
|
);
|
|
|
|
TRACE_EVENT(i915_vma_unbind,
|
|
TP_PROTO(struct i915_vma *vma),
|
|
TP_ARGS(vma),
|
|
|
|
TP_STRUCT__entry(
|
|
__field(struct drm_i915_gem_object *, obj)
|
|
__field(struct i915_address_space *, vm)
|
|
__field(u64, offset)
|
|
__field(u64, size)
|
|
),
|
|
|
|
TP_fast_assign(
|
|
__entry->obj = vma->obj;
|
|
__entry->vm = vma->vm;
|
|
__entry->offset = vma->node.start;
|
|
__entry->size = vma->node.size;
|
|
),
|
|
|
|
TP_printk("obj=%p, offset=0x%016llx size=0x%llx vm=%p",
|
|
__entry->obj, __entry->offset, __entry->size, __entry->vm)
|
|
);
|
|
|
|
TRACE_EVENT(i915_gem_object_pwrite,
|
|
TP_PROTO(struct drm_i915_gem_object *obj, u64 offset, u64 len),
|
|
TP_ARGS(obj, offset, len),
|
|
|
|
TP_STRUCT__entry(
|
|
__field(struct drm_i915_gem_object *, obj)
|
|
__field(u64, offset)
|
|
__field(u64, len)
|
|
),
|
|
|
|
TP_fast_assign(
|
|
__entry->obj = obj;
|
|
__entry->offset = offset;
|
|
__entry->len = len;
|
|
),
|
|
|
|
TP_printk("obj=%p, offset=0x%llx, len=0x%llx",
|
|
__entry->obj, __entry->offset, __entry->len)
|
|
);
|
|
|
|
TRACE_EVENT(i915_gem_object_pread,
|
|
TP_PROTO(struct drm_i915_gem_object *obj, u64 offset, u64 len),
|
|
TP_ARGS(obj, offset, len),
|
|
|
|
TP_STRUCT__entry(
|
|
__field(struct drm_i915_gem_object *, obj)
|
|
__field(u64, offset)
|
|
__field(u64, len)
|
|
),
|
|
|
|
TP_fast_assign(
|
|
__entry->obj = obj;
|
|
__entry->offset = offset;
|
|
__entry->len = len;
|
|
),
|
|
|
|
TP_printk("obj=%p, offset=0x%llx, len=0x%llx",
|
|
__entry->obj, __entry->offset, __entry->len)
|
|
);
|
|
|
|
TRACE_EVENT(i915_gem_object_fault,
|
|
TP_PROTO(struct drm_i915_gem_object *obj, u64 index, bool gtt, bool write),
|
|
TP_ARGS(obj, index, gtt, write),
|
|
|
|
TP_STRUCT__entry(
|
|
__field(struct drm_i915_gem_object *, obj)
|
|
__field(u64, index)
|
|
__field(bool, gtt)
|
|
__field(bool, write)
|
|
),
|
|
|
|
TP_fast_assign(
|
|
__entry->obj = obj;
|
|
__entry->index = index;
|
|
__entry->gtt = gtt;
|
|
__entry->write = write;
|
|
),
|
|
|
|
TP_printk("obj=%p, %s index=%llu %s",
|
|
__entry->obj,
|
|
__entry->gtt ? "GTT" : "CPU",
|
|
__entry->index,
|
|
__entry->write ? ", writable" : "")
|
|
);
|
|
|
|
DECLARE_EVENT_CLASS(i915_gem_object,
|
|
TP_PROTO(struct drm_i915_gem_object *obj),
|
|
TP_ARGS(obj),
|
|
|
|
TP_STRUCT__entry(
|
|
__field(struct drm_i915_gem_object *, obj)
|
|
),
|
|
|
|
TP_fast_assign(
|
|
__entry->obj = obj;
|
|
),
|
|
|
|
TP_printk("obj=%p", __entry->obj)
|
|
);
|
|
|
|
DEFINE_EVENT(i915_gem_object, i915_gem_object_clflush,
|
|
TP_PROTO(struct drm_i915_gem_object *obj),
|
|
TP_ARGS(obj)
|
|
);
|
|
|
|
DEFINE_EVENT(i915_gem_object, i915_gem_object_destroy,
|
|
TP_PROTO(struct drm_i915_gem_object *obj),
|
|
TP_ARGS(obj)
|
|
);
|
|
|
|
TRACE_EVENT(i915_gem_evict,
|
|
TP_PROTO(struct i915_address_space *vm, u64 size, u64 align, unsigned int flags),
|
|
TP_ARGS(vm, size, align, flags),
|
|
|
|
TP_STRUCT__entry(
|
|
__field(u32, dev)
|
|
__field(struct i915_address_space *, vm)
|
|
__field(u64, size)
|
|
__field(u64, align)
|
|
__field(unsigned int, flags)
|
|
),
|
|
|
|
TP_fast_assign(
|
|
__entry->dev = vm->i915->drm.primary->index;
|
|
__entry->vm = vm;
|
|
__entry->size = size;
|
|
__entry->align = align;
|
|
__entry->flags = flags;
|
|
),
|
|
|
|
TP_printk("dev=%d, vm=%p, size=0x%llx, align=0x%llx %s",
|
|
__entry->dev, __entry->vm, __entry->size, __entry->align,
|
|
__entry->flags & PIN_MAPPABLE ? ", mappable" : "")
|
|
);
|
|
|
|
TRACE_EVENT(i915_gem_evict_node,
|
|
TP_PROTO(struct i915_address_space *vm, struct drm_mm_node *node, unsigned int flags),
|
|
TP_ARGS(vm, node, flags),
|
|
|
|
TP_STRUCT__entry(
|
|
__field(u32, dev)
|
|
__field(struct i915_address_space *, vm)
|
|
__field(u64, start)
|
|
__field(u64, size)
|
|
__field(unsigned long, color)
|
|
__field(unsigned int, flags)
|
|
),
|
|
|
|
TP_fast_assign(
|
|
__entry->dev = vm->i915->drm.primary->index;
|
|
__entry->vm = vm;
|
|
__entry->start = node->start;
|
|
__entry->size = node->size;
|
|
__entry->color = node->color;
|
|
__entry->flags = flags;
|
|
),
|
|
|
|
TP_printk("dev=%d, vm=%p, start=0x%llx size=0x%llx, color=0x%lx, flags=%x",
|
|
__entry->dev, __entry->vm,
|
|
__entry->start, __entry->size,
|
|
__entry->color, __entry->flags)
|
|
);
|
|
|
|
TRACE_EVENT(i915_gem_evict_vm,
|
|
TP_PROTO(struct i915_address_space *vm),
|
|
TP_ARGS(vm),
|
|
|
|
TP_STRUCT__entry(
|
|
__field(u32, dev)
|
|
__field(struct i915_address_space *, vm)
|
|
),
|
|
|
|
TP_fast_assign(
|
|
__entry->dev = vm->i915->drm.primary->index;
|
|
__entry->vm = vm;
|
|
),
|
|
|
|
TP_printk("dev=%d, vm=%p", __entry->dev, __entry->vm)
|
|
);
|
|
|
|
TRACE_EVENT(i915_request_queue,
|
|
TP_PROTO(struct i915_request *rq, u32 flags),
|
|
TP_ARGS(rq, flags),
|
|
|
|
TP_STRUCT__entry(
|
|
__field(u32, dev)
|
|
__field(u64, ctx)
|
|
__field(u16, class)
|
|
__field(u16, instance)
|
|
__field(u32, seqno)
|
|
__field(u32, flags)
|
|
),
|
|
|
|
TP_fast_assign(
|
|
__entry->dev = rq->engine->i915->drm.primary->index;
|
|
__entry->class = rq->engine->uabi_class;
|
|
__entry->instance = rq->engine->uabi_instance;
|
|
__entry->ctx = rq->fence.context;
|
|
__entry->seqno = rq->fence.seqno;
|
|
__entry->flags = flags;
|
|
),
|
|
|
|
TP_printk("dev=%u, engine=%u:%u, ctx=%llu, seqno=%u, flags=0x%x",
|
|
__entry->dev, __entry->class, __entry->instance,
|
|
__entry->ctx, __entry->seqno, __entry->flags)
|
|
);
|
|
|
|
DECLARE_EVENT_CLASS(i915_request,
|
|
TP_PROTO(struct i915_request *rq),
|
|
TP_ARGS(rq),
|
|
|
|
TP_STRUCT__entry(
|
|
__field(u32, dev)
|
|
__field(u64, ctx)
|
|
__field(u32, guc_id)
|
|
__field(u16, class)
|
|
__field(u16, instance)
|
|
__field(u32, seqno)
|
|
__field(u32, tail)
|
|
),
|
|
|
|
TP_fast_assign(
|
|
__entry->dev = rq->engine->i915->drm.primary->index;
|
|
__entry->class = rq->engine->uabi_class;
|
|
__entry->instance = rq->engine->uabi_instance;
|
|
__entry->guc_id = rq->context->guc_id.id;
|
|
__entry->ctx = rq->fence.context;
|
|
__entry->seqno = rq->fence.seqno;
|
|
__entry->tail = rq->tail;
|
|
),
|
|
|
|
TP_printk("dev=%u, engine=%u:%u, guc_id=%u, ctx=%llu, seqno=%u, tail=%u",
|
|
__entry->dev, __entry->class, __entry->instance,
|
|
__entry->guc_id, __entry->ctx, __entry->seqno,
|
|
__entry->tail)
|
|
);
|
|
|
|
DEFINE_EVENT(i915_request, i915_request_add,
|
|
TP_PROTO(struct i915_request *rq),
|
|
TP_ARGS(rq)
|
|
);
|
|
|
|
#if defined(CONFIG_DRM_I915_LOW_LEVEL_TRACEPOINTS)
|
|
DEFINE_EVENT(i915_request, i915_request_guc_submit,
|
|
TP_PROTO(struct i915_request *rq),
|
|
TP_ARGS(rq)
|
|
);
|
|
|
|
DEFINE_EVENT(i915_request, i915_request_submit,
|
|
TP_PROTO(struct i915_request *rq),
|
|
TP_ARGS(rq)
|
|
);
|
|
|
|
DEFINE_EVENT(i915_request, i915_request_execute,
|
|
TP_PROTO(struct i915_request *rq),
|
|
TP_ARGS(rq)
|
|
);
|
|
|
|
TRACE_EVENT(i915_request_in,
|
|
TP_PROTO(struct i915_request *rq, unsigned int port),
|
|
TP_ARGS(rq, port),
|
|
|
|
TP_STRUCT__entry(
|
|
__field(u32, dev)
|
|
__field(u64, ctx)
|
|
__field(u16, class)
|
|
__field(u16, instance)
|
|
__field(u32, seqno)
|
|
__field(u32, port)
|
|
__field(s32, prio)
|
|
),
|
|
|
|
TP_fast_assign(
|
|
__entry->dev = rq->engine->i915->drm.primary->index;
|
|
__entry->class = rq->engine->uabi_class;
|
|
__entry->instance = rq->engine->uabi_instance;
|
|
__entry->ctx = rq->fence.context;
|
|
__entry->seqno = rq->fence.seqno;
|
|
__entry->prio = rq->sched.attr.priority;
|
|
__entry->port = port;
|
|
),
|
|
|
|
TP_printk("dev=%u, engine=%u:%u, ctx=%llu, seqno=%u, prio=%d, port=%u",
|
|
__entry->dev, __entry->class, __entry->instance,
|
|
__entry->ctx, __entry->seqno,
|
|
__entry->prio, __entry->port)
|
|
);
|
|
|
|
TRACE_EVENT(i915_request_out,
|
|
TP_PROTO(struct i915_request *rq),
|
|
TP_ARGS(rq),
|
|
|
|
TP_STRUCT__entry(
|
|
__field(u32, dev)
|
|
__field(u64, ctx)
|
|
__field(u16, class)
|
|
__field(u16, instance)
|
|
__field(u32, seqno)
|
|
__field(u32, completed)
|
|
),
|
|
|
|
TP_fast_assign(
|
|
__entry->dev = rq->engine->i915->drm.primary->index;
|
|
__entry->class = rq->engine->uabi_class;
|
|
__entry->instance = rq->engine->uabi_instance;
|
|
__entry->ctx = rq->fence.context;
|
|
__entry->seqno = rq->fence.seqno;
|
|
__entry->completed = i915_request_completed(rq);
|
|
),
|
|
|
|
TP_printk("dev=%u, engine=%u:%u, ctx=%llu, seqno=%u, completed?=%u",
|
|
__entry->dev, __entry->class, __entry->instance,
|
|
__entry->ctx, __entry->seqno, __entry->completed)
|
|
);
|
|
|
|
DECLARE_EVENT_CLASS(intel_context,
|
|
TP_PROTO(struct intel_context *ce),
|
|
TP_ARGS(ce),
|
|
|
|
TP_STRUCT__entry(
|
|
__field(u32, guc_id)
|
|
__field(int, pin_count)
|
|
__field(u32, sched_state)
|
|
__field(u8, guc_prio)
|
|
),
|
|
|
|
TP_fast_assign(
|
|
__entry->guc_id = ce->guc_id.id;
|
|
__entry->pin_count = atomic_read(&ce->pin_count);
|
|
__entry->sched_state = ce->guc_state.sched_state;
|
|
__entry->guc_prio = ce->guc_state.prio;
|
|
),
|
|
|
|
TP_printk("guc_id=%d, pin_count=%d sched_state=0x%x, guc_prio=%u",
|
|
__entry->guc_id, __entry->pin_count,
|
|
__entry->sched_state,
|
|
__entry->guc_prio)
|
|
);
|
|
|
|
DEFINE_EVENT(intel_context, intel_context_set_prio,
|
|
TP_PROTO(struct intel_context *ce),
|
|
TP_ARGS(ce)
|
|
);
|
|
|
|
DEFINE_EVENT(intel_context, intel_context_reset,
|
|
TP_PROTO(struct intel_context *ce),
|
|
TP_ARGS(ce)
|
|
);
|
|
|
|
DEFINE_EVENT(intel_context, intel_context_ban,
|
|
TP_PROTO(struct intel_context *ce),
|
|
TP_ARGS(ce)
|
|
);
|
|
|
|
DEFINE_EVENT(intel_context, intel_context_register,
|
|
TP_PROTO(struct intel_context *ce),
|
|
TP_ARGS(ce)
|
|
);
|
|
|
|
DEFINE_EVENT(intel_context, intel_context_deregister,
|
|
TP_PROTO(struct intel_context *ce),
|
|
TP_ARGS(ce)
|
|
);
|
|
|
|
DEFINE_EVENT(intel_context, intel_context_deregister_done,
|
|
TP_PROTO(struct intel_context *ce),
|
|
TP_ARGS(ce)
|
|
);
|
|
|
|
DEFINE_EVENT(intel_context, intel_context_sched_enable,
|
|
TP_PROTO(struct intel_context *ce),
|
|
TP_ARGS(ce)
|
|
);
|
|
|
|
DEFINE_EVENT(intel_context, intel_context_sched_disable,
|
|
TP_PROTO(struct intel_context *ce),
|
|
TP_ARGS(ce)
|
|
);
|
|
|
|
DEFINE_EVENT(intel_context, intel_context_sched_done,
|
|
TP_PROTO(struct intel_context *ce),
|
|
TP_ARGS(ce)
|
|
);
|
|
|
|
DEFINE_EVENT(intel_context, intel_context_create,
|
|
TP_PROTO(struct intel_context *ce),
|
|
TP_ARGS(ce)
|
|
);
|
|
|
|
DEFINE_EVENT(intel_context, intel_context_fence_release,
|
|
TP_PROTO(struct intel_context *ce),
|
|
TP_ARGS(ce)
|
|
);
|
|
|
|
DEFINE_EVENT(intel_context, intel_context_free,
|
|
TP_PROTO(struct intel_context *ce),
|
|
TP_ARGS(ce)
|
|
);
|
|
|
|
DEFINE_EVENT(intel_context, intel_context_steal_guc_id,
|
|
TP_PROTO(struct intel_context *ce),
|
|
TP_ARGS(ce)
|
|
);
|
|
|
|
DEFINE_EVENT(intel_context, intel_context_do_pin,
|
|
TP_PROTO(struct intel_context *ce),
|
|
TP_ARGS(ce)
|
|
);
|
|
|
|
DEFINE_EVENT(intel_context, intel_context_do_unpin,
|
|
TP_PROTO(struct intel_context *ce),
|
|
TP_ARGS(ce)
|
|
);
|
|
|
|
#else
|
|
#if !defined(TRACE_HEADER_MULTI_READ)
|
|
static inline void
|
|
trace_i915_request_guc_submit(struct i915_request *rq)
|
|
{
|
|
}
|
|
|
|
static inline void
|
|
trace_i915_request_submit(struct i915_request *rq)
|
|
{
|
|
}
|
|
|
|
static inline void
|
|
trace_i915_request_execute(struct i915_request *rq)
|
|
{
|
|
}
|
|
|
|
static inline void
|
|
trace_i915_request_in(struct i915_request *rq, unsigned int port)
|
|
{
|
|
}
|
|
|
|
static inline void
|
|
trace_i915_request_out(struct i915_request *rq)
|
|
{
|
|
}
|
|
|
|
static inline void
|
|
trace_intel_context_set_prio(struct intel_context *ce)
|
|
{
|
|
}
|
|
|
|
static inline void
|
|
trace_intel_context_reset(struct intel_context *ce)
|
|
{
|
|
}
|
|
|
|
static inline void
|
|
trace_intel_context_ban(struct intel_context *ce)
|
|
{
|
|
}
|
|
|
|
static inline void
|
|
trace_intel_context_register(struct intel_context *ce)
|
|
{
|
|
}
|
|
|
|
static inline void
|
|
trace_intel_context_deregister(struct intel_context *ce)
|
|
{
|
|
}
|
|
|
|
static inline void
|
|
trace_intel_context_deregister_done(struct intel_context *ce)
|
|
{
|
|
}
|
|
|
|
static inline void
|
|
trace_intel_context_sched_enable(struct intel_context *ce)
|
|
{
|
|
}
|
|
|
|
static inline void
|
|
trace_intel_context_sched_disable(struct intel_context *ce)
|
|
{
|
|
}
|
|
|
|
static inline void
|
|
trace_intel_context_sched_done(struct intel_context *ce)
|
|
{
|
|
}
|
|
|
|
static inline void
|
|
trace_intel_context_create(struct intel_context *ce)
|
|
{
|
|
}
|
|
|
|
static inline void
|
|
trace_intel_context_fence_release(struct intel_context *ce)
|
|
{
|
|
}
|
|
|
|
static inline void
|
|
trace_intel_context_free(struct intel_context *ce)
|
|
{
|
|
}
|
|
|
|
static inline void
|
|
trace_intel_context_steal_guc_id(struct intel_context *ce)
|
|
{
|
|
}
|
|
|
|
static inline void
|
|
trace_intel_context_do_pin(struct intel_context *ce)
|
|
{
|
|
}
|
|
|
|
static inline void
|
|
trace_intel_context_do_unpin(struct intel_context *ce)
|
|
{
|
|
}
|
|
#endif
|
|
#endif
|
|
|
|
DEFINE_EVENT(i915_request, i915_request_retire,
|
|
TP_PROTO(struct i915_request *rq),
|
|
TP_ARGS(rq)
|
|
);
|
|
|
|
TRACE_EVENT(i915_request_wait_begin,
|
|
TP_PROTO(struct i915_request *rq, unsigned int flags),
|
|
TP_ARGS(rq, flags),
|
|
|
|
TP_STRUCT__entry(
|
|
__field(u32, dev)
|
|
__field(u64, ctx)
|
|
__field(u16, class)
|
|
__field(u16, instance)
|
|
__field(u32, seqno)
|
|
__field(unsigned int, flags)
|
|
),
|
|
|
|
/* NB: the blocking information is racy since mutex_is_locked
|
|
* doesn't check that the current thread holds the lock. The only
|
|
* other option would be to pass the boolean information of whether
|
|
* or not the class was blocking down through the stack which is
|
|
* less desirable.
|
|
*/
|
|
TP_fast_assign(
|
|
__entry->dev = rq->engine->i915->drm.primary->index;
|
|
__entry->class = rq->engine->uabi_class;
|
|
__entry->instance = rq->engine->uabi_instance;
|
|
__entry->ctx = rq->fence.context;
|
|
__entry->seqno = rq->fence.seqno;
|
|
__entry->flags = flags;
|
|
),
|
|
|
|
TP_printk("dev=%u, engine=%u:%u, ctx=%llu, seqno=%u, flags=0x%x",
|
|
__entry->dev, __entry->class, __entry->instance,
|
|
__entry->ctx, __entry->seqno,
|
|
__entry->flags)
|
|
);
|
|
|
|
DEFINE_EVENT(i915_request, i915_request_wait_end,
|
|
TP_PROTO(struct i915_request *rq),
|
|
TP_ARGS(rq)
|
|
);
|
|
|
|
TRACE_EVENT_CONDITION(i915_reg_rw,
|
|
TP_PROTO(bool write, i915_reg_t reg, u64 val, int len, bool trace),
|
|
|
|
TP_ARGS(write, reg, val, len, trace),
|
|
|
|
TP_CONDITION(trace),
|
|
|
|
TP_STRUCT__entry(
|
|
__field(u64, val)
|
|
__field(u32, reg)
|
|
__field(u16, write)
|
|
__field(u16, len)
|
|
),
|
|
|
|
TP_fast_assign(
|
|
__entry->val = (u64)val;
|
|
__entry->reg = i915_mmio_reg_offset(reg);
|
|
__entry->write = write;
|
|
__entry->len = len;
|
|
),
|
|
|
|
TP_printk("%s reg=0x%x, len=%d, val=(0x%x, 0x%x)",
|
|
__entry->write ? "write" : "read",
|
|
__entry->reg, __entry->len,
|
|
(u32)(__entry->val & 0xffffffff),
|
|
(u32)(__entry->val >> 32))
|
|
);
|
|
|
|
TRACE_EVENT(intel_gpu_freq_change,
|
|
TP_PROTO(u32 freq),
|
|
TP_ARGS(freq),
|
|
|
|
TP_STRUCT__entry(
|
|
__field(u32, freq)
|
|
),
|
|
|
|
TP_fast_assign(
|
|
__entry->freq = freq;
|
|
),
|
|
|
|
TP_printk("new_freq=%u", __entry->freq)
|
|
);
|
|
|
|
/**
|
|
* DOC: i915_ppgtt_create and i915_ppgtt_release tracepoints
|
|
*
|
|
* With full ppgtt enabled each process using drm will allocate at least one
|
|
* translation table. With these traces it is possible to keep track of the
|
|
* allocation and of the lifetime of the tables; this can be used during
|
|
* testing/debug to verify that we are not leaking ppgtts.
|
|
* These traces identify the ppgtt through the vm pointer, which is also printed
|
|
* by the i915_vma_bind and i915_vma_unbind tracepoints.
|
|
*/
|
|
DECLARE_EVENT_CLASS(i915_ppgtt,
|
|
TP_PROTO(struct i915_address_space *vm),
|
|
TP_ARGS(vm),
|
|
|
|
TP_STRUCT__entry(
|
|
__field(struct i915_address_space *, vm)
|
|
__field(u32, dev)
|
|
),
|
|
|
|
TP_fast_assign(
|
|
__entry->vm = vm;
|
|
__entry->dev = vm->i915->drm.primary->index;
|
|
),
|
|
|
|
TP_printk("dev=%u, vm=%p", __entry->dev, __entry->vm)
|
|
)
|
|
|
|
DEFINE_EVENT(i915_ppgtt, i915_ppgtt_create,
|
|
TP_PROTO(struct i915_address_space *vm),
|
|
TP_ARGS(vm)
|
|
);
|
|
|
|
DEFINE_EVENT(i915_ppgtt, i915_ppgtt_release,
|
|
TP_PROTO(struct i915_address_space *vm),
|
|
TP_ARGS(vm)
|
|
);
|
|
|
|
/**
|
|
* DOC: i915_context_create and i915_context_free tracepoints
|
|
*
|
|
* These tracepoints are used to track creation and deletion of contexts.
|
|
* If full ppgtt is enabled, they also print the address of the vm assigned to
|
|
* the context.
|
|
*/
|
|
DECLARE_EVENT_CLASS(i915_context,
|
|
TP_PROTO(struct i915_gem_context *ctx),
|
|
TP_ARGS(ctx),
|
|
|
|
TP_STRUCT__entry(
|
|
__field(u32, dev)
|
|
__field(struct i915_gem_context *, ctx)
|
|
__field(struct i915_address_space *, vm)
|
|
),
|
|
|
|
TP_fast_assign(
|
|
__entry->dev = ctx->i915->drm.primary->index;
|
|
__entry->ctx = ctx;
|
|
__entry->vm = ctx->vm;
|
|
),
|
|
|
|
TP_printk("dev=%u, ctx=%p, ctx_vm=%p",
|
|
__entry->dev, __entry->ctx, __entry->vm)
|
|
)
|
|
|
|
DEFINE_EVENT(i915_context, i915_context_create,
|
|
TP_PROTO(struct i915_gem_context *ctx),
|
|
TP_ARGS(ctx)
|
|
);
|
|
|
|
DEFINE_EVENT(i915_context, i915_context_free,
|
|
TP_PROTO(struct i915_gem_context *ctx),
|
|
TP_ARGS(ctx)
|
|
);
|
|
|
|
#endif /* _I915_TRACE_H_ */
|
|
|
|
/* This part must be outside protection */
|
|
#undef TRACE_INCLUDE_PATH
|
|
#define TRACE_INCLUDE_PATH ../../drivers/gpu/drm/i915
|
|
#include <trace/define_trace.h>
|