Commit d7965152 authored by Robert Bragg's avatar Robert Bragg Committed by Daniel Vetter

drm/i915: Enable i915 perf stream for Haswell OA unit

Gen graphics hardware can be set up to periodically write snapshots of
performance counters into a circular buffer via its Observation
Architecture and this patch exposes that capability to userspace via the
i915 perf interface.

v2:
   Make sure to initialize ->specific_ctx_id when opening, without
   relying on _pin_notify hook, in case ctx already pinned.
v3:
   Revert back to pinning ctx upfront when opening stream, removing
   need to hook in to pinning and to update OACONTROL on the fly.
Signed-off-by: default avatarRobert Bragg <robert@sixbynine.org>
Signed-off-by: default avatarZhenyu Wang <zhenyuw@linux.intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: default avatarMatthew Auld <matthew.auld@intel.com>
Reviewed-by: default avatarSourab Gupta <sourab.gupta@intel.com>
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
Link: http://patchwork.freedesktop.org/patch/msgid/20161107194957.3385-7-robert@sixbynine.org
parent 8a3003dd
......@@ -1797,6 +1797,11 @@ struct intel_wm_config {
bool sprites_scaled;
};
struct i915_oa_format {
u32 format;
int size;
};
struct i915_oa_reg {
i915_reg_t addr;
u32 value;
......@@ -1817,11 +1822,6 @@ struct i915_perf_stream_ops {
*/
void (*disable)(struct i915_perf_stream *stream);
/* Return: true if any i915 perf records are ready to read()
* for this stream.
*/
bool (*can_read)(struct i915_perf_stream *stream);
/* Call poll_wait, passing a wait queue that will be woken
* once there is something ready to read() for the stream
*/
......@@ -1831,9 +1831,7 @@ struct i915_perf_stream_ops {
/* For handling a blocking read, wait until there is something
* to ready to read() for the stream. E.g. wait on the same
* wait queue that would be passed to poll_wait() until
* ->can_read() returns true (if its safe to call ->can_read()
* without the i915 perf lock held).
* wait queue that would be passed to poll_wait().
*/
int (*wait_unlocked)(struct i915_perf_stream *stream);
......@@ -1873,11 +1871,28 @@ struct i915_perf_stream {
struct list_head link;
u32 sample_flags;
int sample_size;
struct i915_gem_context *ctx;
bool enabled;
struct i915_perf_stream_ops *ops;
const struct i915_perf_stream_ops *ops;
};
struct i915_oa_ops {
void (*init_oa_buffer)(struct drm_i915_private *dev_priv);
int (*enable_metric_set)(struct drm_i915_private *dev_priv);
void (*disable_metric_set)(struct drm_i915_private *dev_priv);
void (*oa_enable)(struct drm_i915_private *dev_priv);
void (*oa_disable)(struct drm_i915_private *dev_priv);
void (*update_oacontrol)(struct drm_i915_private *dev_priv);
void (*update_hw_ctx_id_locked)(struct drm_i915_private *dev_priv,
u32 ctx_id);
int (*read)(struct i915_perf_stream *stream,
char __user *buf,
size_t count,
size_t *offset);
bool (*oa_buffer_is_empty)(struct drm_i915_private *dev_priv);
};
struct drm_i915_private {
......@@ -2177,16 +2192,47 @@ struct drm_i915_private {
struct {
bool initialized;
struct mutex lock;
struct list_head streams;
spinlock_t hook_lock;
struct {
u32 metrics_set;
struct i915_perf_stream *exclusive_stream;
u32 specific_ctx_id;
struct i915_vma *pinned_rcs_vma;
struct hrtimer poll_check_timer;
wait_queue_head_t poll_wq;
bool pollin;
bool periodic;
int period_exponent;
int timestamp_frequency;
int tail_margin;
int metrics_set;
const struct i915_oa_reg *mux_regs;
int mux_regs_len;
const struct i915_oa_reg *b_counter_regs;
int b_counter_regs_len;
struct {
struct i915_vma *vma;
u8 *vaddr;
int format;
int format_size;
} oa_buffer;
u32 gen7_latched_oastatus1;
struct i915_oa_ops ops;
const struct i915_oa_format *oa_formats;
int n_builtin_sets;
} oa;
} perf;
......
This diff is collapsed.
This diff is collapsed.
......@@ -1230,6 +1230,18 @@ struct drm_i915_gem_context_param {
__u64 value;
};
enum drm_i915_oa_format {
I915_OA_FORMAT_A13 = 1,
I915_OA_FORMAT_A29,
I915_OA_FORMAT_A13_B8_C8,
I915_OA_FORMAT_B4_C8,
I915_OA_FORMAT_A45_B8_C8,
I915_OA_FORMAT_B4_C8_A16,
I915_OA_FORMAT_C4_B8,
I915_OA_FORMAT_MAX /* non-ABI */
};
enum drm_i915_perf_property_id {
/**
* Open the stream for a specific context handle (as used with
......@@ -1238,6 +1250,32 @@ enum drm_i915_perf_property_id {
*/
DRM_I915_PERF_PROP_CTX_HANDLE = 1,
/**
* A value of 1 requests the inclusion of raw OA unit reports as
* part of stream samples.
*/
DRM_I915_PERF_PROP_SAMPLE_OA,
/**
* The value specifies which set of OA unit metrics should be
* be configured, defining the contents of any OA unit reports.
*/
DRM_I915_PERF_PROP_OA_METRICS_SET,
/**
* The value specifies the size and layout of OA unit reports.
*/
DRM_I915_PERF_PROP_OA_FORMAT,
/**
* Specifying this property implicitly requests periodic OA unit
* sampling and (at least on Haswell) the sampling frequency is derived
* from this exponent as follows:
*
* 80ns * 2^(period_exponent + 1)
*/
DRM_I915_PERF_PROP_OA_EXPONENT,
DRM_I915_PERF_PROP_MAX /* non-ABI */
};
......@@ -1257,7 +1295,23 @@ struct drm_i915_perf_open_param {
__u64 __user properties_ptr;
};
/**
* Enable data capture for a stream that was either opened in a disabled state
* via I915_PERF_FLAG_DISABLED or was later disabled via
* I915_PERF_IOCTL_DISABLE.
*
* It is intended to be cheaper to disable and enable a stream than it may be
* to close and re-open a stream with the same configuration.
*
* It's undefined whether any pending data for the stream will be lost.
*/
#define I915_PERF_IOCTL_ENABLE _IO('i', 0x0)
/**
* Disable data capture for a stream.
*
* It is an error to try and read a stream that is disabled.
*/
#define I915_PERF_IOCTL_DISABLE _IO('i', 0x1)
/**
......@@ -1281,17 +1335,30 @@ enum drm_i915_perf_record_type {
* every sample.
*
* The order of these sample properties given by userspace has no
* affect on the ordering of data within a sample. The order will be
* affect on the ordering of data within a sample. The order is
* documented here.
*
* struct {
* struct drm_i915_perf_record_header header;
*
* TODO: itemize extensible sample data here
* { u32 oa_report[]; } && DRM_I915_PERF_PROP_SAMPLE_OA
* };
*/
DRM_I915_PERF_RECORD_SAMPLE = 1,
/*
* Indicates that one or more OA reports were not written by the
* hardware. This can happen for example if an MI_REPORT_PERF_COUNT
* command collides with periodic sampling - which would be more likely
* at higher sampling frequencies.
*/
DRM_I915_PERF_RECORD_OA_REPORT_LOST = 2,
/**
* An error occurred that resulted in all pending OA reports being lost.
*/
DRM_I915_PERF_RECORD_OA_BUFFER_LOST = 3,
DRM_I915_PERF_RECORD_MAX /* non-ABI */
};
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment