diff mbox series

drm/i915/perf: Refactor oa object to better manage resources

Message ID 20190501165046.30375-1-umesh.nerlige.ramappa@intel.com (mailing list archive)
State New, archived
Headers show
Series drm/i915/perf: Refactor oa object to better manage resources | expand

Commit Message

Umesh Nerlige Ramappa May 1, 2019, 4:50 p.m. UTC
The oa object manages the oa buffer and must be allocated when the user
intends to read performance counter snapshots. This can be achieved by
making the oa object part of the stream object which is allocated when a
stream is opened by the user.

Attributes in the oa object that are gen-specific are moved to the perf
object so that they can be initialized on driver load.

The split provides a better separation of the objects used in perf
implementation of i915 driver so that resources are allocated and
initialized only when needed.

Signed-off-by: Umesh Nerlige Ramappa <umesh.nerlige.ramappa@intel.com>
---
 drivers/gpu/drm/i915/gt/intel_sseu.c  |   2 +-
 drivers/gpu/drm/i915/gvt/scheduler.c  |   4 +-
 drivers/gpu/drm/i915/i915_drv.h       | 219 +++++-----
 drivers/gpu/drm/i915/i915_oa_bdw.c    |  30 +-
 drivers/gpu/drm/i915/i915_oa_bxt.c    |  30 +-
 drivers/gpu/drm/i915/i915_oa_cflgt2.c |  30 +-
 drivers/gpu/drm/i915/i915_oa_cflgt3.c |  30 +-
 drivers/gpu/drm/i915/i915_oa_chv.c    |  30 +-
 drivers/gpu/drm/i915/i915_oa_cnl.c    |  30 +-
 drivers/gpu/drm/i915/i915_oa_glk.c    |  30 +-
 drivers/gpu/drm/i915/i915_oa_hsw.c    |  30 +-
 drivers/gpu/drm/i915/i915_oa_icl.c    |  30 +-
 drivers/gpu/drm/i915/i915_oa_kblgt2.c |  30 +-
 drivers/gpu/drm/i915/i915_oa_kblgt3.c |  30 +-
 drivers/gpu/drm/i915/i915_oa_sklgt2.c |  30 +-
 drivers/gpu/drm/i915/i915_oa_sklgt3.c |  30 +-
 drivers/gpu/drm/i915/i915_oa_sklgt4.c |  30 +-
 drivers/gpu/drm/i915/i915_perf.c      | 580 ++++++++++++++------------
 18 files changed, 627 insertions(+), 598 deletions(-)

Comments

Lionel Landwerlin May 2, 2019, 10:26 a.m. UTC | #1
On 01/05/2019 17:50, Umesh Nerlige Ramappa wrote:
> The oa object manages the oa buffer and must be allocated when the user
> intends to read performance counter snapshots. This can be achieved by
> making the oa object part of the stream object which is allocated when a
> stream is opened by the user.
>
> Attributes in the oa object that are gen-specific are moved to the perf
> object so that they can be initialized on driver load.
>
> The split provides a better separation of the objects used in perf
> implementation of i915 driver so that resources are allocated and
> initialized only when needed.
>
> Signed-off-by: Umesh Nerlige Ramappa <umesh.nerlige.ramappa@intel.com>


This refactoring makes sense.

I've opened a PR on gputop to match the changes in the generated files : 
https://github.com/rib/gputop/pull/201


Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>


> ---
>   drivers/gpu/drm/i915/gt/intel_sseu.c  |   2 +-
>   drivers/gpu/drm/i915/gvt/scheduler.c  |   4 +-
>   drivers/gpu/drm/i915/i915_drv.h       | 219 +++++-----
>   drivers/gpu/drm/i915/i915_oa_bdw.c    |  30 +-
>   drivers/gpu/drm/i915/i915_oa_bxt.c    |  30 +-
>   drivers/gpu/drm/i915/i915_oa_cflgt2.c |  30 +-
>   drivers/gpu/drm/i915/i915_oa_cflgt3.c |  30 +-
>   drivers/gpu/drm/i915/i915_oa_chv.c    |  30 +-
>   drivers/gpu/drm/i915/i915_oa_cnl.c    |  30 +-
>   drivers/gpu/drm/i915/i915_oa_glk.c    |  30 +-
>   drivers/gpu/drm/i915/i915_oa_hsw.c    |  30 +-
>   drivers/gpu/drm/i915/i915_oa_icl.c    |  30 +-
>   drivers/gpu/drm/i915/i915_oa_kblgt2.c |  30 +-
>   drivers/gpu/drm/i915/i915_oa_kblgt3.c |  30 +-
>   drivers/gpu/drm/i915/i915_oa_sklgt2.c |  30 +-
>   drivers/gpu/drm/i915/i915_oa_sklgt3.c |  30 +-
>   drivers/gpu/drm/i915/i915_oa_sklgt4.c |  30 +-
>   drivers/gpu/drm/i915/i915_perf.c      | 580 ++++++++++++++------------
>   18 files changed, 627 insertions(+), 598 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/gt/intel_sseu.c b/drivers/gpu/drm/i915/gt/intel_sseu.c
> index 7f448f3bea0b..fa78df39521a 100644
> --- a/drivers/gpu/drm/i915/gt/intel_sseu.c
> +++ b/drivers/gpu/drm/i915/gt/intel_sseu.c
> @@ -32,7 +32,7 @@ u32 intel_sseu_make_rpcs(struct drm_i915_private *i915,
>   	 * cases which disable slices for functional, apart for performance
>   	 * reasons. So in this case we select a known stable subset.
>   	 */
> -	if (!i915->perf.oa.exclusive_stream) {
> +	if (!i915->perf.exclusive_stream) {
>   		ctx_sseu = *req_sseu;
>   	} else {
>   		ctx_sseu = intel_sseu_from_device_info(sseu);
> diff --git a/drivers/gpu/drm/i915/gvt/scheduler.c b/drivers/gpu/drm/i915/gvt/scheduler.c
> index 7ae42f2ebfe8..878e71a927de 100644
> --- a/drivers/gpu/drm/i915/gvt/scheduler.c
> +++ b/drivers/gpu/drm/i915/gvt/scheduler.c
> @@ -81,8 +81,8 @@ static void sr_oa_regs(struct intel_vgpu_workload *workload,
>   		u32 *reg_state, bool save)
>   {
>   	struct drm_i915_private *dev_priv = workload->vgpu->gvt->dev_priv;
> -	u32 ctx_oactxctrl = dev_priv->perf.oa.ctx_oactxctrl_offset;
> -	u32 ctx_flexeu0 = dev_priv->perf.oa.ctx_flexeu0_offset;
> +	u32 ctx_oactxctrl = dev_priv->perf.ctx_oactxctrl_offset;
> +	u32 ctx_flexeu0 = dev_priv->perf.ctx_flexeu0_offset;
>   	int i = 0;
>   	u32 flex_mmio[] = {
>   		i915_mmio_reg_offset(EU_PERF_CNTL0),
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 1cea98f8b85c..9536550f11cc 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -1399,6 +1399,86 @@ struct i915_perf_stream {
>   	 * @oa_config: The OA configuration used by the stream.
>   	 */
>   	struct i915_oa_config *oa_config;
> +
> +	/**
> +	 * The OA context specific information.
> +	 */
> +	struct intel_context *pinned_ctx;
> +	u32 specific_ctx_id;
> +	u32 specific_ctx_id_mask;
> +
> +	struct hrtimer poll_check_timer;
> +	wait_queue_head_t poll_wq;
> +	bool pollin;
> +
> +	bool periodic;
> +	int period_exponent;
> +
> +	/**
> +	 * State of the OA buffer.
> +	 */
> +	struct {
> +		struct i915_vma *vma;
> +		u8 *vaddr;
> +		u32 last_ctx_id;
> +		int format;
> +		int format_size;
> +		int size_exponent;
> +
> +		/**
> +		 * Locks reads and writes to all head/tail state
> +		 *
> +		 * Consider: the head and tail pointer state needs to be read
> +		 * consistently from a hrtimer callback (atomic context) and
> +		 * read() fop (user context) with tail pointer updates happening
> +		 * in atomic context and head updates in user context and the
> +		 * (unlikely) possibility of read() errors needing to reset all
> +		 * head/tail state.
> +		 *
> +		 * Note: Contention/performance aren't currently a significant
> +		 * concern here considering the relatively low frequency of
> +		 * hrtimer callbacks (5ms period) and that reads typically only
> +		 * happen in response to a hrtimer event and likely complete
> +		 * before the next callback.
> +		 *
> +		 * Note: This lock is not held *while* reading and copying data
> +		 * to userspace so the value of head observed in htrimer
> +		 * callbacks won't represent any partial consumption of data.
> +		 */
> +		spinlock_t ptr_lock;
> +
> +		/**
> +		 * One 'aging' tail pointer and one 'aged' tail pointer ready to
> +		 * used for reading.
> +		 *
> +		 * Initial values of 0xffffffff are invalid and imply that an
> +		 * update is required (and should be ignored by an attempted
> +		 * read)
> +		 */
> +		struct {
> +			u32 offset;
> +		} tails[2];
> +
> +		/**
> +		 * Index for the aged tail ready to read() data up to.
> +		 */
> +		unsigned int aged_tail_idx;
> +
> +		/**
> +		 * A monotonic timestamp for when the current aging tail pointer
> +		 * was read; used to determine when it is old enough to trust.
> +		 */
> +		u64 aging_timestamp;
> +
> +		/**
> +		 * Although we can always read back the head pointer register,
> +		 * we prefer to avoid trusting the HW state, just to avoid any
> +		 * risk that some hardware condition could * somehow bump the
> +		 * head pointer unpredictably and cause us to forward the wrong
> +		 * OA buffer data to userspace.
> +		 */
> +		u32 head;
> +	} oa_buffer;
>   };
>   
>   /**
> @@ -1436,7 +1516,7 @@ struct i915_oa_ops {
>   	 * @disable_metric_set: Remove system constraints associated with using
>   	 * the OA unit.
>   	 */
> -	void (*disable_metric_set)(struct drm_i915_private *dev_priv);
> +	void (*disable_metric_set)(struct i915_perf_stream *stream);
>   
>   	/**
>   	 * @oa_enable: Enable periodic sampling
> @@ -1464,7 +1544,7 @@ struct i915_oa_ops {
>   	 * handling the OA unit tail pointer race that affects multiple
>   	 * generations.
>   	 */
> -	u32 (*oa_hw_tail_read)(struct drm_i915_private *dev_priv);
> +	u32 (*oa_hw_tail_read)(struct i915_perf_stream *stream);
>   };
>   
>   struct intel_cdclk_state {
> @@ -1867,120 +1947,35 @@ struct drm_i915_private {
>   		struct mutex lock;
>   		struct list_head streams;
>   
> -		struct {
> -			/*
> -			 * The stream currently using the OA unit. If accessed
> -			 * outside a syscall associated to its file
> -			 * descriptor, you need to hold
> -			 * dev_priv->drm.struct_mutex.
> -			 */
> -			struct i915_perf_stream *exclusive_stream;
> +		/*
> +		 * The stream currently using the OA unit. If accessed
> +		 * outside a syscall associated to its file
> +		 * descriptor, you need to hold
> +		 * dev_priv->drm.struct_mutex.
> +		 */
> +		struct i915_perf_stream *exclusive_stream;
> +
> +		/**
> +		 * For rate limiting any notifications of spurious
> +		 * invalid OA reports
> +		 */
> +		struct ratelimit_state spurious_report_rs;
>   
> -			struct intel_context *pinned_ctx;
> -			u32 specific_ctx_id;
> -			u32 specific_ctx_id_mask;
> +		struct i915_oa_config test_config;
>   
> -			struct hrtimer poll_check_timer;
> -			wait_queue_head_t poll_wq;
> -			bool pollin;
> +		u32 gen7_latched_oastatus1;
> +		u32 ctx_oactxctrl_offset;
> +		u32 ctx_flexeu0_offset;
>   
> -			/**
> -			 * For rate limiting any notifications of spurious
> -			 * invalid OA reports
> -			 */
> -			struct ratelimit_state spurious_report_rs;
> -
> -			bool periodic;
> -			int period_exponent;
> -
> -			struct i915_oa_config test_config;
> -
> -			struct {
> -				struct i915_vma *vma;
> -				u8 *vaddr;
> -				u32 last_ctx_id;
> -				int format;
> -				int format_size;
> -
> -				/**
> -				 * Locks reads and writes to all head/tail state
> -				 *
> -				 * Consider: the head and tail pointer state
> -				 * needs to be read consistently from a hrtimer
> -				 * callback (atomic context) and read() fop
> -				 * (user context) with tail pointer updates
> -				 * happening in atomic context and head updates
> -				 * in user context and the (unlikely)
> -				 * possibility of read() errors needing to
> -				 * reset all head/tail state.
> -				 *
> -				 * Note: Contention or performance aren't
> -				 * currently a significant concern here
> -				 * considering the relatively low frequency of
> -				 * hrtimer callbacks (5ms period) and that
> -				 * reads typically only happen in response to a
> -				 * hrtimer event and likely complete before the
> -				 * next callback.
> -				 *
> -				 * Note: This lock is not held *while* reading
> -				 * and copying data to userspace so the value
> -				 * of head observed in htrimer callbacks won't
> -				 * represent any partial consumption of data.
> -				 */
> -				spinlock_t ptr_lock;
> -
> -				/**
> -				 * One 'aging' tail pointer and one 'aged'
> -				 * tail pointer ready to used for reading.
> -				 *
> -				 * Initial values of 0xffffffff are invalid
> -				 * and imply that an update is required
> -				 * (and should be ignored by an attempted
> -				 * read)
> -				 */
> -				struct {
> -					u32 offset;
> -				} tails[2];
> -
> -				/**
> -				 * Index for the aged tail ready to read()
> -				 * data up to.
> -				 */
> -				unsigned int aged_tail_idx;
> -
> -				/**
> -				 * A monotonic timestamp for when the current
> -				 * aging tail pointer was read; used to
> -				 * determine when it is old enough to trust.
> -				 */
> -				u64 aging_timestamp;
> -
> -				/**
> -				 * Although we can always read back the head
> -				 * pointer register, we prefer to avoid
> -				 * trusting the HW state, just to avoid any
> -				 * risk that some hardware condition could
> -				 * somehow bump the head pointer unpredictably
> -				 * and cause us to forward the wrong OA buffer
> -				 * data to userspace.
> -				 */
> -				u32 head;
> -			} oa_buffer;
> -
> -			u32 gen7_latched_oastatus1;
> -			u32 ctx_oactxctrl_offset;
> -			u32 ctx_flexeu0_offset;
> -
> -			/**
> -			 * The RPT_ID/reason field for Gen8+ includes a bit
> -			 * to determine if the CTX ID in the report is valid
> -			 * but the specific bit differs between Gen 8 and 9
> -			 */
> -			u32 gen8_valid_ctx_bit;
> +		/**
> +		 * The RPT_ID/reason field for Gen8+ includes a bit
> +		 * to determine if the CTX ID in the report is valid
> +		 * but the specific bit differs between Gen 8 and 9
> +		 */
> +		u32 gen8_valid_ctx_bit;
>   
> -			struct i915_oa_ops ops;
> -			const struct i915_oa_format *oa_formats;
> -		} oa;
> +		struct i915_oa_ops ops;
> +		const struct i915_oa_format *oa_formats;
>   	} perf;
>   
>   	/* Abstract the submission mechanism (legacy ringbuffer or execlists) away */
> diff --git a/drivers/gpu/drm/i915/i915_oa_bdw.c b/drivers/gpu/drm/i915/i915_oa_bdw.c
> index 4acdb94555b7..7d632d503510 100644
> --- a/drivers/gpu/drm/i915/i915_oa_bdw.c
> +++ b/drivers/gpu/drm/i915/i915_oa_bdw.c
> @@ -66,26 +66,26 @@ show_test_oa_id(struct device *kdev, struct device_attribute *attr, char *buf)
>   void
>   i915_perf_load_test_config_bdw(struct drm_i915_private *dev_priv)
>   {
> -	strlcpy(dev_priv->perf.oa.test_config.uuid,
> +	strlcpy(dev_priv->perf.test_config.uuid,
>   		"d6de6f55-e526-4f79-a6a6-d7315c09044e",
> -		sizeof(dev_priv->perf.oa.test_config.uuid));
> -	dev_priv->perf.oa.test_config.id = 1;
> +		sizeof(dev_priv->perf.test_config.uuid));
> +	dev_priv->perf.test_config.id = 1;
>   
> -	dev_priv->perf.oa.test_config.mux_regs = mux_config_test_oa;
> -	dev_priv->perf.oa.test_config.mux_regs_len = ARRAY_SIZE(mux_config_test_oa);
> +	dev_priv->perf.test_config.mux_regs = mux_config_test_oa;
> +	dev_priv->perf.test_config.mux_regs_len = ARRAY_SIZE(mux_config_test_oa);
>   
> -	dev_priv->perf.oa.test_config.b_counter_regs = b_counter_config_test_oa;
> -	dev_priv->perf.oa.test_config.b_counter_regs_len = ARRAY_SIZE(b_counter_config_test_oa);
> +	dev_priv->perf.test_config.b_counter_regs = b_counter_config_test_oa;
> +	dev_priv->perf.test_config.b_counter_regs_len = ARRAY_SIZE(b_counter_config_test_oa);
>   
> -	dev_priv->perf.oa.test_config.flex_regs = flex_eu_config_test_oa;
> -	dev_priv->perf.oa.test_config.flex_regs_len = ARRAY_SIZE(flex_eu_config_test_oa);
> +	dev_priv->perf.test_config.flex_regs = flex_eu_config_test_oa;
> +	dev_priv->perf.test_config.flex_regs_len = ARRAY_SIZE(flex_eu_config_test_oa);
>   
> -	dev_priv->perf.oa.test_config.sysfs_metric.name = "d6de6f55-e526-4f79-a6a6-d7315c09044e";
> -	dev_priv->perf.oa.test_config.sysfs_metric.attrs = dev_priv->perf.oa.test_config.attrs;
> +	dev_priv->perf.test_config.sysfs_metric.name = "d6de6f55-e526-4f79-a6a6-d7315c09044e";
> +	dev_priv->perf.test_config.sysfs_metric.attrs = dev_priv->perf.test_config.attrs;
>   
> -	dev_priv->perf.oa.test_config.attrs[0] = &dev_priv->perf.oa.test_config.sysfs_metric_id.attr;
> +	dev_priv->perf.test_config.attrs[0] = &dev_priv->perf.test_config.sysfs_metric_id.attr;
>   
> -	dev_priv->perf.oa.test_config.sysfs_metric_id.attr.name = "id";
> -	dev_priv->perf.oa.test_config.sysfs_metric_id.attr.mode = 0444;
> -	dev_priv->perf.oa.test_config.sysfs_metric_id.show = show_test_oa_id;
> +	dev_priv->perf.test_config.sysfs_metric_id.attr.name = "id";
> +	dev_priv->perf.test_config.sysfs_metric_id.attr.mode = 0444;
> +	dev_priv->perf.test_config.sysfs_metric_id.show = show_test_oa_id;
>   }
> diff --git a/drivers/gpu/drm/i915/i915_oa_bxt.c b/drivers/gpu/drm/i915/i915_oa_bxt.c
> index a44195c39923..a4cc584fb5c9 100644
> --- a/drivers/gpu/drm/i915/i915_oa_bxt.c
> +++ b/drivers/gpu/drm/i915/i915_oa_bxt.c
> @@ -64,26 +64,26 @@ show_test_oa_id(struct device *kdev, struct device_attribute *attr, char *buf)
>   void
>   i915_perf_load_test_config_bxt(struct drm_i915_private *dev_priv)
>   {
> -	strlcpy(dev_priv->perf.oa.test_config.uuid,
> +	strlcpy(dev_priv->perf.test_config.uuid,
>   		"5ee72f5c-092f-421e-8b70-225f7c3e9612",
> -		sizeof(dev_priv->perf.oa.test_config.uuid));
> -	dev_priv->perf.oa.test_config.id = 1;
> +		sizeof(dev_priv->perf.test_config.uuid));
> +	dev_priv->perf.test_config.id = 1;
>   
> -	dev_priv->perf.oa.test_config.mux_regs = mux_config_test_oa;
> -	dev_priv->perf.oa.test_config.mux_regs_len = ARRAY_SIZE(mux_config_test_oa);
> +	dev_priv->perf.test_config.mux_regs = mux_config_test_oa;
> +	dev_priv->perf.test_config.mux_regs_len = ARRAY_SIZE(mux_config_test_oa);
>   
> -	dev_priv->perf.oa.test_config.b_counter_regs = b_counter_config_test_oa;
> -	dev_priv->perf.oa.test_config.b_counter_regs_len = ARRAY_SIZE(b_counter_config_test_oa);
> +	dev_priv->perf.test_config.b_counter_regs = b_counter_config_test_oa;
> +	dev_priv->perf.test_config.b_counter_regs_len = ARRAY_SIZE(b_counter_config_test_oa);
>   
> -	dev_priv->perf.oa.test_config.flex_regs = flex_eu_config_test_oa;
> -	dev_priv->perf.oa.test_config.flex_regs_len = ARRAY_SIZE(flex_eu_config_test_oa);
> +	dev_priv->perf.test_config.flex_regs = flex_eu_config_test_oa;
> +	dev_priv->perf.test_config.flex_regs_len = ARRAY_SIZE(flex_eu_config_test_oa);
>   
> -	dev_priv->perf.oa.test_config.sysfs_metric.name = "5ee72f5c-092f-421e-8b70-225f7c3e9612";
> -	dev_priv->perf.oa.test_config.sysfs_metric.attrs = dev_priv->perf.oa.test_config.attrs;
> +	dev_priv->perf.test_config.sysfs_metric.name = "5ee72f5c-092f-421e-8b70-225f7c3e9612";
> +	dev_priv->perf.test_config.sysfs_metric.attrs = dev_priv->perf.test_config.attrs;
>   
> -	dev_priv->perf.oa.test_config.attrs[0] = &dev_priv->perf.oa.test_config.sysfs_metric_id.attr;
> +	dev_priv->perf.test_config.attrs[0] = &dev_priv->perf.test_config.sysfs_metric_id.attr;
>   
> -	dev_priv->perf.oa.test_config.sysfs_metric_id.attr.name = "id";
> -	dev_priv->perf.oa.test_config.sysfs_metric_id.attr.mode = 0444;
> -	dev_priv->perf.oa.test_config.sysfs_metric_id.show = show_test_oa_id;
> +	dev_priv->perf.test_config.sysfs_metric_id.attr.name = "id";
> +	dev_priv->perf.test_config.sysfs_metric_id.attr.mode = 0444;
> +	dev_priv->perf.test_config.sysfs_metric_id.show = show_test_oa_id;
>   }
> diff --git a/drivers/gpu/drm/i915/i915_oa_cflgt2.c b/drivers/gpu/drm/i915/i915_oa_cflgt2.c
> index 7f60d51b8761..51930c71bf7c 100644
> --- a/drivers/gpu/drm/i915/i915_oa_cflgt2.c
> +++ b/drivers/gpu/drm/i915/i915_oa_cflgt2.c
> @@ -65,26 +65,26 @@ show_test_oa_id(struct device *kdev, struct device_attribute *attr, char *buf)
>   void
>   i915_perf_load_test_config_cflgt2(struct drm_i915_private *dev_priv)
>   {
> -	strlcpy(dev_priv->perf.oa.test_config.uuid,
> +	strlcpy(dev_priv->perf.test_config.uuid,
>   		"74fb4902-d3d3-4237-9e90-cbdc68d0a446",
> -		sizeof(dev_priv->perf.oa.test_config.uuid));
> -	dev_priv->perf.oa.test_config.id = 1;
> +		sizeof(dev_priv->perf.test_config.uuid));
> +	dev_priv->perf.test_config.id = 1;
>   
> -	dev_priv->perf.oa.test_config.mux_regs = mux_config_test_oa;
> -	dev_priv->perf.oa.test_config.mux_regs_len = ARRAY_SIZE(mux_config_test_oa);
> +	dev_priv->perf.test_config.mux_regs = mux_config_test_oa;
> +	dev_priv->perf.test_config.mux_regs_len = ARRAY_SIZE(mux_config_test_oa);
>   
> -	dev_priv->perf.oa.test_config.b_counter_regs = b_counter_config_test_oa;
> -	dev_priv->perf.oa.test_config.b_counter_regs_len = ARRAY_SIZE(b_counter_config_test_oa);
> +	dev_priv->perf.test_config.b_counter_regs = b_counter_config_test_oa;
> +	dev_priv->perf.test_config.b_counter_regs_len = ARRAY_SIZE(b_counter_config_test_oa);
>   
> -	dev_priv->perf.oa.test_config.flex_regs = flex_eu_config_test_oa;
> -	dev_priv->perf.oa.test_config.flex_regs_len = ARRAY_SIZE(flex_eu_config_test_oa);
> +	dev_priv->perf.test_config.flex_regs = flex_eu_config_test_oa;
> +	dev_priv->perf.test_config.flex_regs_len = ARRAY_SIZE(flex_eu_config_test_oa);
>   
> -	dev_priv->perf.oa.test_config.sysfs_metric.name = "74fb4902-d3d3-4237-9e90-cbdc68d0a446";
> -	dev_priv->perf.oa.test_config.sysfs_metric.attrs = dev_priv->perf.oa.test_config.attrs;
> +	dev_priv->perf.test_config.sysfs_metric.name = "74fb4902-d3d3-4237-9e90-cbdc68d0a446";
> +	dev_priv->perf.test_config.sysfs_metric.attrs = dev_priv->perf.test_config.attrs;
>   
> -	dev_priv->perf.oa.test_config.attrs[0] = &dev_priv->perf.oa.test_config.sysfs_metric_id.attr;
> +	dev_priv->perf.test_config.attrs[0] = &dev_priv->perf.test_config.sysfs_metric_id.attr;
>   
> -	dev_priv->perf.oa.test_config.sysfs_metric_id.attr.name = "id";
> -	dev_priv->perf.oa.test_config.sysfs_metric_id.attr.mode = 0444;
> -	dev_priv->perf.oa.test_config.sysfs_metric_id.show = show_test_oa_id;
> +	dev_priv->perf.test_config.sysfs_metric_id.attr.name = "id";
> +	dev_priv->perf.test_config.sysfs_metric_id.attr.mode = 0444;
> +	dev_priv->perf.test_config.sysfs_metric_id.show = show_test_oa_id;
>   }
> diff --git a/drivers/gpu/drm/i915/i915_oa_cflgt3.c b/drivers/gpu/drm/i915/i915_oa_cflgt3.c
> index a92c38e3a0ce..de630b53d364 100644
> --- a/drivers/gpu/drm/i915/i915_oa_cflgt3.c
> +++ b/drivers/gpu/drm/i915/i915_oa_cflgt3.c
> @@ -65,26 +65,26 @@ show_test_oa_id(struct device *kdev, struct device_attribute *attr, char *buf)
>   void
>   i915_perf_load_test_config_cflgt3(struct drm_i915_private *dev_priv)
>   {
> -	strlcpy(dev_priv->perf.oa.test_config.uuid,
> +	strlcpy(dev_priv->perf.test_config.uuid,
>   		"577e8e2c-3fa0-4875-8743-3538d585e3b0",
> -		sizeof(dev_priv->perf.oa.test_config.uuid));
> -	dev_priv->perf.oa.test_config.id = 1;
> +		sizeof(dev_priv->perf.test_config.uuid));
> +	dev_priv->perf.test_config.id = 1;
>   
> -	dev_priv->perf.oa.test_config.mux_regs = mux_config_test_oa;
> -	dev_priv->perf.oa.test_config.mux_regs_len = ARRAY_SIZE(mux_config_test_oa);
> +	dev_priv->perf.test_config.mux_regs = mux_config_test_oa;
> +	dev_priv->perf.test_config.mux_regs_len = ARRAY_SIZE(mux_config_test_oa);
>   
> -	dev_priv->perf.oa.test_config.b_counter_regs = b_counter_config_test_oa;
> -	dev_priv->perf.oa.test_config.b_counter_regs_len = ARRAY_SIZE(b_counter_config_test_oa);
> +	dev_priv->perf.test_config.b_counter_regs = b_counter_config_test_oa;
> +	dev_priv->perf.test_config.b_counter_regs_len = ARRAY_SIZE(b_counter_config_test_oa);
>   
> -	dev_priv->perf.oa.test_config.flex_regs = flex_eu_config_test_oa;
> -	dev_priv->perf.oa.test_config.flex_regs_len = ARRAY_SIZE(flex_eu_config_test_oa);
> +	dev_priv->perf.test_config.flex_regs = flex_eu_config_test_oa;
> +	dev_priv->perf.test_config.flex_regs_len = ARRAY_SIZE(flex_eu_config_test_oa);
>   
> -	dev_priv->perf.oa.test_config.sysfs_metric.name = "577e8e2c-3fa0-4875-8743-3538d585e3b0";
> -	dev_priv->perf.oa.test_config.sysfs_metric.attrs = dev_priv->perf.oa.test_config.attrs;
> +	dev_priv->perf.test_config.sysfs_metric.name = "577e8e2c-3fa0-4875-8743-3538d585e3b0";
> +	dev_priv->perf.test_config.sysfs_metric.attrs = dev_priv->perf.test_config.attrs;
>   
> -	dev_priv->perf.oa.test_config.attrs[0] = &dev_priv->perf.oa.test_config.sysfs_metric_id.attr;
> +	dev_priv->perf.test_config.attrs[0] = &dev_priv->perf.test_config.sysfs_metric_id.attr;
>   
> -	dev_priv->perf.oa.test_config.sysfs_metric_id.attr.name = "id";
> -	dev_priv->perf.oa.test_config.sysfs_metric_id.attr.mode = 0444;
> -	dev_priv->perf.oa.test_config.sysfs_metric_id.show = show_test_oa_id;
> +	dev_priv->perf.test_config.sysfs_metric_id.attr.name = "id";
> +	dev_priv->perf.test_config.sysfs_metric_id.attr.mode = 0444;
> +	dev_priv->perf.test_config.sysfs_metric_id.show = show_test_oa_id;
>   }
> diff --git a/drivers/gpu/drm/i915/i915_oa_chv.c b/drivers/gpu/drm/i915/i915_oa_chv.c
> index 71ec889a0114..7d7f33c4468f 100644
> --- a/drivers/gpu/drm/i915/i915_oa_chv.c
> +++ b/drivers/gpu/drm/i915/i915_oa_chv.c
> @@ -65,26 +65,26 @@ show_test_oa_id(struct device *kdev, struct device_attribute *attr, char *buf)
>   void
>   i915_perf_load_test_config_chv(struct drm_i915_private *dev_priv)
>   {
> -	strlcpy(dev_priv->perf.oa.test_config.uuid,
> +	strlcpy(dev_priv->perf.test_config.uuid,
>   		"4a534b07-cba3-414d-8d60-874830e883aa",
> -		sizeof(dev_priv->perf.oa.test_config.uuid));
> -	dev_priv->perf.oa.test_config.id = 1;
> +		sizeof(dev_priv->perf.test_config.uuid));
> +	dev_priv->perf.test_config.id = 1;
>   
> -	dev_priv->perf.oa.test_config.mux_regs = mux_config_test_oa;
> -	dev_priv->perf.oa.test_config.mux_regs_len = ARRAY_SIZE(mux_config_test_oa);
> +	dev_priv->perf.test_config.mux_regs = mux_config_test_oa;
> +	dev_priv->perf.test_config.mux_regs_len = ARRAY_SIZE(mux_config_test_oa);
>   
> -	dev_priv->perf.oa.test_config.b_counter_regs = b_counter_config_test_oa;
> -	dev_priv->perf.oa.test_config.b_counter_regs_len = ARRAY_SIZE(b_counter_config_test_oa);
> +	dev_priv->perf.test_config.b_counter_regs = b_counter_config_test_oa;
> +	dev_priv->perf.test_config.b_counter_regs_len = ARRAY_SIZE(b_counter_config_test_oa);
>   
> -	dev_priv->perf.oa.test_config.flex_regs = flex_eu_config_test_oa;
> -	dev_priv->perf.oa.test_config.flex_regs_len = ARRAY_SIZE(flex_eu_config_test_oa);
> +	dev_priv->perf.test_config.flex_regs = flex_eu_config_test_oa;
> +	dev_priv->perf.test_config.flex_regs_len = ARRAY_SIZE(flex_eu_config_test_oa);
>   
> -	dev_priv->perf.oa.test_config.sysfs_metric.name = "4a534b07-cba3-414d-8d60-874830e883aa";
> -	dev_priv->perf.oa.test_config.sysfs_metric.attrs = dev_priv->perf.oa.test_config.attrs;
> +	dev_priv->perf.test_config.sysfs_metric.name = "4a534b07-cba3-414d-8d60-874830e883aa";
> +	dev_priv->perf.test_config.sysfs_metric.attrs = dev_priv->perf.test_config.attrs;
>   
> -	dev_priv->perf.oa.test_config.attrs[0] = &dev_priv->perf.oa.test_config.sysfs_metric_id.attr;
> +	dev_priv->perf.test_config.attrs[0] = &dev_priv->perf.test_config.sysfs_metric_id.attr;
>   
> -	dev_priv->perf.oa.test_config.sysfs_metric_id.attr.name = "id";
> -	dev_priv->perf.oa.test_config.sysfs_metric_id.attr.mode = 0444;
> -	dev_priv->perf.oa.test_config.sysfs_metric_id.show = show_test_oa_id;
> +	dev_priv->perf.test_config.sysfs_metric_id.attr.name = "id";
> +	dev_priv->perf.test_config.sysfs_metric_id.attr.mode = 0444;
> +	dev_priv->perf.test_config.sysfs_metric_id.show = show_test_oa_id;
>   }
> diff --git a/drivers/gpu/drm/i915/i915_oa_cnl.c b/drivers/gpu/drm/i915/i915_oa_cnl.c
> index 5c23d883d6c9..4ae86a8983c3 100644
> --- a/drivers/gpu/drm/i915/i915_oa_cnl.c
> +++ b/drivers/gpu/drm/i915/i915_oa_cnl.c
> @@ -77,26 +77,26 @@ show_test_oa_id(struct device *kdev, struct device_attribute *attr, char *buf)
>   void
>   i915_perf_load_test_config_cnl(struct drm_i915_private *dev_priv)
>   {
> -	strlcpy(dev_priv->perf.oa.test_config.uuid,
> +	strlcpy(dev_priv->perf.test_config.uuid,
>   		"db41edd4-d8e7-4730-ad11-b9a2d6833503",
> -		sizeof(dev_priv->perf.oa.test_config.uuid));
> -	dev_priv->perf.oa.test_config.id = 1;
> +		sizeof(dev_priv->perf.test_config.uuid));
> +	dev_priv->perf.test_config.id = 1;
>   
> -	dev_priv->perf.oa.test_config.mux_regs = mux_config_test_oa;
> -	dev_priv->perf.oa.test_config.mux_regs_len = ARRAY_SIZE(mux_config_test_oa);
> +	dev_priv->perf.test_config.mux_regs = mux_config_test_oa;
> +	dev_priv->perf.test_config.mux_regs_len = ARRAY_SIZE(mux_config_test_oa);
>   
> -	dev_priv->perf.oa.test_config.b_counter_regs = b_counter_config_test_oa;
> -	dev_priv->perf.oa.test_config.b_counter_regs_len = ARRAY_SIZE(b_counter_config_test_oa);
> +	dev_priv->perf.test_config.b_counter_regs = b_counter_config_test_oa;
> +	dev_priv->perf.test_config.b_counter_regs_len = ARRAY_SIZE(b_counter_config_test_oa);
>   
> -	dev_priv->perf.oa.test_config.flex_regs = flex_eu_config_test_oa;
> -	dev_priv->perf.oa.test_config.flex_regs_len = ARRAY_SIZE(flex_eu_config_test_oa);
> +	dev_priv->perf.test_config.flex_regs = flex_eu_config_test_oa;
> +	dev_priv->perf.test_config.flex_regs_len = ARRAY_SIZE(flex_eu_config_test_oa);
>   
> -	dev_priv->perf.oa.test_config.sysfs_metric.name = "db41edd4-d8e7-4730-ad11-b9a2d6833503";
> -	dev_priv->perf.oa.test_config.sysfs_metric.attrs = dev_priv->perf.oa.test_config.attrs;
> +	dev_priv->perf.test_config.sysfs_metric.name = "db41edd4-d8e7-4730-ad11-b9a2d6833503";
> +	dev_priv->perf.test_config.sysfs_metric.attrs = dev_priv->perf.test_config.attrs;
>   
> -	dev_priv->perf.oa.test_config.attrs[0] = &dev_priv->perf.oa.test_config.sysfs_metric_id.attr;
> +	dev_priv->perf.test_config.attrs[0] = &dev_priv->perf.test_config.sysfs_metric_id.attr;
>   
> -	dev_priv->perf.oa.test_config.sysfs_metric_id.attr.name = "id";
> -	dev_priv->perf.oa.test_config.sysfs_metric_id.attr.mode = 0444;
> -	dev_priv->perf.oa.test_config.sysfs_metric_id.show = show_test_oa_id;
> +	dev_priv->perf.test_config.sysfs_metric_id.attr.name = "id";
> +	dev_priv->perf.test_config.sysfs_metric_id.attr.mode = 0444;
> +	dev_priv->perf.test_config.sysfs_metric_id.show = show_test_oa_id;
>   }
> diff --git a/drivers/gpu/drm/i915/i915_oa_glk.c b/drivers/gpu/drm/i915/i915_oa_glk.c
> index 4bdda66df7d2..d8d634dca158 100644
> --- a/drivers/gpu/drm/i915/i915_oa_glk.c
> +++ b/drivers/gpu/drm/i915/i915_oa_glk.c
> @@ -64,26 +64,26 @@ show_test_oa_id(struct device *kdev, struct device_attribute *attr, char *buf)
>   void
>   i915_perf_load_test_config_glk(struct drm_i915_private *dev_priv)
>   {
> -	strlcpy(dev_priv->perf.oa.test_config.uuid,
> +	strlcpy(dev_priv->perf.test_config.uuid,
>   		"dd3fd789-e783-4204-8cd0-b671bbccb0cf",
> -		sizeof(dev_priv->perf.oa.test_config.uuid));
> -	dev_priv->perf.oa.test_config.id = 1;
> +		sizeof(dev_priv->perf.test_config.uuid));
> +	dev_priv->perf.test_config.id = 1;
>   
> -	dev_priv->perf.oa.test_config.mux_regs = mux_config_test_oa;
> -	dev_priv->perf.oa.test_config.mux_regs_len = ARRAY_SIZE(mux_config_test_oa);
> +	dev_priv->perf.test_config.mux_regs = mux_config_test_oa;
> +	dev_priv->perf.test_config.mux_regs_len = ARRAY_SIZE(mux_config_test_oa);
>   
> -	dev_priv->perf.oa.test_config.b_counter_regs = b_counter_config_test_oa;
> -	dev_priv->perf.oa.test_config.b_counter_regs_len = ARRAY_SIZE(b_counter_config_test_oa);
> +	dev_priv->perf.test_config.b_counter_regs = b_counter_config_test_oa;
> +	dev_priv->perf.test_config.b_counter_regs_len = ARRAY_SIZE(b_counter_config_test_oa);
>   
> -	dev_priv->perf.oa.test_config.flex_regs = flex_eu_config_test_oa;
> -	dev_priv->perf.oa.test_config.flex_regs_len = ARRAY_SIZE(flex_eu_config_test_oa);
> +	dev_priv->perf.test_config.flex_regs = flex_eu_config_test_oa;
> +	dev_priv->perf.test_config.flex_regs_len = ARRAY_SIZE(flex_eu_config_test_oa);
>   
> -	dev_priv->perf.oa.test_config.sysfs_metric.name = "dd3fd789-e783-4204-8cd0-b671bbccb0cf";
> -	dev_priv->perf.oa.test_config.sysfs_metric.attrs = dev_priv->perf.oa.test_config.attrs;
> +	dev_priv->perf.test_config.sysfs_metric.name = "dd3fd789-e783-4204-8cd0-b671bbccb0cf";
> +	dev_priv->perf.test_config.sysfs_metric.attrs = dev_priv->perf.test_config.attrs;
>   
> -	dev_priv->perf.oa.test_config.attrs[0] = &dev_priv->perf.oa.test_config.sysfs_metric_id.attr;
> +	dev_priv->perf.test_config.attrs[0] = &dev_priv->perf.test_config.sysfs_metric_id.attr;
>   
> -	dev_priv->perf.oa.test_config.sysfs_metric_id.attr.name = "id";
> -	dev_priv->perf.oa.test_config.sysfs_metric_id.attr.mode = 0444;
> -	dev_priv->perf.oa.test_config.sysfs_metric_id.show = show_test_oa_id;
> +	dev_priv->perf.test_config.sysfs_metric_id.attr.name = "id";
> +	dev_priv->perf.test_config.sysfs_metric_id.attr.mode = 0444;
> +	dev_priv->perf.test_config.sysfs_metric_id.show = show_test_oa_id;
>   }
> diff --git a/drivers/gpu/drm/i915/i915_oa_hsw.c b/drivers/gpu/drm/i915/i915_oa_hsw.c
> index cc6526fdd2bd..7032277876db 100644
> --- a/drivers/gpu/drm/i915/i915_oa_hsw.c
> +++ b/drivers/gpu/drm/i915/i915_oa_hsw.c
> @@ -94,26 +94,26 @@ show_render_basic_id(struct device *kdev, struct device_attribute *attr, char *b
>   void
>   i915_perf_load_test_config_hsw(struct drm_i915_private *dev_priv)
>   {
> -	strlcpy(dev_priv->perf.oa.test_config.uuid,
> +	strlcpy(dev_priv->perf.test_config.uuid,
>   		"403d8832-1a27-4aa6-a64e-f5389ce7b212",
> -		sizeof(dev_priv->perf.oa.test_config.uuid));
> -	dev_priv->perf.oa.test_config.id = 1;
> +		sizeof(dev_priv->perf.test_config.uuid));
> +	dev_priv->perf.test_config.id = 1;
>   
> -	dev_priv->perf.oa.test_config.mux_regs = mux_config_render_basic;
> -	dev_priv->perf.oa.test_config.mux_regs_len = ARRAY_SIZE(mux_config_render_basic);
> +	dev_priv->perf.test_config.mux_regs = mux_config_render_basic;
> +	dev_priv->perf.test_config.mux_regs_len = ARRAY_SIZE(mux_config_render_basic);
>   
> -	dev_priv->perf.oa.test_config.b_counter_regs = b_counter_config_render_basic;
> -	dev_priv->perf.oa.test_config.b_counter_regs_len = ARRAY_SIZE(b_counter_config_render_basic);
> +	dev_priv->perf.test_config.b_counter_regs = b_counter_config_render_basic;
> +	dev_priv->perf.test_config.b_counter_regs_len = ARRAY_SIZE(b_counter_config_render_basic);
>   
> -	dev_priv->perf.oa.test_config.flex_regs = flex_eu_config_render_basic;
> -	dev_priv->perf.oa.test_config.flex_regs_len = ARRAY_SIZE(flex_eu_config_render_basic);
> +	dev_priv->perf.test_config.flex_regs = flex_eu_config_render_basic;
> +	dev_priv->perf.test_config.flex_regs_len = ARRAY_SIZE(flex_eu_config_render_basic);
>   
> -	dev_priv->perf.oa.test_config.sysfs_metric.name = "403d8832-1a27-4aa6-a64e-f5389ce7b212";
> -	dev_priv->perf.oa.test_config.sysfs_metric.attrs = dev_priv->perf.oa.test_config.attrs;
> +	dev_priv->perf.test_config.sysfs_metric.name = "403d8832-1a27-4aa6-a64e-f5389ce7b212";
> +	dev_priv->perf.test_config.sysfs_metric.attrs = dev_priv->perf.test_config.attrs;
>   
> -	dev_priv->perf.oa.test_config.attrs[0] = &dev_priv->perf.oa.test_config.sysfs_metric_id.attr;
> +	dev_priv->perf.test_config.attrs[0] = &dev_priv->perf.test_config.sysfs_metric_id.attr;
>   
> -	dev_priv->perf.oa.test_config.sysfs_metric_id.attr.name = "id";
> -	dev_priv->perf.oa.test_config.sysfs_metric_id.attr.mode = 0444;
> -	dev_priv->perf.oa.test_config.sysfs_metric_id.show = show_render_basic_id;
> +	dev_priv->perf.test_config.sysfs_metric_id.attr.name = "id";
> +	dev_priv->perf.test_config.sysfs_metric_id.attr.mode = 0444;
> +	dev_priv->perf.test_config.sysfs_metric_id.show = show_render_basic_id;
>   }
> diff --git a/drivers/gpu/drm/i915/i915_oa_icl.c b/drivers/gpu/drm/i915/i915_oa_icl.c
> index baa51427a543..bca23f150626 100644
> --- a/drivers/gpu/drm/i915/i915_oa_icl.c
> +++ b/drivers/gpu/drm/i915/i915_oa_icl.c
> @@ -74,26 +74,26 @@ show_test_oa_id(struct device *kdev, struct device_attribute *attr, char *buf)
>   void
>   i915_perf_load_test_config_icl(struct drm_i915_private *dev_priv)
>   {
> -	strlcpy(dev_priv->perf.oa.test_config.uuid,
> +	strlcpy(dev_priv->perf.test_config.uuid,
>   		"a291665e-244b-4b76-9b9a-01de9d3c8068",
> -		sizeof(dev_priv->perf.oa.test_config.uuid));
> -	dev_priv->perf.oa.test_config.id = 1;
> +		sizeof(dev_priv->perf.test_config.uuid));
> +	dev_priv->perf.test_config.id = 1;
>   
> -	dev_priv->perf.oa.test_config.mux_regs = mux_config_test_oa;
> -	dev_priv->perf.oa.test_config.mux_regs_len = ARRAY_SIZE(mux_config_test_oa);
> +	dev_priv->perf.test_config.mux_regs = mux_config_test_oa;
> +	dev_priv->perf.test_config.mux_regs_len = ARRAY_SIZE(mux_config_test_oa);
>   
> -	dev_priv->perf.oa.test_config.b_counter_regs = b_counter_config_test_oa;
> -	dev_priv->perf.oa.test_config.b_counter_regs_len = ARRAY_SIZE(b_counter_config_test_oa);
> +	dev_priv->perf.test_config.b_counter_regs = b_counter_config_test_oa;
> +	dev_priv->perf.test_config.b_counter_regs_len = ARRAY_SIZE(b_counter_config_test_oa);
>   
> -	dev_priv->perf.oa.test_config.flex_regs = flex_eu_config_test_oa;
> -	dev_priv->perf.oa.test_config.flex_regs_len = ARRAY_SIZE(flex_eu_config_test_oa);
> +	dev_priv->perf.test_config.flex_regs = flex_eu_config_test_oa;
> +	dev_priv->perf.test_config.flex_regs_len = ARRAY_SIZE(flex_eu_config_test_oa);
>   
> -	dev_priv->perf.oa.test_config.sysfs_metric.name = "a291665e-244b-4b76-9b9a-01de9d3c8068";
> -	dev_priv->perf.oa.test_config.sysfs_metric.attrs = dev_priv->perf.oa.test_config.attrs;
> +	dev_priv->perf.test_config.sysfs_metric.name = "a291665e-244b-4b76-9b9a-01de9d3c8068";
> +	dev_priv->perf.test_config.sysfs_metric.attrs = dev_priv->perf.test_config.attrs;
>   
> -	dev_priv->perf.oa.test_config.attrs[0] = &dev_priv->perf.oa.test_config.sysfs_metric_id.attr;
> +	dev_priv->perf.test_config.attrs[0] = &dev_priv->perf.test_config.sysfs_metric_id.attr;
>   
> -	dev_priv->perf.oa.test_config.sysfs_metric_id.attr.name = "id";
> -	dev_priv->perf.oa.test_config.sysfs_metric_id.attr.mode = 0444;
> -	dev_priv->perf.oa.test_config.sysfs_metric_id.show = show_test_oa_id;
> +	dev_priv->perf.test_config.sysfs_metric_id.attr.name = "id";
> +	dev_priv->perf.test_config.sysfs_metric_id.attr.mode = 0444;
> +	dev_priv->perf.test_config.sysfs_metric_id.show = show_test_oa_id;
>   }
> diff --git a/drivers/gpu/drm/i915/i915_oa_kblgt2.c b/drivers/gpu/drm/i915/i915_oa_kblgt2.c
> index 168e49ab0d4d..2e1d12f78c9b 100644
> --- a/drivers/gpu/drm/i915/i915_oa_kblgt2.c
> +++ b/drivers/gpu/drm/i915/i915_oa_kblgt2.c
> @@ -65,26 +65,26 @@ show_test_oa_id(struct device *kdev, struct device_attribute *attr, char *buf)
>   void
>   i915_perf_load_test_config_kblgt2(struct drm_i915_private *dev_priv)
>   {
> -	strlcpy(dev_priv->perf.oa.test_config.uuid,
> +	strlcpy(dev_priv->perf.test_config.uuid,
>   		"baa3c7e4-52b6-4b85-801e-465a94b746dd",
> -		sizeof(dev_priv->perf.oa.test_config.uuid));
> -	dev_priv->perf.oa.test_config.id = 1;
> +		sizeof(dev_priv->perf.test_config.uuid));
> +	dev_priv->perf.test_config.id = 1;
>   
> -	dev_priv->perf.oa.test_config.mux_regs = mux_config_test_oa;
> -	dev_priv->perf.oa.test_config.mux_regs_len = ARRAY_SIZE(mux_config_test_oa);
> +	dev_priv->perf.test_config.mux_regs = mux_config_test_oa;
> +	dev_priv->perf.test_config.mux_regs_len = ARRAY_SIZE(mux_config_test_oa);
>   
> -	dev_priv->perf.oa.test_config.b_counter_regs = b_counter_config_test_oa;
> -	dev_priv->perf.oa.test_config.b_counter_regs_len = ARRAY_SIZE(b_counter_config_test_oa);
> +	dev_priv->perf.test_config.b_counter_regs = b_counter_config_test_oa;
> +	dev_priv->perf.test_config.b_counter_regs_len = ARRAY_SIZE(b_counter_config_test_oa);
>   
> -	dev_priv->perf.oa.test_config.flex_regs = flex_eu_config_test_oa;
> -	dev_priv->perf.oa.test_config.flex_regs_len = ARRAY_SIZE(flex_eu_config_test_oa);
> +	dev_priv->perf.test_config.flex_regs = flex_eu_config_test_oa;
> +	dev_priv->perf.test_config.flex_regs_len = ARRAY_SIZE(flex_eu_config_test_oa);
>   
> -	dev_priv->perf.oa.test_config.sysfs_metric.name = "baa3c7e4-52b6-4b85-801e-465a94b746dd";
> -	dev_priv->perf.oa.test_config.sysfs_metric.attrs = dev_priv->perf.oa.test_config.attrs;
> +	dev_priv->perf.test_config.sysfs_metric.name = "baa3c7e4-52b6-4b85-801e-465a94b746dd";
> +	dev_priv->perf.test_config.sysfs_metric.attrs = dev_priv->perf.test_config.attrs;
>   
> -	dev_priv->perf.oa.test_config.attrs[0] = &dev_priv->perf.oa.test_config.sysfs_metric_id.attr;
> +	dev_priv->perf.test_config.attrs[0] = &dev_priv->perf.test_config.sysfs_metric_id.attr;
>   
> -	dev_priv->perf.oa.test_config.sysfs_metric_id.attr.name = "id";
> -	dev_priv->perf.oa.test_config.sysfs_metric_id.attr.mode = 0444;
> -	dev_priv->perf.oa.test_config.sysfs_metric_id.show = show_test_oa_id;
> +	dev_priv->perf.test_config.sysfs_metric_id.attr.name = "id";
> +	dev_priv->perf.test_config.sysfs_metric_id.attr.mode = 0444;
> +	dev_priv->perf.test_config.sysfs_metric_id.show = show_test_oa_id;
>   }
> diff --git a/drivers/gpu/drm/i915/i915_oa_kblgt3.c b/drivers/gpu/drm/i915/i915_oa_kblgt3.c
> index 6ffa553c388e..07a8567bd5be 100644
> --- a/drivers/gpu/drm/i915/i915_oa_kblgt3.c
> +++ b/drivers/gpu/drm/i915/i915_oa_kblgt3.c
> @@ -65,26 +65,26 @@ show_test_oa_id(struct device *kdev, struct device_attribute *attr, char *buf)
>   void
>   i915_perf_load_test_config_kblgt3(struct drm_i915_private *dev_priv)
>   {
> -	strlcpy(dev_priv->perf.oa.test_config.uuid,
> +	strlcpy(dev_priv->perf.test_config.uuid,
>   		"f1792f32-6db2-4b50-b4b2-557128f1688d",
> -		sizeof(dev_priv->perf.oa.test_config.uuid));
> -	dev_priv->perf.oa.test_config.id = 1;
> +		sizeof(dev_priv->perf.test_config.uuid));
> +	dev_priv->perf.test_config.id = 1;
>   
> -	dev_priv->perf.oa.test_config.mux_regs = mux_config_test_oa;
> -	dev_priv->perf.oa.test_config.mux_regs_len = ARRAY_SIZE(mux_config_test_oa);
> +	dev_priv->perf.test_config.mux_regs = mux_config_test_oa;
> +	dev_priv->perf.test_config.mux_regs_len = ARRAY_SIZE(mux_config_test_oa);
>   
> -	dev_priv->perf.oa.test_config.b_counter_regs = b_counter_config_test_oa;
> -	dev_priv->perf.oa.test_config.b_counter_regs_len = ARRAY_SIZE(b_counter_config_test_oa);
> +	dev_priv->perf.test_config.b_counter_regs = b_counter_config_test_oa;
> +	dev_priv->perf.test_config.b_counter_regs_len = ARRAY_SIZE(b_counter_config_test_oa);
>   
> -	dev_priv->perf.oa.test_config.flex_regs = flex_eu_config_test_oa;
> -	dev_priv->perf.oa.test_config.flex_regs_len = ARRAY_SIZE(flex_eu_config_test_oa);
> +	dev_priv->perf.test_config.flex_regs = flex_eu_config_test_oa;
> +	dev_priv->perf.test_config.flex_regs_len = ARRAY_SIZE(flex_eu_config_test_oa);
>   
> -	dev_priv->perf.oa.test_config.sysfs_metric.name = "f1792f32-6db2-4b50-b4b2-557128f1688d";
> -	dev_priv->perf.oa.test_config.sysfs_metric.attrs = dev_priv->perf.oa.test_config.attrs;
> +	dev_priv->perf.test_config.sysfs_metric.name = "f1792f32-6db2-4b50-b4b2-557128f1688d";
> +	dev_priv->perf.test_config.sysfs_metric.attrs = dev_priv->perf.test_config.attrs;
>   
> -	dev_priv->perf.oa.test_config.attrs[0] = &dev_priv->perf.oa.test_config.sysfs_metric_id.attr;
> +	dev_priv->perf.test_config.attrs[0] = &dev_priv->perf.test_config.sysfs_metric_id.attr;
>   
> -	dev_priv->perf.oa.test_config.sysfs_metric_id.attr.name = "id";
> -	dev_priv->perf.oa.test_config.sysfs_metric_id.attr.mode = 0444;
> -	dev_priv->perf.oa.test_config.sysfs_metric_id.show = show_test_oa_id;
> +	dev_priv->perf.test_config.sysfs_metric_id.attr.name = "id";
> +	dev_priv->perf.test_config.sysfs_metric_id.attr.mode = 0444;
> +	dev_priv->perf.test_config.sysfs_metric_id.show = show_test_oa_id;
>   }
> diff --git a/drivers/gpu/drm/i915/i915_oa_sklgt2.c b/drivers/gpu/drm/i915/i915_oa_sklgt2.c
> index 7ce6ee851d43..fa463a92f5bb 100644
> --- a/drivers/gpu/drm/i915/i915_oa_sklgt2.c
> +++ b/drivers/gpu/drm/i915/i915_oa_sklgt2.c
> @@ -64,26 +64,26 @@ show_test_oa_id(struct device *kdev, struct device_attribute *attr, char *buf)
>   void
>   i915_perf_load_test_config_sklgt2(struct drm_i915_private *dev_priv)
>   {
> -	strlcpy(dev_priv->perf.oa.test_config.uuid,
> +	strlcpy(dev_priv->perf.test_config.uuid,
>   		"1651949f-0ac0-4cb1-a06f-dafd74a407d1",
> -		sizeof(dev_priv->perf.oa.test_config.uuid));
> -	dev_priv->perf.oa.test_config.id = 1;
> +		sizeof(dev_priv->perf.test_config.uuid));
> +	dev_priv->perf.test_config.id = 1;
>   
> -	dev_priv->perf.oa.test_config.mux_regs = mux_config_test_oa;
> -	dev_priv->perf.oa.test_config.mux_regs_len = ARRAY_SIZE(mux_config_test_oa);
> +	dev_priv->perf.test_config.mux_regs = mux_config_test_oa;
> +	dev_priv->perf.test_config.mux_regs_len = ARRAY_SIZE(mux_config_test_oa);
>   
> -	dev_priv->perf.oa.test_config.b_counter_regs = b_counter_config_test_oa;
> -	dev_priv->perf.oa.test_config.b_counter_regs_len = ARRAY_SIZE(b_counter_config_test_oa);
> +	dev_priv->perf.test_config.b_counter_regs = b_counter_config_test_oa;
> +	dev_priv->perf.test_config.b_counter_regs_len = ARRAY_SIZE(b_counter_config_test_oa);
>   
> -	dev_priv->perf.oa.test_config.flex_regs = flex_eu_config_test_oa;
> -	dev_priv->perf.oa.test_config.flex_regs_len = ARRAY_SIZE(flex_eu_config_test_oa);
> +	dev_priv->perf.test_config.flex_regs = flex_eu_config_test_oa;
> +	dev_priv->perf.test_config.flex_regs_len = ARRAY_SIZE(flex_eu_config_test_oa);
>   
> -	dev_priv->perf.oa.test_config.sysfs_metric.name = "1651949f-0ac0-4cb1-a06f-dafd74a407d1";
> -	dev_priv->perf.oa.test_config.sysfs_metric.attrs = dev_priv->perf.oa.test_config.attrs;
> +	dev_priv->perf.test_config.sysfs_metric.name = "1651949f-0ac0-4cb1-a06f-dafd74a407d1";
> +	dev_priv->perf.test_config.sysfs_metric.attrs = dev_priv->perf.test_config.attrs;
>   
> -	dev_priv->perf.oa.test_config.attrs[0] = &dev_priv->perf.oa.test_config.sysfs_metric_id.attr;
> +	dev_priv->perf.test_config.attrs[0] = &dev_priv->perf.test_config.sysfs_metric_id.attr;
>   
> -	dev_priv->perf.oa.test_config.sysfs_metric_id.attr.name = "id";
> -	dev_priv->perf.oa.test_config.sysfs_metric_id.attr.mode = 0444;
> -	dev_priv->perf.oa.test_config.sysfs_metric_id.show = show_test_oa_id;
> +	dev_priv->perf.test_config.sysfs_metric_id.attr.name = "id";
> +	dev_priv->perf.test_config.sysfs_metric_id.attr.mode = 0444;
> +	dev_priv->perf.test_config.sysfs_metric_id.show = show_test_oa_id;
>   }
> diff --git a/drivers/gpu/drm/i915/i915_oa_sklgt3.c b/drivers/gpu/drm/i915/i915_oa_sklgt3.c
> index 086ca2631e1c..9c9497d7a9d5 100644
> --- a/drivers/gpu/drm/i915/i915_oa_sklgt3.c
> +++ b/drivers/gpu/drm/i915/i915_oa_sklgt3.c
> @@ -65,26 +65,26 @@ show_test_oa_id(struct device *kdev, struct device_attribute *attr, char *buf)
>   void
>   i915_perf_load_test_config_sklgt3(struct drm_i915_private *dev_priv)
>   {
> -	strlcpy(dev_priv->perf.oa.test_config.uuid,
> +	strlcpy(dev_priv->perf.test_config.uuid,
>   		"2b985803-d3c9-4629-8a4f-634bfecba0e8",
> -		sizeof(dev_priv->perf.oa.test_config.uuid));
> -	dev_priv->perf.oa.test_config.id = 1;
> +		sizeof(dev_priv->perf.test_config.uuid));
> +	dev_priv->perf.test_config.id = 1;
>   
> -	dev_priv->perf.oa.test_config.mux_regs = mux_config_test_oa;
> -	dev_priv->perf.oa.test_config.mux_regs_len = ARRAY_SIZE(mux_config_test_oa);
> +	dev_priv->perf.test_config.mux_regs = mux_config_test_oa;
> +	dev_priv->perf.test_config.mux_regs_len = ARRAY_SIZE(mux_config_test_oa);
>   
> -	dev_priv->perf.oa.test_config.b_counter_regs = b_counter_config_test_oa;
> -	dev_priv->perf.oa.test_config.b_counter_regs_len = ARRAY_SIZE(b_counter_config_test_oa);
> +	dev_priv->perf.test_config.b_counter_regs = b_counter_config_test_oa;
> +	dev_priv->perf.test_config.b_counter_regs_len = ARRAY_SIZE(b_counter_config_test_oa);
>   
> -	dev_priv->perf.oa.test_config.flex_regs = flex_eu_config_test_oa;
> -	dev_priv->perf.oa.test_config.flex_regs_len = ARRAY_SIZE(flex_eu_config_test_oa);
> +	dev_priv->perf.test_config.flex_regs = flex_eu_config_test_oa;
> +	dev_priv->perf.test_config.flex_regs_len = ARRAY_SIZE(flex_eu_config_test_oa);
>   
> -	dev_priv->perf.oa.test_config.sysfs_metric.name = "2b985803-d3c9-4629-8a4f-634bfecba0e8";
> -	dev_priv->perf.oa.test_config.sysfs_metric.attrs = dev_priv->perf.oa.test_config.attrs;
> +	dev_priv->perf.test_config.sysfs_metric.name = "2b985803-d3c9-4629-8a4f-634bfecba0e8";
> +	dev_priv->perf.test_config.sysfs_metric.attrs = dev_priv->perf.test_config.attrs;
>   
> -	dev_priv->perf.oa.test_config.attrs[0] = &dev_priv->perf.oa.test_config.sysfs_metric_id.attr;
> +	dev_priv->perf.test_config.attrs[0] = &dev_priv->perf.test_config.sysfs_metric_id.attr;
>   
> -	dev_priv->perf.oa.test_config.sysfs_metric_id.attr.name = "id";
> -	dev_priv->perf.oa.test_config.sysfs_metric_id.attr.mode = 0444;
> -	dev_priv->perf.oa.test_config.sysfs_metric_id.show = show_test_oa_id;
> +	dev_priv->perf.test_config.sysfs_metric_id.attr.name = "id";
> +	dev_priv->perf.test_config.sysfs_metric_id.attr.mode = 0444;
> +	dev_priv->perf.test_config.sysfs_metric_id.show = show_test_oa_id;
>   }
> diff --git a/drivers/gpu/drm/i915/i915_oa_sklgt4.c b/drivers/gpu/drm/i915/i915_oa_sklgt4.c
> index b291a6eb8a87..65ebc6b8dd70 100644
> --- a/drivers/gpu/drm/i915/i915_oa_sklgt4.c
> +++ b/drivers/gpu/drm/i915/i915_oa_sklgt4.c
> @@ -65,26 +65,26 @@ show_test_oa_id(struct device *kdev, struct device_attribute *attr, char *buf)
>   void
>   i915_perf_load_test_config_sklgt4(struct drm_i915_private *dev_priv)
>   {
> -	strlcpy(dev_priv->perf.oa.test_config.uuid,
> +	strlcpy(dev_priv->perf.test_config.uuid,
>   		"882fa433-1f4a-4a67-a962-c741888fe5f5",
> -		sizeof(dev_priv->perf.oa.test_config.uuid));
> -	dev_priv->perf.oa.test_config.id = 1;
> +		sizeof(dev_priv->perf.test_config.uuid));
> +	dev_priv->perf.test_config.id = 1;
>   
> -	dev_priv->perf.oa.test_config.mux_regs = mux_config_test_oa;
> -	dev_priv->perf.oa.test_config.mux_regs_len = ARRAY_SIZE(mux_config_test_oa);
> +	dev_priv->perf.test_config.mux_regs = mux_config_test_oa;
> +	dev_priv->perf.test_config.mux_regs_len = ARRAY_SIZE(mux_config_test_oa);
>   
> -	dev_priv->perf.oa.test_config.b_counter_regs = b_counter_config_test_oa;
> -	dev_priv->perf.oa.test_config.b_counter_regs_len = ARRAY_SIZE(b_counter_config_test_oa);
> +	dev_priv->perf.test_config.b_counter_regs = b_counter_config_test_oa;
> +	dev_priv->perf.test_config.b_counter_regs_len = ARRAY_SIZE(b_counter_config_test_oa);
>   
> -	dev_priv->perf.oa.test_config.flex_regs = flex_eu_config_test_oa;
> -	dev_priv->perf.oa.test_config.flex_regs_len = ARRAY_SIZE(flex_eu_config_test_oa);
> +	dev_priv->perf.test_config.flex_regs = flex_eu_config_test_oa;
> +	dev_priv->perf.test_config.flex_regs_len = ARRAY_SIZE(flex_eu_config_test_oa);
>   
> -	dev_priv->perf.oa.test_config.sysfs_metric.name = "882fa433-1f4a-4a67-a962-c741888fe5f5";
> -	dev_priv->perf.oa.test_config.sysfs_metric.attrs = dev_priv->perf.oa.test_config.attrs;
> +	dev_priv->perf.test_config.sysfs_metric.name = "882fa433-1f4a-4a67-a962-c741888fe5f5";
> +	dev_priv->perf.test_config.sysfs_metric.attrs = dev_priv->perf.test_config.attrs;
>   
> -	dev_priv->perf.oa.test_config.attrs[0] = &dev_priv->perf.oa.test_config.sysfs_metric_id.attr;
> +	dev_priv->perf.test_config.attrs[0] = &dev_priv->perf.test_config.sysfs_metric_id.attr;
>   
> -	dev_priv->perf.oa.test_config.sysfs_metric_id.attr.name = "id";
> -	dev_priv->perf.oa.test_config.sysfs_metric_id.attr.mode = 0444;
> -	dev_priv->perf.oa.test_config.sysfs_metric_id.show = show_test_oa_id;
> +	dev_priv->perf.test_config.sysfs_metric_id.attr.name = "id";
> +	dev_priv->perf.test_config.sysfs_metric_id.attr.mode = 0444;
> +	dev_priv->perf.test_config.sysfs_metric_id.show = show_test_oa_id;
>   }
> diff --git a/drivers/gpu/drm/i915/i915_perf.c b/drivers/gpu/drm/i915/i915_perf.c
> index c4995d5a16d2..be3f68461c50 100644
> --- a/drivers/gpu/drm/i915/i915_perf.c
> +++ b/drivers/gpu/drm/i915/i915_perf.c
> @@ -364,6 +364,8 @@ struct perf_open_properties {
>   	int oa_period_exponent;
>   };
>   
> +static enum hrtimer_restart oa_poll_check_timer_cb(struct hrtimer *hrtimer);
> +
>   static void free_oa_config(struct drm_i915_private *dev_priv,
>   			   struct i915_oa_config *oa_config)
>   {
> @@ -392,8 +394,8 @@ static int get_oa_config(struct drm_i915_private *dev_priv,
>   	int ret;
>   
>   	if (metrics_set == 1) {
> -		*out_config = &dev_priv->perf.oa.test_config;
> -		atomic_inc(&dev_priv->perf.oa.test_config.ref_count);
> +		*out_config = &dev_priv->perf.test_config;
> +		atomic_inc(&dev_priv->perf.test_config.ref_count);
>   		return 0;
>   	}
>   
> @@ -412,13 +414,16 @@ static int get_oa_config(struct drm_i915_private *dev_priv,
>   	return ret;
>   }
>   
> -static u32 gen8_oa_hw_tail_read(struct drm_i915_private *dev_priv)
> +static u32 gen8_oa_hw_tail_read(struct i915_perf_stream *stream)
>   {
> +	struct drm_i915_private *dev_priv = stream->dev_priv;
> +
>   	return I915_READ(GEN8_OATAILPTR) & GEN8_OATAILPTR_MASK;
>   }
>   
> -static u32 gen7_oa_hw_tail_read(struct drm_i915_private *dev_priv)
> +static u32 gen7_oa_hw_tail_read(struct i915_perf_stream *stream)
>   {
> +	struct drm_i915_private *dev_priv = stream->dev_priv;
>   	u32 oastatus1 = I915_READ(GEN7_OASTATUS1);
>   
>   	return oastatus1 & GEN7_OASTATUS1_TAIL_MASK;
> @@ -426,7 +431,7 @@ static u32 gen7_oa_hw_tail_read(struct drm_i915_private *dev_priv)
>   
>   /**
>    * oa_buffer_check_unlocked - check for data and update tail ptr state
> - * @dev_priv: i915 device instance
> + * @stream: i915 stream instance
>    *
>    * This is either called via fops (for blocking reads in user ctx) or the poll
>    * check hrtimer (atomic ctx) to check the OA buffer tail pointer and check
> @@ -448,9 +453,10 @@ static u32 gen7_oa_hw_tail_read(struct drm_i915_private *dev_priv)
>    *
>    * Returns: %true if the OA buffer contains data, else %false
>    */
> -static bool oa_buffer_check_unlocked(struct drm_i915_private *dev_priv)
> +static bool oa_buffer_check_unlocked(struct i915_perf_stream *stream)
>   {
> -	int report_size = dev_priv->perf.oa.oa_buffer.format_size;
> +	struct drm_i915_private *dev_priv = stream->dev_priv;
> +	int report_size = stream->oa_buffer.format_size;
>   	unsigned long flags;
>   	unsigned int aged_idx;
>   	u32 head, hw_tail, aged_tail, aging_tail;
> @@ -460,19 +466,19 @@ static bool oa_buffer_check_unlocked(struct drm_i915_private *dev_priv)
>   	 * could result in an OA buffer reset which might reset the head,
>   	 * tails[] and aged_tail state.
>   	 */
> -	spin_lock_irqsave(&dev_priv->perf.oa.oa_buffer.ptr_lock, flags);
> +	spin_lock_irqsave(&stream->oa_buffer.ptr_lock, flags);
>   
>   	/* NB: The head we observe here might effectively be a little out of
>   	 * date (between head and tails[aged_idx].offset if there is currently
>   	 * a read() in progress.
>   	 */
> -	head = dev_priv->perf.oa.oa_buffer.head;
> +	head = stream->oa_buffer.head;
>   
> -	aged_idx = dev_priv->perf.oa.oa_buffer.aged_tail_idx;
> -	aged_tail = dev_priv->perf.oa.oa_buffer.tails[aged_idx].offset;
> -	aging_tail = dev_priv->perf.oa.oa_buffer.tails[!aged_idx].offset;
> +	aged_idx = stream->oa_buffer.aged_tail_idx;
> +	aged_tail = stream->oa_buffer.tails[aged_idx].offset;
> +	aging_tail = stream->oa_buffer.tails[!aged_idx].offset;
>   
> -	hw_tail = dev_priv->perf.oa.ops.oa_hw_tail_read(dev_priv);
> +	hw_tail = dev_priv->perf.ops.oa_hw_tail_read(stream);
>   
>   	/* The tail pointer increases in 64 byte increments,
>   	 * not in report_size steps...
> @@ -492,16 +498,16 @@ static bool oa_buffer_check_unlocked(struct drm_i915_private *dev_priv)
>   	 * available) without needing to wait for a later hrtimer callback.
>   	 */
>   	if (aging_tail != INVALID_TAIL_PTR &&
> -	    ((now - dev_priv->perf.oa.oa_buffer.aging_timestamp) >
> +	    ((now - stream->oa_buffer.aging_timestamp) >
>   	     OA_TAIL_MARGIN_NSEC)) {
>   
>   		aged_idx ^= 1;
> -		dev_priv->perf.oa.oa_buffer.aged_tail_idx = aged_idx;
> +		stream->oa_buffer.aged_tail_idx = aged_idx;
>   
>   		aged_tail = aging_tail;
>   
>   		/* Mark that we need a new pointer to start aging... */
> -		dev_priv->perf.oa.oa_buffer.tails[!aged_idx].offset = INVALID_TAIL_PTR;
> +		stream->oa_buffer.tails[!aged_idx].offset = INVALID_TAIL_PTR;
>   		aging_tail = INVALID_TAIL_PTR;
>   	}
>   
> @@ -516,7 +522,7 @@ static bool oa_buffer_check_unlocked(struct drm_i915_private *dev_priv)
>   	if (aging_tail == INVALID_TAIL_PTR &&
>   	    (aged_tail == INVALID_TAIL_PTR ||
>   	     OA_TAKEN(hw_tail, aged_tail) >= report_size)) {
> -		struct i915_vma *vma = dev_priv->perf.oa.oa_buffer.vma;
> +		struct i915_vma *vma = stream->oa_buffer.vma;
>   		u32 gtt_offset = i915_ggtt_offset(vma);
>   
>   		/* Be paranoid and do a bounds check on the pointer read back
> @@ -525,16 +531,16 @@ static bool oa_buffer_check_unlocked(struct drm_i915_private *dev_priv)
>   		 */
>   		if (hw_tail >= gtt_offset &&
>   		    hw_tail < (gtt_offset + OA_BUFFER_SIZE)) {
> -			dev_priv->perf.oa.oa_buffer.tails[!aged_idx].offset =
> +			stream->oa_buffer.tails[!aged_idx].offset =
>   				aging_tail = hw_tail;
> -			dev_priv->perf.oa.oa_buffer.aging_timestamp = now;
> +			stream->oa_buffer.aging_timestamp = now;
>   		} else {
>   			DRM_ERROR("Ignoring spurious out of range OA buffer tail pointer = %u\n",
>   				  hw_tail);
>   		}
>   	}
>   
> -	spin_unlock_irqrestore(&dev_priv->perf.oa.oa_buffer.ptr_lock, flags);
> +	spin_unlock_irqrestore(&stream->oa_buffer.ptr_lock, flags);
>   
>   	return aged_tail == INVALID_TAIL_PTR ?
>   		false : OA_TAKEN(aged_tail, head) >= report_size;
> @@ -597,8 +603,7 @@ static int append_oa_sample(struct i915_perf_stream *stream,
>   			    size_t *offset,
>   			    const u8 *report)
>   {
> -	struct drm_i915_private *dev_priv = stream->dev_priv;
> -	int report_size = dev_priv->perf.oa.oa_buffer.format_size;
> +	int report_size = stream->oa_buffer.format_size;
>   	struct drm_i915_perf_record_header header;
>   	u32 sample_flags = stream->sample_flags;
>   
> @@ -650,9 +655,9 @@ static int gen8_append_oa_reports(struct i915_perf_stream *stream,
>   				  size_t *offset)
>   {
>   	struct drm_i915_private *dev_priv = stream->dev_priv;
> -	int report_size = dev_priv->perf.oa.oa_buffer.format_size;
> -	u8 *oa_buf_base = dev_priv->perf.oa.oa_buffer.vaddr;
> -	u32 gtt_offset = i915_ggtt_offset(dev_priv->perf.oa.oa_buffer.vma);
> +	int report_size = stream->oa_buffer.format_size;
> +	u8 *oa_buf_base = stream->oa_buffer.vaddr;
> +	u32 gtt_offset = i915_ggtt_offset(stream->oa_buffer.vma);
>   	u32 mask = (OA_BUFFER_SIZE - 1);
>   	size_t start_offset = *offset;
>   	unsigned long flags;
> @@ -664,13 +669,13 @@ static int gen8_append_oa_reports(struct i915_perf_stream *stream,
>   	if (WARN_ON(!stream->enabled))
>   		return -EIO;
>   
> -	spin_lock_irqsave(&dev_priv->perf.oa.oa_buffer.ptr_lock, flags);
> +	spin_lock_irqsave(&stream->oa_buffer.ptr_lock, flags);
>   
> -	head = dev_priv->perf.oa.oa_buffer.head;
> -	aged_tail_idx = dev_priv->perf.oa.oa_buffer.aged_tail_idx;
> -	tail = dev_priv->perf.oa.oa_buffer.tails[aged_tail_idx].offset;
> +	head = stream->oa_buffer.head;
> +	aged_tail_idx = stream->oa_buffer.aged_tail_idx;
> +	tail = stream->oa_buffer.tails[aged_tail_idx].offset;
>   
> -	spin_unlock_irqrestore(&dev_priv->perf.oa.oa_buffer.ptr_lock, flags);
> +	spin_unlock_irqrestore(&stream->oa_buffer.ptr_lock, flags);
>   
>   	/*
>   	 * An invalid tail pointer here means we're still waiting for the poll
> @@ -734,12 +739,12 @@ static int gen8_append_oa_reports(struct i915_perf_stream *stream,
>   		reason = ((report32[0] >> OAREPORT_REASON_SHIFT) &
>   			  OAREPORT_REASON_MASK);
>   		if (reason == 0) {
> -			if (__ratelimit(&dev_priv->perf.oa.spurious_report_rs))
> +			if (__ratelimit(&dev_priv->perf.spurious_report_rs))
>   				DRM_NOTE("Skipping spurious, invalid OA report\n");
>   			continue;
>   		}
>   
> -		ctx_id = report32[2] & dev_priv->perf.oa.specific_ctx_id_mask;
> +		ctx_id = report32[2] & stream->specific_ctx_id_mask;
>   
>   		/*
>   		 * Squash whatever is in the CTX_ID field if it's marked as
> @@ -749,7 +754,7 @@ static int gen8_append_oa_reports(struct i915_perf_stream *stream,
>   		 * Note: that we don't clear the valid_ctx_bit so userspace can
>   		 * understand that the ID has been squashed by the kernel.
>   		 */
> -		if (!(report32[0] & dev_priv->perf.oa.gen8_valid_ctx_bit))
> +		if (!(report32[0] & dev_priv->perf.gen8_valid_ctx_bit))
>   			ctx_id = report32[2] = INVALID_CTX_ID;
>   
>   		/*
> @@ -783,18 +788,18 @@ static int gen8_append_oa_reports(struct i915_perf_stream *stream,
>   		 * switches since it's not-uncommon for periodic samples to
>   		 * identify a switch before any 'context switch' report.
>   		 */
> -		if (!dev_priv->perf.oa.exclusive_stream->ctx ||
> -		    dev_priv->perf.oa.specific_ctx_id == ctx_id ||
> -		    (dev_priv->perf.oa.oa_buffer.last_ctx_id ==
> -		     dev_priv->perf.oa.specific_ctx_id) ||
> +		if (!dev_priv->perf.exclusive_stream->ctx ||
> +		    stream->specific_ctx_id == ctx_id ||
> +		    (stream->oa_buffer.last_ctx_id ==
> +		     stream->specific_ctx_id) ||
>   		    reason & OAREPORT_REASON_CTX_SWITCH) {
>   
>   			/*
>   			 * While filtering for a single context we avoid
>   			 * leaking the IDs of other contexts.
>   			 */
> -			if (dev_priv->perf.oa.exclusive_stream->ctx &&
> -			    dev_priv->perf.oa.specific_ctx_id != ctx_id) {
> +			if (dev_priv->perf.exclusive_stream->ctx &&
> +			    stream->specific_ctx_id != ctx_id) {
>   				report32[2] = INVALID_CTX_ID;
>   			}
>   
> @@ -803,7 +808,7 @@ static int gen8_append_oa_reports(struct i915_perf_stream *stream,
>   			if (ret)
>   				break;
>   
> -			dev_priv->perf.oa.oa_buffer.last_ctx_id = ctx_id;
> +			stream->oa_buffer.last_ctx_id = ctx_id;
>   		}
>   
>   		/*
> @@ -817,7 +822,7 @@ static int gen8_append_oa_reports(struct i915_perf_stream *stream,
>   	}
>   
>   	if (start_offset != *offset) {
> -		spin_lock_irqsave(&dev_priv->perf.oa.oa_buffer.ptr_lock, flags);
> +		spin_lock_irqsave(&stream->oa_buffer.ptr_lock, flags);
>   
>   		/*
>   		 * We removed the gtt_offset for the copy loop above, indexing
> @@ -826,9 +831,9 @@ static int gen8_append_oa_reports(struct i915_perf_stream *stream,
>   		head += gtt_offset;
>   
>   		I915_WRITE(GEN8_OAHEADPTR, head & GEN8_OAHEADPTR_MASK);
> -		dev_priv->perf.oa.oa_buffer.head = head;
> +		stream->oa_buffer.head = head;
>   
> -		spin_unlock_irqrestore(&dev_priv->perf.oa.oa_buffer.ptr_lock, flags);
> +		spin_unlock_irqrestore(&stream->oa_buffer.ptr_lock, flags);
>   	}
>   
>   	return ret;
> @@ -863,7 +868,7 @@ static int gen8_oa_read(struct i915_perf_stream *stream,
>   	u32 oastatus;
>   	int ret;
>   
> -	if (WARN_ON(!dev_priv->perf.oa.oa_buffer.vaddr))
> +	if (WARN_ON(!stream->oa_buffer.vaddr))
>   		return -EIO;
>   
>   	oastatus = I915_READ(GEN8_OASTATUS);
> @@ -889,10 +894,10 @@ static int gen8_oa_read(struct i915_perf_stream *stream,
>   			return ret;
>   
>   		DRM_DEBUG("OA buffer overflow (exponent = %d): force restart\n",
> -			  dev_priv->perf.oa.period_exponent);
> +			  stream->period_exponent);
>   
> -		dev_priv->perf.oa.ops.oa_disable(stream);
> -		dev_priv->perf.oa.ops.oa_enable(stream);
> +		dev_priv->perf.ops.oa_disable(stream);
> +		dev_priv->perf.ops.oa_enable(stream);
>   
>   		/*
>   		 * Note: .oa_enable() is expected to re-init the oabuffer and
> @@ -939,9 +944,9 @@ static int gen7_append_oa_reports(struct i915_perf_stream *stream,
>   				  size_t *offset)
>   {
>   	struct drm_i915_private *dev_priv = stream->dev_priv;
> -	int report_size = dev_priv->perf.oa.oa_buffer.format_size;
> -	u8 *oa_buf_base = dev_priv->perf.oa.oa_buffer.vaddr;
> -	u32 gtt_offset = i915_ggtt_offset(dev_priv->perf.oa.oa_buffer.vma);
> +	int report_size = stream->oa_buffer.format_size;
> +	u8 *oa_buf_base = stream->oa_buffer.vaddr;
> +	u32 gtt_offset = i915_ggtt_offset(stream->oa_buffer.vma);
>   	u32 mask = (OA_BUFFER_SIZE - 1);
>   	size_t start_offset = *offset;
>   	unsigned long flags;
> @@ -953,13 +958,13 @@ static int gen7_append_oa_reports(struct i915_perf_stream *stream,
>   	if (WARN_ON(!stream->enabled))
>   		return -EIO;
>   
> -	spin_lock_irqsave(&dev_priv->perf.oa.oa_buffer.ptr_lock, flags);
> +	spin_lock_irqsave(&stream->oa_buffer.ptr_lock, flags);
>   
> -	head = dev_priv->perf.oa.oa_buffer.head;
> -	aged_tail_idx = dev_priv->perf.oa.oa_buffer.aged_tail_idx;
> -	tail = dev_priv->perf.oa.oa_buffer.tails[aged_tail_idx].offset;
> +	head = stream->oa_buffer.head;
> +	aged_tail_idx = stream->oa_buffer.aged_tail_idx;
> +	tail = stream->oa_buffer.tails[aged_tail_idx].offset;
>   
> -	spin_unlock_irqrestore(&dev_priv->perf.oa.oa_buffer.ptr_lock, flags);
> +	spin_unlock_irqrestore(&stream->oa_buffer.ptr_lock, flags);
>   
>   	/* An invalid tail pointer here means we're still waiting for the poll
>   	 * hrtimer callback to give us a pointer
> @@ -1012,7 +1017,7 @@ static int gen7_append_oa_reports(struct i915_perf_stream *stream,
>   		 * copying it to userspace...
>   		 */
>   		if (report32[0] == 0) {
> -			if (__ratelimit(&dev_priv->perf.oa.spurious_report_rs))
> +			if (__ratelimit(&dev_priv->perf.spurious_report_rs))
>   				DRM_NOTE("Skipping spurious, invalid OA report\n");
>   			continue;
>   		}
> @@ -1031,7 +1036,7 @@ static int gen7_append_oa_reports(struct i915_perf_stream *stream,
>   	}
>   
>   	if (start_offset != *offset) {
> -		spin_lock_irqsave(&dev_priv->perf.oa.oa_buffer.ptr_lock, flags);
> +		spin_lock_irqsave(&stream->oa_buffer.ptr_lock, flags);
>   
>   		/* We removed the gtt_offset for the copy loop above, indexing
>   		 * relative to oa_buf_base so put back here...
> @@ -1041,9 +1046,9 @@ static int gen7_append_oa_reports(struct i915_perf_stream *stream,
>   		I915_WRITE(GEN7_OASTATUS2,
>   			   ((head & GEN7_OASTATUS2_HEAD_MASK) |
>   			    GEN7_OASTATUS2_MEM_SELECT_GGTT));
> -		dev_priv->perf.oa.oa_buffer.head = head;
> +		stream->oa_buffer.head = head;
>   
> -		spin_unlock_irqrestore(&dev_priv->perf.oa.oa_buffer.ptr_lock, flags);
> +		spin_unlock_irqrestore(&stream->oa_buffer.ptr_lock, flags);
>   	}
>   
>   	return ret;
> @@ -1074,7 +1079,7 @@ static int gen7_oa_read(struct i915_perf_stream *stream,
>   	u32 oastatus1;
>   	int ret;
>   
> -	if (WARN_ON(!dev_priv->perf.oa.oa_buffer.vaddr))
> +	if (WARN_ON(!stream->oa_buffer.vaddr))
>   		return -EIO;
>   
>   	oastatus1 = I915_READ(GEN7_OASTATUS1);
> @@ -1084,7 +1089,7 @@ static int gen7_oa_read(struct i915_perf_stream *stream,
>   	 * may be updated asynchronously) so we ignore status bits
>   	 * that have already been reported to userspace.
>   	 */
> -	oastatus1 &= ~dev_priv->perf.oa.gen7_latched_oastatus1;
> +	oastatus1 &= ~dev_priv->perf.gen7_latched_oastatus1;
>   
>   	/* We treat OABUFFER_OVERFLOW as a significant error:
>   	 *
> @@ -1113,10 +1118,10 @@ static int gen7_oa_read(struct i915_perf_stream *stream,
>   			return ret;
>   
>   		DRM_DEBUG("OA buffer overflow (exponent = %d): force restart\n",
> -			  dev_priv->perf.oa.period_exponent);
> +			  stream->period_exponent);
>   
> -		dev_priv->perf.oa.ops.oa_disable(stream);
> -		dev_priv->perf.oa.ops.oa_enable(stream);
> +		dev_priv->perf.ops.oa_disable(stream);
> +		dev_priv->perf.ops.oa_enable(stream);
>   
>   		oastatus1 = I915_READ(GEN7_OASTATUS1);
>   	}
> @@ -1126,7 +1131,7 @@ static int gen7_oa_read(struct i915_perf_stream *stream,
>   				       DRM_I915_PERF_RECORD_OA_REPORT_LOST);
>   		if (ret)
>   			return ret;
> -		dev_priv->perf.oa.gen7_latched_oastatus1 |=
> +		dev_priv->perf.gen7_latched_oastatus1 |=
>   			GEN7_OASTATUS1_REPORT_LOST;
>   	}
>   
> @@ -1149,14 +1154,12 @@ static int gen7_oa_read(struct i915_perf_stream *stream,
>    */
>   static int i915_oa_wait_unlocked(struct i915_perf_stream *stream)
>   {
> -	struct drm_i915_private *dev_priv = stream->dev_priv;
> -
>   	/* We would wait indefinitely if periodic sampling is not enabled */
> -	if (!dev_priv->perf.oa.periodic)
> +	if (!stream->periodic)
>   		return -EIO;
>   
> -	return wait_event_interruptible(dev_priv->perf.oa.poll_wq,
> -					oa_buffer_check_unlocked(dev_priv));
> +	return wait_event_interruptible(stream->poll_wq,
> +					oa_buffer_check_unlocked(stream));
>   }
>   
>   /**
> @@ -1173,9 +1176,7 @@ static void i915_oa_poll_wait(struct i915_perf_stream *stream,
>   			      struct file *file,
>   			      poll_table *wait)
>   {
> -	struct drm_i915_private *dev_priv = stream->dev_priv;
> -
> -	poll_wait(file, &dev_priv->perf.oa.poll_wq, wait);
> +	poll_wait(file, &stream->poll_wq, wait);
>   }
>   
>   /**
> @@ -1197,13 +1198,14 @@ static int i915_oa_read(struct i915_perf_stream *stream,
>   {
>   	struct drm_i915_private *dev_priv = stream->dev_priv;
>   
> -	return dev_priv->perf.oa.ops.read(stream, buf, count, offset);
> +	return dev_priv->perf.ops.read(stream, buf, count, offset);
>   }
>   
> -static struct intel_context *oa_pin_context(struct drm_i915_private *i915,
> -					    struct i915_gem_context *ctx)
> +static struct intel_context *oa_pin_context(struct i915_perf_stream *stream)
>   {
>   	struct i915_gem_engines_iter it;
> +	struct drm_i915_private *i915 = stream->dev_priv;
> +	struct i915_gem_context *ctx = stream->ctx;
>   	struct intel_context *ce;
>   	int err;
>   
> @@ -1221,7 +1223,7 @@ static struct intel_context *oa_pin_context(struct drm_i915_private *i915,
>   		 */
>   		err = intel_context_pin(ce);
>   		if (err == 0) {
> -			i915->perf.oa.pinned_ctx = ce;
> +			stream->pinned_ctx = ce;
>   			break;
>   		}
>   	}
> @@ -1231,7 +1233,7 @@ static struct intel_context *oa_pin_context(struct drm_i915_private *i915,
>   	if (err)
>   		return ERR_PTR(err);
>   
> -	return i915->perf.oa.pinned_ctx;
> +	return stream->pinned_ctx;
>   }
>   
>   /**
> @@ -1249,7 +1251,7 @@ static int oa_get_render_ctx_id(struct i915_perf_stream *stream)
>   	struct drm_i915_private *i915 = stream->dev_priv;
>   	struct intel_context *ce;
>   
> -	ce = oa_pin_context(i915, stream->ctx);
> +	ce = oa_pin_context(stream);
>   	if (IS_ERR(ce))
>   		return PTR_ERR(ce);
>   
> @@ -1259,8 +1261,8 @@ static int oa_get_render_ctx_id(struct i915_perf_stream *stream)
>   		 * On Haswell we don't do any post processing of the reports
>   		 * and don't need to use the mask.
>   		 */
> -		i915->perf.oa.specific_ctx_id = i915_ggtt_offset(ce->state);
> -		i915->perf.oa.specific_ctx_id_mask = 0;
> +		stream->specific_ctx_id = i915_ggtt_offset(ce->state);
> +		stream->specific_ctx_id_mask = 0;
>   		break;
>   	}
>   
> @@ -1278,33 +1280,36 @@ static int oa_get_render_ctx_id(struct i915_perf_stream *stream)
>   			 * dropped by GuC. They won't be part of the context
>   			 * ID in the OA reports, so squash those lower bits.
>   			 */
> -			i915->perf.oa.specific_ctx_id =
> +			stream->specific_ctx_id =
>   				lower_32_bits(ce->lrc_desc) >> 12;
>   
>   			/*
>   			 * GuC uses the top bit to signal proxy submission, so
>   			 * ignore that bit.
>   			 */
> -			i915->perf.oa.specific_ctx_id_mask =
> +			stream->specific_ctx_id_mask =
>   				(1U << (GEN8_CTX_ID_WIDTH - 1)) - 1;
>   		} else {
> -			i915->perf.oa.specific_ctx_id_mask =
> +			stream->specific_ctx_id_mask =
>   				(1U << GEN8_CTX_ID_WIDTH) - 1;
> -			i915->perf.oa.specific_ctx_id =
> +			stream->specific_ctx_id =
>   				upper_32_bits(ce->lrc_desc);
> -			i915->perf.oa.specific_ctx_id &=
> -				i915->perf.oa.specific_ctx_id_mask;
> +			stream->specific_ctx_id &=
> +				stream->specific_ctx_id_mask;
>   		}
>   		break;
>   
>   	case 11: {
> -		i915->perf.oa.specific_ctx_id_mask =
> -			((1U << GEN11_SW_CTX_ID_WIDTH) - 1) << (GEN11_SW_CTX_ID_SHIFT - 32) |
> -			((1U << GEN11_ENGINE_INSTANCE_WIDTH) - 1) << (GEN11_ENGINE_INSTANCE_SHIFT - 32) |
> -			((1 << GEN11_ENGINE_CLASS_WIDTH) - 1) << (GEN11_ENGINE_CLASS_SHIFT - 32);
> -		i915->perf.oa.specific_ctx_id = upper_32_bits(ce->lrc_desc);
> -		i915->perf.oa.specific_ctx_id &=
> -			i915->perf.oa.specific_ctx_id_mask;
> +		stream->specific_ctx_id_mask =
> +			((1U << GEN11_SW_CTX_ID_WIDTH) - 1)
> +				<< (GEN11_SW_CTX_ID_SHIFT - 32) |
> +			((1U << GEN11_ENGINE_INSTANCE_WIDTH) - 1)
> +				<< (GEN11_ENGINE_INSTANCE_SHIFT - 32) |
> +			((1 << GEN11_ENGINE_CLASS_WIDTH) - 1)
> +				<< (GEN11_ENGINE_CLASS_SHIFT - 32);
> +		stream->specific_ctx_id = upper_32_bits(ce->lrc_desc);
> +		stream->specific_ctx_id &=
> +			stream->specific_ctx_id_mask;
>   		break;
>   	}
>   
> @@ -1313,8 +1318,8 @@ static int oa_get_render_ctx_id(struct i915_perf_stream *stream)
>   	}
>   
>   	DRM_DEBUG_DRIVER("filtering on ctx_id=0x%x ctx_id_mask=0x%x\n",
> -			 i915->perf.oa.specific_ctx_id,
> -			 i915->perf.oa.specific_ctx_id_mask);
> +			 stream->specific_ctx_id,
> +			 stream->specific_ctx_id_mask);
>   
>   	return 0;
>   }
> @@ -1331,10 +1336,10 @@ static void oa_put_render_ctx_id(struct i915_perf_stream *stream)
>   	struct drm_i915_private *dev_priv = stream->dev_priv;
>   	struct intel_context *ce;
>   
> -	dev_priv->perf.oa.specific_ctx_id = INVALID_CTX_ID;
> -	dev_priv->perf.oa.specific_ctx_id_mask = 0;
> +	stream->specific_ctx_id = INVALID_CTX_ID;
> +	stream->specific_ctx_id_mask = 0;
>   
> -	ce = fetch_and_zero(&dev_priv->perf.oa.pinned_ctx);
> +	ce = fetch_and_zero(&stream->pinned_ctx);
>   	if (ce) {
>   		mutex_lock(&dev_priv->drm.struct_mutex);
>   		intel_context_unpin(ce);
> @@ -1343,34 +1348,34 @@ static void oa_put_render_ctx_id(struct i915_perf_stream *stream)
>   }
>   
>   static void
> -free_oa_buffer(struct drm_i915_private *i915)
> +free_oa_buffer(struct i915_perf_stream *stream)
>   {
> -	mutex_lock(&i915->drm.struct_mutex);
> +	struct drm_i915_private *i915 = stream->dev_priv;
>   
> -	i915_vma_unpin_and_release(&i915->perf.oa.oa_buffer.vma,
> +	mutex_lock(&i915->drm.struct_mutex);
> +	i915_vma_unpin_and_release(&stream->oa_buffer.vma,
>   				   I915_VMA_RELEASE_MAP);
> -
>   	mutex_unlock(&i915->drm.struct_mutex);
>   
> -	i915->perf.oa.oa_buffer.vaddr = NULL;
> +	stream->oa_buffer.vaddr = NULL;
>   }
>   
>   static void i915_oa_stream_destroy(struct i915_perf_stream *stream)
>   {
>   	struct drm_i915_private *dev_priv = stream->dev_priv;
>   
> -	BUG_ON(stream != dev_priv->perf.oa.exclusive_stream);
> +	BUG_ON(stream != dev_priv->perf.exclusive_stream);
>   
>   	/*
>   	 * Unset exclusive_stream first, it will be checked while disabling
>   	 * the metric set on gen8+.
>   	 */
>   	mutex_lock(&dev_priv->drm.struct_mutex);
> -	dev_priv->perf.oa.exclusive_stream = NULL;
> -	dev_priv->perf.oa.ops.disable_metric_set(dev_priv);
> +	dev_priv->perf.exclusive_stream = NULL;
> +	dev_priv->perf.ops.disable_metric_set(stream);
>   	mutex_unlock(&dev_priv->drm.struct_mutex);
>   
> -	free_oa_buffer(dev_priv);
> +	free_oa_buffer(stream);
>   
>   	intel_uncore_forcewake_put(&dev_priv->uncore, FORCEWAKE_ALL);
>   	intel_runtime_pm_put(dev_priv, stream->wakeref);
> @@ -1380,41 +1385,42 @@ static void i915_oa_stream_destroy(struct i915_perf_stream *stream)
>   
>   	put_oa_config(dev_priv, stream->oa_config);
>   
> -	if (dev_priv->perf.oa.spurious_report_rs.missed) {
> +	if (dev_priv->perf.spurious_report_rs.missed) {
>   		DRM_NOTE("%d spurious OA report notices suppressed due to ratelimiting\n",
> -			 dev_priv->perf.oa.spurious_report_rs.missed);
> +			 dev_priv->perf.spurious_report_rs.missed);
>   	}
>   }
>   
> -static void gen7_init_oa_buffer(struct drm_i915_private *dev_priv)
> +static void gen7_init_oa_buffer(struct i915_perf_stream *stream)
>   {
> -	u32 gtt_offset = i915_ggtt_offset(dev_priv->perf.oa.oa_buffer.vma);
> +	struct drm_i915_private *dev_priv = stream->dev_priv;
> +	u32 gtt_offset = i915_ggtt_offset(stream->oa_buffer.vma);
>   	unsigned long flags;
>   
> -	spin_lock_irqsave(&dev_priv->perf.oa.oa_buffer.ptr_lock, flags);
> +	spin_lock_irqsave(&stream->oa_buffer.ptr_lock, flags);
>   
>   	/* Pre-DevBDW: OABUFFER must be set with counters off,
>   	 * before OASTATUS1, but after OASTATUS2
>   	 */
>   	I915_WRITE(GEN7_OASTATUS2,
>   		   gtt_offset | GEN7_OASTATUS2_MEM_SELECT_GGTT); /* head */
> -	dev_priv->perf.oa.oa_buffer.head = gtt_offset;
> +	stream->oa_buffer.head = gtt_offset;
>   
>   	I915_WRITE(GEN7_OABUFFER, gtt_offset);
>   
>   	I915_WRITE(GEN7_OASTATUS1, gtt_offset | OABUFFER_SIZE_16M); /* tail */
>   
>   	/* Mark that we need updated tail pointers to read from... */
> -	dev_priv->perf.oa.oa_buffer.tails[0].offset = INVALID_TAIL_PTR;
> -	dev_priv->perf.oa.oa_buffer.tails[1].offset = INVALID_TAIL_PTR;
> +	stream->oa_buffer.tails[0].offset = INVALID_TAIL_PTR;
> +	stream->oa_buffer.tails[1].offset = INVALID_TAIL_PTR;
>   
> -	spin_unlock_irqrestore(&dev_priv->perf.oa.oa_buffer.ptr_lock, flags);
> +	spin_unlock_irqrestore(&stream->oa_buffer.ptr_lock, flags);
>   
>   	/* On Haswell we have to track which OASTATUS1 flags we've
>   	 * already seen since they can't be cleared while periodic
>   	 * sampling is enabled.
>   	 */
> -	dev_priv->perf.oa.gen7_latched_oastatus1 = 0;
> +	dev_priv->perf.gen7_latched_oastatus1 = 0;
>   
>   	/* NB: although the OA buffer will initially be allocated
>   	 * zeroed via shmfs (and so this memset is redundant when
> @@ -1427,24 +1433,25 @@ static void gen7_init_oa_buffer(struct drm_i915_private *dev_priv)
>   	 * the assumption that new reports are being written to zeroed
>   	 * memory...
>   	 */
> -	memset(dev_priv->perf.oa.oa_buffer.vaddr, 0, OA_BUFFER_SIZE);
> +	memset(stream->oa_buffer.vaddr, 0, OA_BUFFER_SIZE);
>   
>   	/* Maybe make ->pollin per-stream state if we support multiple
>   	 * concurrent streams in the future.
>   	 */
> -	dev_priv->perf.oa.pollin = false;
> +	stream->pollin = false;
>   }
>   
> -static void gen8_init_oa_buffer(struct drm_i915_private *dev_priv)
> +static void gen8_init_oa_buffer(struct i915_perf_stream *stream)
>   {
> -	u32 gtt_offset = i915_ggtt_offset(dev_priv->perf.oa.oa_buffer.vma);
> +	struct drm_i915_private *dev_priv = stream->dev_priv;
> +	u32 gtt_offset = i915_ggtt_offset(stream->oa_buffer.vma);
>   	unsigned long flags;
>   
> -	spin_lock_irqsave(&dev_priv->perf.oa.oa_buffer.ptr_lock, flags);
> +	spin_lock_irqsave(&stream->oa_buffer.ptr_lock, flags);
>   
>   	I915_WRITE(GEN8_OASTATUS, 0);
>   	I915_WRITE(GEN8_OAHEADPTR, gtt_offset);
> -	dev_priv->perf.oa.oa_buffer.head = gtt_offset;
> +	stream->oa_buffer.head = gtt_offset;
>   
>   	I915_WRITE(GEN8_OABUFFER_UDW, 0);
>   
> @@ -1461,17 +1468,17 @@ static void gen8_init_oa_buffer(struct drm_i915_private *dev_priv)
>   	I915_WRITE(GEN8_OATAILPTR, gtt_offset & GEN8_OATAILPTR_MASK);
>   
>   	/* Mark that we need updated tail pointers to read from... */
> -	dev_priv->perf.oa.oa_buffer.tails[0].offset = INVALID_TAIL_PTR;
> -	dev_priv->perf.oa.oa_buffer.tails[1].offset = INVALID_TAIL_PTR;
> +	stream->oa_buffer.tails[0].offset = INVALID_TAIL_PTR;
> +	stream->oa_buffer.tails[1].offset = INVALID_TAIL_PTR;
>   
>   	/*
>   	 * Reset state used to recognise context switches, affecting which
>   	 * reports we will forward to userspace while filtering for a single
>   	 * context.
>   	 */
> -	dev_priv->perf.oa.oa_buffer.last_ctx_id = INVALID_CTX_ID;
> +	stream->oa_buffer.last_ctx_id = INVALID_CTX_ID;
>   
> -	spin_unlock_irqrestore(&dev_priv->perf.oa.oa_buffer.ptr_lock, flags);
> +	spin_unlock_irqrestore(&stream->oa_buffer.ptr_lock, flags);
>   
>   	/*
>   	 * NB: although the OA buffer will initially be allocated
> @@ -1485,22 +1492,23 @@ static void gen8_init_oa_buffer(struct drm_i915_private *dev_priv)
>   	 * the assumption that new reports are being written to zeroed
>   	 * memory...
>   	 */
> -	memset(dev_priv->perf.oa.oa_buffer.vaddr, 0, OA_BUFFER_SIZE);
> +	memset(stream->oa_buffer.vaddr, 0, OA_BUFFER_SIZE);
>   
>   	/*
>   	 * Maybe make ->pollin per-stream state if we support multiple
>   	 * concurrent streams in the future.
>   	 */
> -	dev_priv->perf.oa.pollin = false;
> +	stream->pollin = false;
>   }
>   
> -static int alloc_oa_buffer(struct drm_i915_private *dev_priv)
> +static int alloc_oa_buffer(struct i915_perf_stream *stream)
>   {
>   	struct drm_i915_gem_object *bo;
> +	struct drm_i915_private *dev_priv = stream->dev_priv;
>   	struct i915_vma *vma;
>   	int ret;
>   
> -	if (WARN_ON(dev_priv->perf.oa.oa_buffer.vma))
> +	if (WARN_ON(stream->oa_buffer.vma))
>   		return -ENODEV;
>   
>   	ret = i915_mutex_lock_interruptible(&dev_priv->drm);
> @@ -1525,18 +1533,18 @@ static int alloc_oa_buffer(struct drm_i915_private *dev_priv)
>   		ret = PTR_ERR(vma);
>   		goto err_unref;
>   	}
> -	dev_priv->perf.oa.oa_buffer.vma = vma;
> +	stream->oa_buffer.vma = vma;
>   
> -	dev_priv->perf.oa.oa_buffer.vaddr =
> +	stream->oa_buffer.vaddr =
>   		i915_gem_object_pin_map(bo, I915_MAP_WB);
> -	if (IS_ERR(dev_priv->perf.oa.oa_buffer.vaddr)) {
> -		ret = PTR_ERR(dev_priv->perf.oa.oa_buffer.vaddr);
> +	if (IS_ERR(stream->oa_buffer.vaddr)) {
> +		ret = PTR_ERR(stream->oa_buffer.vaddr);
>   		goto err_unpin;
>   	}
>   
>   	DRM_DEBUG_DRIVER("OA Buffer initialized, gtt offset = 0x%x, vaddr = %p\n",
> -			 i915_ggtt_offset(dev_priv->perf.oa.oa_buffer.vma),
> -			 dev_priv->perf.oa.oa_buffer.vaddr);
> +			 i915_ggtt_offset(stream->oa_buffer.vma),
> +			 stream->oa_buffer.vaddr);
>   
>   	goto unlock;
>   
> @@ -1546,8 +1554,8 @@ static int alloc_oa_buffer(struct drm_i915_private *dev_priv)
>   err_unref:
>   	i915_gem_object_put(bo);
>   
> -	dev_priv->perf.oa.oa_buffer.vaddr = NULL;
> -	dev_priv->perf.oa.oa_buffer.vma = NULL;
> +	stream->oa_buffer.vaddr = NULL;
> +	stream->oa_buffer.vma = NULL;
>   
>   unlock:
>   	mutex_unlock(&dev_priv->drm.struct_mutex);
> @@ -1617,8 +1625,10 @@ static int hsw_enable_metric_set(struct i915_perf_stream *stream)
>   	return 0;
>   }
>   
> -static void hsw_disable_metric_set(struct drm_i915_private *dev_priv)
> +static void hsw_disable_metric_set(struct i915_perf_stream *stream)
>   {
> +	struct drm_i915_private *dev_priv = stream->dev_priv;
> +
>   	I915_WRITE(GEN6_UCGCTL1, (I915_READ(GEN6_UCGCTL1) &
>   				  ~GEN6_CSUNIT_CLOCK_GATE_DISABLE));
>   	I915_WRITE(GEN7_MISCCPCTL, (I915_READ(GEN7_MISCCPCTL) |
> @@ -1636,13 +1646,14 @@ static void hsw_disable_metric_set(struct drm_i915_private *dev_priv)
>    * in the case that the OA unit has been disabled.
>    */
>   static void
> -gen8_update_reg_state_unlocked(struct intel_context *ce,
> +gen8_update_reg_state_unlocked(struct i915_perf_stream *stream,
> +			       struct intel_context *ce,
>   			       u32 *reg_state,
>   			       const struct i915_oa_config *oa_config)
>   {
>   	struct drm_i915_private *i915 = ce->gem_context->i915;
> -	u32 ctx_oactxctrl = i915->perf.oa.ctx_oactxctrl_offset;
> -	u32 ctx_flexeu0 = i915->perf.oa.ctx_flexeu0_offset;
> +	u32 ctx_oactxctrl = i915->perf.ctx_oactxctrl_offset;
> +	u32 ctx_flexeu0 = i915->perf.ctx_flexeu0_offset;
>   	/* The MMIO offsets for Flex EU registers aren't contiguous */
>   	i915_reg_t flex_regs[] = {
>   		EU_PERF_CNTL0,
> @@ -1656,8 +1667,8 @@ gen8_update_reg_state_unlocked(struct intel_context *ce,
>   	int i;
>   
>   	CTX_REG(reg_state, ctx_oactxctrl, GEN8_OACTXCONTROL,
> -		(i915->perf.oa.period_exponent << GEN8_OA_TIMER_PERIOD_SHIFT) |
> -		(i915->perf.oa.periodic ? GEN8_OA_TIMER_ENABLE : 0) |
> +		(stream->period_exponent << GEN8_OA_TIMER_PERIOD_SHIFT) |
> +		(stream->periodic ? GEN8_OA_TIMER_ENABLE : 0) |
>   		GEN8_OA_COUNTER_RESUME);
>   
>   	for (i = 0; i < ARRAY_SIZE(flex_regs); i++) {
> @@ -1673,10 +1684,12 @@ gen8_update_reg_state_unlocked(struct intel_context *ce,
>   
>   		if (oa_config) {
>   			u32 j;
> +			struct i915_oa_reg reg;
>   
>   			for (j = 0; j < oa_config->flex_regs_len; j++) {
> -				if (i915_mmio_reg_offset(oa_config->flex_regs[j].addr) == mmio) {
> -					value = oa_config->flex_regs[j].value;
> +				reg = oa_config->flex_regs[j];
> +				if (i915_mmio_reg_offset(reg.addr) == mmio) {
> +					value = reg.value;
>   					break;
>   				}
>   			}
> @@ -1714,9 +1727,10 @@ gen8_update_reg_state_unlocked(struct intel_context *ce,
>    *
>    * Note: it's only the RCS/Render context that has any OA state.
>    */
> -static int gen8_configure_all_contexts(struct drm_i915_private *dev_priv,
> +static int gen8_configure_all_contexts(struct i915_perf_stream *stream,
>   				       const struct i915_oa_config *oa_config)
>   {
> +	struct drm_i915_private *dev_priv = stream->dev_priv;
>   	unsigned int map_type = i915_coherent_map_type(dev_priv);
>   	struct i915_gem_context *ctx;
>   	struct i915_request *rq;
> @@ -1770,7 +1784,7 @@ static int gen8_configure_all_contexts(struct drm_i915_private *dev_priv,
>   			ce->state->obj->mm.dirty = true;
>   			regs += LRC_STATE_PN * PAGE_SIZE / sizeof(*regs);
>   
> -			gen8_update_reg_state_unlocked(ce, regs, oa_config);
> +			gen8_update_reg_state_unlocked(stream, ce, regs, oa_config);
>   
>   			i915_gem_object_unpin_map(ce->state->obj);
>   		}
> @@ -1821,8 +1835,9 @@ static int gen8_enable_metric_set(struct i915_perf_stream *stream)
>   	 */
>   	if (IS_GEN_RANGE(dev_priv, 9, 11)) {
>   		I915_WRITE(GEN8_OA_DEBUG,
> -			   _MASKED_BIT_ENABLE(GEN9_OA_DEBUG_DISABLE_CLK_RATIO_REPORTS |
> -					      GEN9_OA_DEBUG_INCLUDE_CLK_RATIO));
> +			   _MASKED_BIT_ENABLE(
> +				   GEN9_OA_DEBUG_DISABLE_CLK_RATIO_REPORTS |
> +				   GEN9_OA_DEBUG_INCLUDE_CLK_RATIO));
>   	}
>   
>   	/*
> @@ -1830,7 +1845,7 @@ static int gen8_enable_metric_set(struct i915_perf_stream *stream)
>   	 * to make sure all slices/subslices are ON before writing to NOA
>   	 * registers.
>   	 */
> -	ret = gen8_configure_all_contexts(dev_priv, oa_config);
> +	ret = gen8_configure_all_contexts(stream, oa_config);
>   	if (ret)
>   		return ret;
>   
> @@ -1842,19 +1857,23 @@ static int gen8_enable_metric_set(struct i915_perf_stream *stream)
>   	return 0;
>   }
>   
> -static void gen8_disable_metric_set(struct drm_i915_private *dev_priv)
> +static void gen8_disable_metric_set(struct i915_perf_stream *stream)
>   {
> +	struct drm_i915_private *dev_priv = stream->dev_priv;
> +
>   	/* Reset all contexts' slices/subslices configurations. */
> -	gen8_configure_all_contexts(dev_priv, NULL);
> +	gen8_configure_all_contexts(stream, NULL);
>   
>   	I915_WRITE(GDT_CHICKEN_BITS, (I915_READ(GDT_CHICKEN_BITS) &
>   				      ~GT_NOA_ENABLE));
>   }
>   
> -static void gen10_disable_metric_set(struct drm_i915_private *dev_priv)
> +static void gen10_disable_metric_set(struct i915_perf_stream *stream)
>   {
> +	struct drm_i915_private *dev_priv = stream->dev_priv;
> +
>   	/* Reset all contexts' slices/subslices configurations. */
> -	gen8_configure_all_contexts(dev_priv, NULL);
> +	gen8_configure_all_contexts(stream, NULL);
>   
>   	/* Make sure we disable noa to save power. */
>   	I915_WRITE(RPM_CONFIG1,
> @@ -1865,10 +1884,10 @@ static void gen7_oa_enable(struct i915_perf_stream *stream)
>   {
>   	struct drm_i915_private *dev_priv = stream->dev_priv;
>   	struct i915_gem_context *ctx = stream->ctx;
> -	u32 ctx_id = dev_priv->perf.oa.specific_ctx_id;
> -	bool periodic = dev_priv->perf.oa.periodic;
> -	u32 period_exponent = dev_priv->perf.oa.period_exponent;
> -	u32 report_format = dev_priv->perf.oa.oa_buffer.format;
> +	u32 ctx_id = stream->specific_ctx_id;
> +	bool periodic = stream->periodic;
> +	u32 period_exponent = stream->period_exponent;
> +	u32 report_format = stream->oa_buffer.format;
>   
>   	/*
>   	 * Reset buf pointers so we don't forward reports from before now.
> @@ -1879,7 +1898,7 @@ static void gen7_oa_enable(struct i915_perf_stream *stream)
>   	 * on the assumption that certain fields are written to zeroed
>   	 * memory which this helps maintains.
>   	 */
> -	gen7_init_oa_buffer(dev_priv);
> +	gen7_init_oa_buffer(stream);
>   
>   	I915_WRITE(GEN7_OACONTROL,
>   		   (ctx_id & GEN7_OACONTROL_CTX_MASK) |
> @@ -1894,7 +1913,7 @@ static void gen7_oa_enable(struct i915_perf_stream *stream)
>   static void gen8_oa_enable(struct i915_perf_stream *stream)
>   {
>   	struct drm_i915_private *dev_priv = stream->dev_priv;
> -	u32 report_format = dev_priv->perf.oa.oa_buffer.format;
> +	u32 report_format = stream->oa_buffer.format;
>   
>   	/*
>   	 * Reset buf pointers so we don't forward reports from before now.
> @@ -1905,7 +1924,7 @@ static void gen8_oa_enable(struct i915_perf_stream *stream)
>   	 * on the assumption that certain fields are written to zeroed
>   	 * memory which this helps maintains.
>   	 */
> -	gen8_init_oa_buffer(dev_priv);
> +	gen8_init_oa_buffer(stream);
>   
>   	/*
>   	 * Note: we don't rely on the hardware to perform single context
> @@ -1930,10 +1949,10 @@ static void i915_oa_stream_enable(struct i915_perf_stream *stream)
>   {
>   	struct drm_i915_private *dev_priv = stream->dev_priv;
>   
> -	dev_priv->perf.oa.ops.oa_enable(stream);
> +	dev_priv->perf.ops.oa_enable(stream);
>   
> -	if (dev_priv->perf.oa.periodic)
> -		hrtimer_start(&dev_priv->perf.oa.poll_check_timer,
> +	if (stream->periodic)
> +		hrtimer_start(&stream->poll_check_timer,
>   			      ns_to_ktime(POLL_PERIOD),
>   			      HRTIMER_MODE_REL_PINNED);
>   }
> @@ -1972,10 +1991,10 @@ static void i915_oa_stream_disable(struct i915_perf_stream *stream)
>   {
>   	struct drm_i915_private *dev_priv = stream->dev_priv;
>   
> -	dev_priv->perf.oa.ops.oa_disable(stream);
> +	dev_priv->perf.ops.oa_disable(stream);
>   
> -	if (dev_priv->perf.oa.periodic)
> -		hrtimer_cancel(&dev_priv->perf.oa.poll_check_timer);
> +	if (stream->periodic)
> +		hrtimer_cancel(&stream->poll_check_timer);
>   }
>   
>   static const struct i915_perf_stream_ops i915_oa_stream_ops = {
> @@ -2027,7 +2046,7 @@ static int i915_oa_stream_init(struct i915_perf_stream *stream,
>   		return -EINVAL;
>   	}
>   
> -	if (!dev_priv->perf.oa.ops.enable_metric_set) {
> +	if (!dev_priv->perf.ops.enable_metric_set) {
>   		DRM_DEBUG("OA unit not supported\n");
>   		return -ENODEV;
>   	}
> @@ -2036,7 +2055,7 @@ static int i915_oa_stream_init(struct i915_perf_stream *stream,
>   	 * counter reports and marshal to the appropriate client
>   	 * we currently only allow exclusive access
>   	 */
> -	if (dev_priv->perf.oa.exclusive_stream) {
> +	if (dev_priv->perf.exclusive_stream) {
>   		DRM_DEBUG("OA unit already in use\n");
>   		return -EBUSY;
>   	}
> @@ -2046,43 +2065,23 @@ static int i915_oa_stream_init(struct i915_perf_stream *stream,
>   		return -EINVAL;
>   	}
>   
> -	/* We set up some ratelimit state to potentially throttle any _NOTES
> -	 * about spurious, invalid OA reports which we don't forward to
> -	 * userspace.
> -	 *
> -	 * The initialization is associated with opening the stream (not driver
> -	 * init) considering we print a _NOTE about any throttling when closing
> -	 * the stream instead of waiting until driver _fini which no one would
> -	 * ever see.
> -	 *
> -	 * Using the same limiting factors as printk_ratelimit()
> -	 */
> -	ratelimit_state_init(&dev_priv->perf.oa.spurious_report_rs,
> -			     5 * HZ, 10);
> -	/* Since we use a DRM_NOTE for spurious reports it would be
> -	 * inconsistent to let __ratelimit() automatically print a warning for
> -	 * throttling.
> -	 */
> -	ratelimit_set_flags(&dev_priv->perf.oa.spurious_report_rs,
> -			    RATELIMIT_MSG_ON_RELEASE);
> -
>   	stream->sample_size = sizeof(struct drm_i915_perf_record_header);
>   
> -	format_size = dev_priv->perf.oa.oa_formats[props->oa_format].size;
> +	format_size = dev_priv->perf.oa_formats[props->oa_format].size;
>   
>   	stream->sample_flags |= SAMPLE_OA_REPORT;
>   	stream->sample_size += format_size;
>   
> -	dev_priv->perf.oa.oa_buffer.format_size = format_size;
> -	if (WARN_ON(dev_priv->perf.oa.oa_buffer.format_size == 0))
> +	stream->oa_buffer.format_size = format_size;
> +	if (WARN_ON(stream->oa_buffer.format_size == 0))
>   		return -EINVAL;
>   
> -	dev_priv->perf.oa.oa_buffer.format =
> -		dev_priv->perf.oa.oa_formats[props->oa_format].format;
> +	stream->oa_buffer.format =
> +		dev_priv->perf.oa_formats[props->oa_format].format;
>   
> -	dev_priv->perf.oa.periodic = props->oa_periodic;
> -	if (dev_priv->perf.oa.periodic)
> -		dev_priv->perf.oa.period_exponent = props->oa_period_exponent;
> +	stream->periodic = props->oa_periodic;
> +	if (stream->periodic)
> +		stream->period_exponent = props->oa_period_exponent;
>   
>   	if (stream->ctx) {
>   		ret = oa_get_render_ctx_id(stream);
> @@ -2113,7 +2112,7 @@ static int i915_oa_stream_init(struct i915_perf_stream *stream,
>   	stream->wakeref = intel_runtime_pm_get(dev_priv);
>   	intel_uncore_forcewake_get(&dev_priv->uncore, FORCEWAKE_ALL);
>   
> -	ret = alloc_oa_buffer(dev_priv);
> +	ret = alloc_oa_buffer(stream);
>   	if (ret)
>   		goto err_oa_buf_alloc;
>   
> @@ -2122,9 +2121,9 @@ static int i915_oa_stream_init(struct i915_perf_stream *stream,
>   		goto err_lock;
>   
>   	stream->ops = &i915_oa_stream_ops;
> -	dev_priv->perf.oa.exclusive_stream = stream;
> +	dev_priv->perf.exclusive_stream = stream;
>   
> -	ret = dev_priv->perf.oa.ops.enable_metric_set(stream);
> +	ret = dev_priv->perf.ops.enable_metric_set(stream);
>   	if (ret) {
>   		DRM_DEBUG("Unable to enable metric set\n");
>   		goto err_enable;
> @@ -2132,15 +2131,21 @@ static int i915_oa_stream_init(struct i915_perf_stream *stream,
>   
>   	mutex_unlock(&dev_priv->drm.struct_mutex);
>   
> +	hrtimer_init(&stream->poll_check_timer,
> +		     CLOCK_MONOTONIC, HRTIMER_MODE_REL);
> +	stream->poll_check_timer.function = oa_poll_check_timer_cb;
> +	init_waitqueue_head(&stream->poll_wq);
> +	spin_lock_init(&stream->oa_buffer.ptr_lock);
> +
>   	return 0;
>   
>   err_enable:
> -	dev_priv->perf.oa.exclusive_stream = NULL;
> -	dev_priv->perf.oa.ops.disable_metric_set(dev_priv);
> +	dev_priv->perf.exclusive_stream = NULL;
> +	dev_priv->perf.ops.disable_metric_set(stream);
>   	mutex_unlock(&dev_priv->drm.struct_mutex);
>   
>   err_lock:
> -	free_oa_buffer(dev_priv);
> +	free_oa_buffer(stream);
>   
>   err_oa_buf_alloc:
>   	put_oa_config(dev_priv, stream->oa_config);
> @@ -2164,9 +2169,12 @@ void i915_oa_init_reg_state(struct intel_engine_cs *engine,
>   	if (engine->class != RENDER_CLASS)
>   		return;
>   
> -	stream = engine->i915->perf.oa.exclusive_stream;
> +	stream = engine->i915->perf.exclusive_stream;
>   	if (stream)
> -		gen8_update_reg_state_unlocked(ce, regs, stream->oa_config);
> +		gen8_update_reg_state_unlocked(stream,
> +					       ce,
> +					       regs,
> +					       stream->oa_config);
>   }
>   
>   /**
> @@ -2282,7 +2290,7 @@ static ssize_t i915_perf_read(struct file *file,
>   		/* Maybe make ->pollin per-stream state if we support multiple
>   		 * concurrent streams in the future.
>   		 */
> -		dev_priv->perf.oa.pollin = false;
> +		stream->pollin = false;
>   	}
>   
>   	return ret;
> @@ -2290,13 +2298,13 @@ static ssize_t i915_perf_read(struct file *file,
>   
>   static enum hrtimer_restart oa_poll_check_timer_cb(struct hrtimer *hrtimer)
>   {
> -	struct drm_i915_private *dev_priv =
> -		container_of(hrtimer, typeof(*dev_priv),
> -			     perf.oa.poll_check_timer);
> +	struct i915_perf_stream *stream = container_of(hrtimer,
> +						       typeof(*stream),
> +						       poll_check_timer);
>   
> -	if (oa_buffer_check_unlocked(dev_priv)) {
> -		dev_priv->perf.oa.pollin = true;
> -		wake_up(&dev_priv->perf.oa.poll_wq);
> +	if (oa_buffer_check_unlocked(stream)) {
> +		stream->pollin = true;
> +		wake_up(&stream->poll_wq);
>   	}
>   
>   	hrtimer_forward_now(hrtimer, ns_to_ktime(POLL_PERIOD));
> @@ -2335,7 +2343,7 @@ static __poll_t i915_perf_poll_locked(struct drm_i915_private *dev_priv,
>   	 * the hrtimer/oa_poll_check_timer_cb to notify us when there are
>   	 * samples to read.
>   	 */
> -	if (dev_priv->perf.oa.pollin)
> +	if (stream->pollin)
>   		events |= EPOLLIN;
>   
>   	return events;
> @@ -2668,8 +2676,10 @@ i915_perf_open_ioctl_locked(struct drm_i915_private *dev_priv,
>   
>   static u64 oa_exponent_to_ns(struct drm_i915_private *dev_priv, int exponent)
>   {
> +	struct intel_runtime_info *ri = RUNTIME_INFO(dev_priv);
> +
>   	return div64_u64(1000000000ULL * (2ULL << exponent),
> -			 1000ULL * RUNTIME_INFO(dev_priv)->cs_timestamp_frequency_khz);
> +			 1000ULL * ri->cs_timestamp_frequency_khz);
>   }
>   
>   /**
> @@ -2753,7 +2763,7 @@ static int read_properties_unlocked(struct drm_i915_private *dev_priv,
>   					  value);
>   				return -EINVAL;
>   			}
> -			if (!dev_priv->perf.oa.oa_formats[value].size) {
> +			if (!dev_priv->perf.oa_formats[value].size) {
>   				DRM_DEBUG("Unsupported OA report format %llu\n",
>   					  value);
>   				return -EINVAL;
> @@ -2897,7 +2907,7 @@ void i915_perf_register(struct drm_i915_private *dev_priv)
>   	if (!dev_priv->perf.metrics_kobj)
>   		goto exit;
>   
> -	sysfs_attr_init(&dev_priv->perf.oa.test_config.sysfs_metric_id.attr);
> +	sysfs_attr_init(&dev_priv->perf.test_config.sysfs_metric_id.attr);
>   
>   	if (INTEL_GEN(dev_priv) >= 11) {
>   		i915_perf_load_test_config_icl(dev_priv);
> @@ -2932,15 +2942,15 @@ void i915_perf_register(struct drm_i915_private *dev_priv)
>   		i915_perf_load_test_config_hsw(dev_priv);
>   }
>   
> -	if (dev_priv->perf.oa.test_config.id == 0)
> +	if (dev_priv->perf.test_config.id == 0)
>   		goto sysfs_error;
>   
>   	ret = sysfs_create_group(dev_priv->perf.metrics_kobj,
> -				 &dev_priv->perf.oa.test_config.sysfs_metric);
> +				 &dev_priv->perf.test_config.sysfs_metric);
>   	if (ret)
>   		goto sysfs_error;
>   
> -	atomic_set(&dev_priv->perf.oa.test_config.ref_count, 1);
> +	atomic_set(&dev_priv->perf.test_config.ref_count, 1);
>   
>   	goto exit;
>   
> @@ -2967,7 +2977,7 @@ void i915_perf_unregister(struct drm_i915_private *dev_priv)
>   		return;
>   
>   	sysfs_remove_group(dev_priv->perf.metrics_kobj,
> -			   &dev_priv->perf.oa.test_config.sysfs_metric);
> +			   &dev_priv->perf.test_config.sysfs_metric);
>   
>   	kobject_put(dev_priv->perf.metrics_kobj);
>   	dev_priv->perf.metrics_kobj = NULL;
> @@ -2993,7 +3003,8 @@ static bool gen8_is_valid_flex_addr(struct drm_i915_private *dev_priv, u32 addr)
>   	return false;
>   }
>   
> -static bool gen7_is_valid_b_counter_addr(struct drm_i915_private *dev_priv, u32 addr)
> +static bool gen7_is_valid_b_counter_addr(struct drm_i915_private *dev_priv,
> +					 u32 addr)
>   {
>   	return (addr >= i915_mmio_reg_offset(OASTARTTRIG1) &&
>   		addr <= i915_mmio_reg_offset(OASTARTTRIG8)) ||
> @@ -3078,7 +3089,9 @@ static struct i915_oa_reg *alloc_oa_regs(struct drm_i915_private *dev_priv,
>   	if (!access_ok(regs, n_regs * sizeof(u32) * 2))
>   		return ERR_PTR(-EFAULT);
>   
> -	/* No is_valid function means we're not allowing any register to be programmed. */
> +	/* No is_valid function means we're not allowing any register to be
> +	 * programmed.
> +	 */
>   	GEM_BUG_ON(!is_valid);
>   	if (!is_valid)
>   		return ERR_PTR(-EINVAL);
> @@ -3211,7 +3224,7 @@ int i915_perf_add_config_ioctl(struct drm_device *dev, void *data,
>   	oa_config->mux_regs_len = args->n_mux_regs;
>   	oa_config->mux_regs =
>   		alloc_oa_regs(dev_priv,
> -			      dev_priv->perf.oa.ops.is_valid_mux_reg,
> +			      dev_priv->perf.ops.is_valid_mux_reg,
>   			      u64_to_user_ptr(args->mux_regs_ptr),
>   			      args->n_mux_regs);
>   
> @@ -3224,7 +3237,7 @@ int i915_perf_add_config_ioctl(struct drm_device *dev, void *data,
>   	oa_config->b_counter_regs_len = args->n_boolean_regs;
>   	oa_config->b_counter_regs =
>   		alloc_oa_regs(dev_priv,
> -			      dev_priv->perf.oa.ops.is_valid_b_counter_reg,
> +			      dev_priv->perf.ops.is_valid_b_counter_reg,
>   			      u64_to_user_ptr(args->boolean_regs_ptr),
>   			      args->n_boolean_regs);
>   
> @@ -3243,7 +3256,7 @@ int i915_perf_add_config_ioctl(struct drm_device *dev, void *data,
>   		oa_config->flex_regs_len = args->n_flex_regs;
>   		oa_config->flex_regs =
>   			alloc_oa_regs(dev_priv,
> -				      dev_priv->perf.oa.ops.is_valid_flex_reg,
> +				      dev_priv->perf.ops.is_valid_flex_reg,
>   				      u64_to_user_ptr(args->flex_regs_ptr),
>   				      args->n_flex_regs);
>   
> @@ -3300,7 +3313,8 @@ int i915_perf_add_config_ioctl(struct drm_device *dev, void *data,
>   }
>   
>   /**
> - * i915_perf_remove_config_ioctl - DRM ioctl() for userspace to remove an OA config
> + * i915_perf_remove_config_ioctl - DRM ioctl() for userspace to remove an OA
> + * config
>    * @dev: drm device
>    * @data: ioctl data (pointer to u64 integer) copied from userspace
>    * @file: drm file
> @@ -3409,21 +3423,23 @@ static struct ctl_table dev_root[] = {
>    */
>   void i915_perf_init(struct drm_i915_private *dev_priv)
>   {
> +	struct intel_runtime_info *ri;
> +
>   	if (IS_HASWELL(dev_priv)) {
> -		dev_priv->perf.oa.ops.is_valid_b_counter_reg =
> +		dev_priv->perf.ops.is_valid_b_counter_reg =
>   			gen7_is_valid_b_counter_addr;
> -		dev_priv->perf.oa.ops.is_valid_mux_reg =
> +		dev_priv->perf.ops.is_valid_mux_reg =
>   			hsw_is_valid_mux_addr;
> -		dev_priv->perf.oa.ops.is_valid_flex_reg = NULL;
> -		dev_priv->perf.oa.ops.enable_metric_set = hsw_enable_metric_set;
> -		dev_priv->perf.oa.ops.disable_metric_set = hsw_disable_metric_set;
> -		dev_priv->perf.oa.ops.oa_enable = gen7_oa_enable;
> -		dev_priv->perf.oa.ops.oa_disable = gen7_oa_disable;
> -		dev_priv->perf.oa.ops.read = gen7_oa_read;
> -		dev_priv->perf.oa.ops.oa_hw_tail_read =
> +		dev_priv->perf.ops.is_valid_flex_reg = NULL;
> +		dev_priv->perf.ops.enable_metric_set = hsw_enable_metric_set;
> +		dev_priv->perf.ops.disable_metric_set = hsw_disable_metric_set;
> +		dev_priv->perf.ops.oa_enable = gen7_oa_enable;
> +		dev_priv->perf.ops.oa_disable = gen7_oa_disable;
> +		dev_priv->perf.ops.read = gen7_oa_read;
> +		dev_priv->perf.ops.oa_hw_tail_read =
>   			gen7_oa_hw_tail_read;
>   
> -		dev_priv->perf.oa.oa_formats = hsw_oa_formats;
> +		dev_priv->perf.oa_formats = hsw_oa_formats;
>   	} else if (HAS_LOGICAL_RING_CONTEXTS(dev_priv)) {
>   		/* Note: that although we could theoretically also support the
>   		 * legacy ringbuffer mode on BDW (and earlier iterations of
> @@ -3431,75 +3447,93 @@ void i915_perf_init(struct drm_i915_private *dev_priv)
>   		 * worth the complexity to maintain now that BDW+ enable
>   		 * execlist mode by default.
>   		 */
> -		dev_priv->perf.oa.oa_formats = gen8_plus_oa_formats;
> +		dev_priv->perf.oa_formats = gen8_plus_oa_formats;
>   
> -		dev_priv->perf.oa.ops.oa_enable = gen8_oa_enable;
> -		dev_priv->perf.oa.ops.oa_disable = gen8_oa_disable;
> -		dev_priv->perf.oa.ops.read = gen8_oa_read;
> -		dev_priv->perf.oa.ops.oa_hw_tail_read = gen8_oa_hw_tail_read;
> +		dev_priv->perf.ops.oa_enable = gen8_oa_enable;
> +		dev_priv->perf.ops.oa_disable = gen8_oa_disable;
> +		dev_priv->perf.ops.read = gen8_oa_read;
> +		dev_priv->perf.ops.oa_hw_tail_read = gen8_oa_hw_tail_read;
>   
>   		if (IS_GEN_RANGE(dev_priv, 8, 9)) {
> -			dev_priv->perf.oa.ops.is_valid_b_counter_reg =
> +			dev_priv->perf.ops.is_valid_b_counter_reg =
>   				gen7_is_valid_b_counter_addr;
> -			dev_priv->perf.oa.ops.is_valid_mux_reg =
> +			dev_priv->perf.ops.is_valid_mux_reg =
>   				gen8_is_valid_mux_addr;
> -			dev_priv->perf.oa.ops.is_valid_flex_reg =
> +			dev_priv->perf.ops.is_valid_flex_reg =
>   				gen8_is_valid_flex_addr;
>   
>   			if (IS_CHERRYVIEW(dev_priv)) {
> -				dev_priv->perf.oa.ops.is_valid_mux_reg =
> +				dev_priv->perf.ops.is_valid_mux_reg =
>   					chv_is_valid_mux_addr;
>   			}
>   
> -			dev_priv->perf.oa.ops.enable_metric_set = gen8_enable_metric_set;
> -			dev_priv->perf.oa.ops.disable_metric_set = gen8_disable_metric_set;
> +			dev_priv->perf.ops.enable_metric_set =
> +				gen8_enable_metric_set;
> +			dev_priv->perf.ops.disable_metric_set =
> +				gen8_disable_metric_set;
>   
>   			if (IS_GEN(dev_priv, 8)) {
> -				dev_priv->perf.oa.ctx_oactxctrl_offset = 0x120;
> -				dev_priv->perf.oa.ctx_flexeu0_offset = 0x2ce;
> +				dev_priv->perf.ctx_oactxctrl_offset = 0x120;
> +				dev_priv->perf.ctx_flexeu0_offset = 0x2ce;
>   
> -				dev_priv->perf.oa.gen8_valid_ctx_bit = (1<<25);
> +				dev_priv->perf.gen8_valid_ctx_bit = (1<<25);
>   			} else {
> -				dev_priv->perf.oa.ctx_oactxctrl_offset = 0x128;
> -				dev_priv->perf.oa.ctx_flexeu0_offset = 0x3de;
> +				dev_priv->perf.ctx_oactxctrl_offset = 0x128;
> +				dev_priv->perf.ctx_flexeu0_offset = 0x3de;
>   
> -				dev_priv->perf.oa.gen8_valid_ctx_bit = (1<<16);
> +				dev_priv->perf.gen8_valid_ctx_bit = (1<<16);
>   			}
>   		} else if (IS_GEN_RANGE(dev_priv, 10, 11)) {
> -			dev_priv->perf.oa.ops.is_valid_b_counter_reg =
> +			dev_priv->perf.ops.is_valid_b_counter_reg =
>   				gen7_is_valid_b_counter_addr;
> -			dev_priv->perf.oa.ops.is_valid_mux_reg =
> +			dev_priv->perf.ops.is_valid_mux_reg =
>   				gen10_is_valid_mux_addr;
> -			dev_priv->perf.oa.ops.is_valid_flex_reg =
> +			dev_priv->perf.ops.is_valid_flex_reg =
>   				gen8_is_valid_flex_addr;
>   
> -			dev_priv->perf.oa.ops.enable_metric_set = gen8_enable_metric_set;
> -			dev_priv->perf.oa.ops.disable_metric_set = gen10_disable_metric_set;
> +			dev_priv->perf.ops.enable_metric_set =
> +				gen8_enable_metric_set;
> +			dev_priv->perf.ops.disable_metric_set =
> +				gen10_disable_metric_set;
>   
> -			dev_priv->perf.oa.ctx_oactxctrl_offset = 0x128;
> -			dev_priv->perf.oa.ctx_flexeu0_offset = 0x3de;
> +			dev_priv->perf.ctx_oactxctrl_offset = 0x128;
> +			dev_priv->perf.ctx_flexeu0_offset = 0x3de;
>   
> -			dev_priv->perf.oa.gen8_valid_ctx_bit = (1<<16);
> +			dev_priv->perf.gen8_valid_ctx_bit = (1<<16);
>   		}
>   	}
>   
> -	if (dev_priv->perf.oa.ops.enable_metric_set) {
> -		hrtimer_init(&dev_priv->perf.oa.poll_check_timer,
> -				CLOCK_MONOTONIC, HRTIMER_MODE_REL);
> -		dev_priv->perf.oa.poll_check_timer.function = oa_poll_check_timer_cb;
> -		init_waitqueue_head(&dev_priv->perf.oa.poll_wq);
> -
> +	if (dev_priv->perf.ops.enable_metric_set) {
>   		INIT_LIST_HEAD(&dev_priv->perf.streams);
>   		mutex_init(&dev_priv->perf.lock);
> -		spin_lock_init(&dev_priv->perf.oa.oa_buffer.ptr_lock);
>   
> +		ri = RUNTIME_INFO(dev_priv);
>   		oa_sample_rate_hard_limit = 1000 *
> -			(RUNTIME_INFO(dev_priv)->cs_timestamp_frequency_khz / 2);
> +			(ri->cs_timestamp_frequency_khz / 2);
>   		dev_priv->perf.sysctl_header = register_sysctl_table(dev_root);
>   
>   		mutex_init(&dev_priv->perf.metrics_lock);
>   		idr_init(&dev_priv->perf.metrics_idr);
>   
> +		/* We set up some ratelimit state to potentially throttle any
> +		 * _NOTES about spurious, invalid OA reports which we don't
> +		 * forward to userspace.
> +		 *
> +		 * We print a _NOTE about any throttling when closing the
> +		 * stream instead of waiting until driver _fini which no one
> +		 * would ever see.
> +		 *
> +		 * Using the same limiting factors as printk_ratelimit()
> +		 */
> +		ratelimit_state_init(&dev_priv->perf.spurious_report_rs,
> +				     5 * HZ, 10);
> +		/* Since we use a DRM_NOTE for spurious reports it would be
> +		 * inconsistent to let __ratelimit() automatically print a
> +		 * warning for throttling.
> +		 */
> +		ratelimit_set_flags(&dev_priv->perf.spurious_report_rs,
> +				    RATELIMIT_MSG_ON_RELEASE);
> +
>   		dev_priv->perf.initialized = true;
>   	}
>   }
> @@ -3528,7 +3562,7 @@ void i915_perf_fini(struct drm_i915_private *dev_priv)
>   
>   	unregister_sysctl_table(dev_priv->perf.sysctl_header);
>   
> -	memset(&dev_priv->perf.oa.ops, 0, sizeof(dev_priv->perf.oa.ops));
> +	memset(&dev_priv->perf.ops, 0, sizeof(dev_priv->perf.ops));
>   
>   	dev_priv->perf.initialized = false;
>   }
diff mbox series

Patch

diff --git a/drivers/gpu/drm/i915/gt/intel_sseu.c b/drivers/gpu/drm/i915/gt/intel_sseu.c
index 7f448f3bea0b..fa78df39521a 100644
--- a/drivers/gpu/drm/i915/gt/intel_sseu.c
+++ b/drivers/gpu/drm/i915/gt/intel_sseu.c
@@ -32,7 +32,7 @@  u32 intel_sseu_make_rpcs(struct drm_i915_private *i915,
 	 * cases which disable slices for functional, apart for performance
 	 * reasons. So in this case we select a known stable subset.
 	 */
-	if (!i915->perf.oa.exclusive_stream) {
+	if (!i915->perf.exclusive_stream) {
 		ctx_sseu = *req_sseu;
 	} else {
 		ctx_sseu = intel_sseu_from_device_info(sseu);
diff --git a/drivers/gpu/drm/i915/gvt/scheduler.c b/drivers/gpu/drm/i915/gvt/scheduler.c
index 7ae42f2ebfe8..878e71a927de 100644
--- a/drivers/gpu/drm/i915/gvt/scheduler.c
+++ b/drivers/gpu/drm/i915/gvt/scheduler.c
@@ -81,8 +81,8 @@  static void sr_oa_regs(struct intel_vgpu_workload *workload,
 		u32 *reg_state, bool save)
 {
 	struct drm_i915_private *dev_priv = workload->vgpu->gvt->dev_priv;
-	u32 ctx_oactxctrl = dev_priv->perf.oa.ctx_oactxctrl_offset;
-	u32 ctx_flexeu0 = dev_priv->perf.oa.ctx_flexeu0_offset;
+	u32 ctx_oactxctrl = dev_priv->perf.ctx_oactxctrl_offset;
+	u32 ctx_flexeu0 = dev_priv->perf.ctx_flexeu0_offset;
 	int i = 0;
 	u32 flex_mmio[] = {
 		i915_mmio_reg_offset(EU_PERF_CNTL0),
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 1cea98f8b85c..9536550f11cc 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1399,6 +1399,86 @@  struct i915_perf_stream {
 	 * @oa_config: The OA configuration used by the stream.
 	 */
 	struct i915_oa_config *oa_config;
+
+	/**
+	 * The OA context specific information.
+	 */
+	struct intel_context *pinned_ctx;
+	u32 specific_ctx_id;
+	u32 specific_ctx_id_mask;
+
+	struct hrtimer poll_check_timer;
+	wait_queue_head_t poll_wq;
+	bool pollin;
+
+	bool periodic;
+	int period_exponent;
+
+	/**
+	 * State of the OA buffer.
+	 */
+	struct {
+		struct i915_vma *vma;
+		u8 *vaddr;
+		u32 last_ctx_id;
+		int format;
+		int format_size;
+		int size_exponent;
+
+		/**
+		 * Locks reads and writes to all head/tail state
+		 *
+		 * Consider: the head and tail pointer state needs to be read
+		 * consistently from a hrtimer callback (atomic context) and
+		 * read() fop (user context) with tail pointer updates happening
+		 * in atomic context and head updates in user context and the
+		 * (unlikely) possibility of read() errors needing to reset all
+		 * head/tail state.
+		 *
+		 * Note: Contention/performance aren't currently a significant
+		 * concern here considering the relatively low frequency of
+		 * hrtimer callbacks (5ms period) and that reads typically only
+		 * happen in response to a hrtimer event and likely complete
+		 * before the next callback.
+		 *
+		 * Note: This lock is not held *while* reading and copying data
+		 * to userspace so the value of head observed in htrimer
+		 * callbacks won't represent any partial consumption of data.
+		 */
+		spinlock_t ptr_lock;
+
+		/**
+		 * One 'aging' tail pointer and one 'aged' tail pointer ready to
+		 * used for reading.
+		 *
+		 * Initial values of 0xffffffff are invalid and imply that an
+		 * update is required (and should be ignored by an attempted
+		 * read)
+		 */
+		struct {
+			u32 offset;
+		} tails[2];
+
+		/**
+		 * Index for the aged tail ready to read() data up to.
+		 */
+		unsigned int aged_tail_idx;
+
+		/**
+		 * A monotonic timestamp for when the current aging tail pointer
+		 * was read; used to determine when it is old enough to trust.
+		 */
+		u64 aging_timestamp;
+
+		/**
+		 * Although we can always read back the head pointer register,
+		 * we prefer to avoid trusting the HW state, just to avoid any
+		 * risk that some hardware condition could * somehow bump the
+		 * head pointer unpredictably and cause us to forward the wrong
+		 * OA buffer data to userspace.
+		 */
+		u32 head;
+	} oa_buffer;
 };
 
 /**
@@ -1436,7 +1516,7 @@  struct i915_oa_ops {
 	 * @disable_metric_set: Remove system constraints associated with using
 	 * the OA unit.
 	 */
-	void (*disable_metric_set)(struct drm_i915_private *dev_priv);
+	void (*disable_metric_set)(struct i915_perf_stream *stream);
 
 	/**
 	 * @oa_enable: Enable periodic sampling
@@ -1464,7 +1544,7 @@  struct i915_oa_ops {
 	 * handling the OA unit tail pointer race that affects multiple
 	 * generations.
 	 */
-	u32 (*oa_hw_tail_read)(struct drm_i915_private *dev_priv);
+	u32 (*oa_hw_tail_read)(struct i915_perf_stream *stream);
 };
 
 struct intel_cdclk_state {
@@ -1867,120 +1947,35 @@  struct drm_i915_private {
 		struct mutex lock;
 		struct list_head streams;
 
-		struct {
-			/*
-			 * The stream currently using the OA unit. If accessed
-			 * outside a syscall associated to its file
-			 * descriptor, you need to hold
-			 * dev_priv->drm.struct_mutex.
-			 */
-			struct i915_perf_stream *exclusive_stream;
+		/*
+		 * The stream currently using the OA unit. If accessed
+		 * outside a syscall associated to its file
+		 * descriptor, you need to hold
+		 * dev_priv->drm.struct_mutex.
+		 */
+		struct i915_perf_stream *exclusive_stream;
+
+		/**
+		 * For rate limiting any notifications of spurious
+		 * invalid OA reports
+		 */
+		struct ratelimit_state spurious_report_rs;
 
-			struct intel_context *pinned_ctx;
-			u32 specific_ctx_id;
-			u32 specific_ctx_id_mask;
+		struct i915_oa_config test_config;
 
-			struct hrtimer poll_check_timer;
-			wait_queue_head_t poll_wq;
-			bool pollin;
+		u32 gen7_latched_oastatus1;
+		u32 ctx_oactxctrl_offset;
+		u32 ctx_flexeu0_offset;
 
-			/**
-			 * For rate limiting any notifications of spurious
-			 * invalid OA reports
-			 */
-			struct ratelimit_state spurious_report_rs;
-
-			bool periodic;
-			int period_exponent;
-
-			struct i915_oa_config test_config;
-
-			struct {
-				struct i915_vma *vma;
-				u8 *vaddr;
-				u32 last_ctx_id;
-				int format;
-				int format_size;
-
-				/**
-				 * Locks reads and writes to all head/tail state
-				 *
-				 * Consider: the head and tail pointer state
-				 * needs to be read consistently from a hrtimer
-				 * callback (atomic context) and read() fop
-				 * (user context) with tail pointer updates
-				 * happening in atomic context and head updates
-				 * in user context and the (unlikely)
-				 * possibility of read() errors needing to
-				 * reset all head/tail state.
-				 *
-				 * Note: Contention or performance aren't
-				 * currently a significant concern here
-				 * considering the relatively low frequency of
-				 * hrtimer callbacks (5ms period) and that
-				 * reads typically only happen in response to a
-				 * hrtimer event and likely complete before the
-				 * next callback.
-				 *
-				 * Note: This lock is not held *while* reading
-				 * and copying data to userspace so the value
-				 * of head observed in htrimer callbacks won't
-				 * represent any partial consumption of data.
-				 */
-				spinlock_t ptr_lock;
-
-				/**
-				 * One 'aging' tail pointer and one 'aged'
-				 * tail pointer ready to used for reading.
-				 *
-				 * Initial values of 0xffffffff are invalid
-				 * and imply that an update is required
-				 * (and should be ignored by an attempted
-				 * read)
-				 */
-				struct {
-					u32 offset;
-				} tails[2];
-
-				/**
-				 * Index for the aged tail ready to read()
-				 * data up to.
-				 */
-				unsigned int aged_tail_idx;
-
-				/**
-				 * A monotonic timestamp for when the current
-				 * aging tail pointer was read; used to
-				 * determine when it is old enough to trust.
-				 */
-				u64 aging_timestamp;
-
-				/**
-				 * Although we can always read back the head
-				 * pointer register, we prefer to avoid
-				 * trusting the HW state, just to avoid any
-				 * risk that some hardware condition could
-				 * somehow bump the head pointer unpredictably
-				 * and cause us to forward the wrong OA buffer
-				 * data to userspace.
-				 */
-				u32 head;
-			} oa_buffer;
-
-			u32 gen7_latched_oastatus1;
-			u32 ctx_oactxctrl_offset;
-			u32 ctx_flexeu0_offset;
-
-			/**
-			 * The RPT_ID/reason field for Gen8+ includes a bit
-			 * to determine if the CTX ID in the report is valid
-			 * but the specific bit differs between Gen 8 and 9
-			 */
-			u32 gen8_valid_ctx_bit;
+		/**
+		 * The RPT_ID/reason field for Gen8+ includes a bit
+		 * to determine if the CTX ID in the report is valid
+		 * but the specific bit differs between Gen 8 and 9
+		 */
+		u32 gen8_valid_ctx_bit;
 
-			struct i915_oa_ops ops;
-			const struct i915_oa_format *oa_formats;
-		} oa;
+		struct i915_oa_ops ops;
+		const struct i915_oa_format *oa_formats;
 	} perf;
 
 	/* Abstract the submission mechanism (legacy ringbuffer or execlists) away */
diff --git a/drivers/gpu/drm/i915/i915_oa_bdw.c b/drivers/gpu/drm/i915/i915_oa_bdw.c
index 4acdb94555b7..7d632d503510 100644
--- a/drivers/gpu/drm/i915/i915_oa_bdw.c
+++ b/drivers/gpu/drm/i915/i915_oa_bdw.c
@@ -66,26 +66,26 @@  show_test_oa_id(struct device *kdev, struct device_attribute *attr, char *buf)
 void
 i915_perf_load_test_config_bdw(struct drm_i915_private *dev_priv)
 {
-	strlcpy(dev_priv->perf.oa.test_config.uuid,
+	strlcpy(dev_priv->perf.test_config.uuid,
 		"d6de6f55-e526-4f79-a6a6-d7315c09044e",
-		sizeof(dev_priv->perf.oa.test_config.uuid));
-	dev_priv->perf.oa.test_config.id = 1;
+		sizeof(dev_priv->perf.test_config.uuid));
+	dev_priv->perf.test_config.id = 1;
 
-	dev_priv->perf.oa.test_config.mux_regs = mux_config_test_oa;
-	dev_priv->perf.oa.test_config.mux_regs_len = ARRAY_SIZE(mux_config_test_oa);
+	dev_priv->perf.test_config.mux_regs = mux_config_test_oa;
+	dev_priv->perf.test_config.mux_regs_len = ARRAY_SIZE(mux_config_test_oa);
 
-	dev_priv->perf.oa.test_config.b_counter_regs = b_counter_config_test_oa;
-	dev_priv->perf.oa.test_config.b_counter_regs_len = ARRAY_SIZE(b_counter_config_test_oa);
+	dev_priv->perf.test_config.b_counter_regs = b_counter_config_test_oa;
+	dev_priv->perf.test_config.b_counter_regs_len = ARRAY_SIZE(b_counter_config_test_oa);
 
-	dev_priv->perf.oa.test_config.flex_regs = flex_eu_config_test_oa;
-	dev_priv->perf.oa.test_config.flex_regs_len = ARRAY_SIZE(flex_eu_config_test_oa);
+	dev_priv->perf.test_config.flex_regs = flex_eu_config_test_oa;
+	dev_priv->perf.test_config.flex_regs_len = ARRAY_SIZE(flex_eu_config_test_oa);
 
-	dev_priv->perf.oa.test_config.sysfs_metric.name = "d6de6f55-e526-4f79-a6a6-d7315c09044e";
-	dev_priv->perf.oa.test_config.sysfs_metric.attrs = dev_priv->perf.oa.test_config.attrs;
+	dev_priv->perf.test_config.sysfs_metric.name = "d6de6f55-e526-4f79-a6a6-d7315c09044e";
+	dev_priv->perf.test_config.sysfs_metric.attrs = dev_priv->perf.test_config.attrs;
 
-	dev_priv->perf.oa.test_config.attrs[0] = &dev_priv->perf.oa.test_config.sysfs_metric_id.attr;
+	dev_priv->perf.test_config.attrs[0] = &dev_priv->perf.test_config.sysfs_metric_id.attr;
 
-	dev_priv->perf.oa.test_config.sysfs_metric_id.attr.name = "id";
-	dev_priv->perf.oa.test_config.sysfs_metric_id.attr.mode = 0444;
-	dev_priv->perf.oa.test_config.sysfs_metric_id.show = show_test_oa_id;
+	dev_priv->perf.test_config.sysfs_metric_id.attr.name = "id";
+	dev_priv->perf.test_config.sysfs_metric_id.attr.mode = 0444;
+	dev_priv->perf.test_config.sysfs_metric_id.show = show_test_oa_id;
 }
diff --git a/drivers/gpu/drm/i915/i915_oa_bxt.c b/drivers/gpu/drm/i915/i915_oa_bxt.c
index a44195c39923..a4cc584fb5c9 100644
--- a/drivers/gpu/drm/i915/i915_oa_bxt.c
+++ b/drivers/gpu/drm/i915/i915_oa_bxt.c
@@ -64,26 +64,26 @@  show_test_oa_id(struct device *kdev, struct device_attribute *attr, char *buf)
 void
 i915_perf_load_test_config_bxt(struct drm_i915_private *dev_priv)
 {
-	strlcpy(dev_priv->perf.oa.test_config.uuid,
+	strlcpy(dev_priv->perf.test_config.uuid,
 		"5ee72f5c-092f-421e-8b70-225f7c3e9612",
-		sizeof(dev_priv->perf.oa.test_config.uuid));
-	dev_priv->perf.oa.test_config.id = 1;
+		sizeof(dev_priv->perf.test_config.uuid));
+	dev_priv->perf.test_config.id = 1;
 
-	dev_priv->perf.oa.test_config.mux_regs = mux_config_test_oa;
-	dev_priv->perf.oa.test_config.mux_regs_len = ARRAY_SIZE(mux_config_test_oa);
+	dev_priv->perf.test_config.mux_regs = mux_config_test_oa;
+	dev_priv->perf.test_config.mux_regs_len = ARRAY_SIZE(mux_config_test_oa);
 
-	dev_priv->perf.oa.test_config.b_counter_regs = b_counter_config_test_oa;
-	dev_priv->perf.oa.test_config.b_counter_regs_len = ARRAY_SIZE(b_counter_config_test_oa);
+	dev_priv->perf.test_config.b_counter_regs = b_counter_config_test_oa;
+	dev_priv->perf.test_config.b_counter_regs_len = ARRAY_SIZE(b_counter_config_test_oa);
 
-	dev_priv->perf.oa.test_config.flex_regs = flex_eu_config_test_oa;
-	dev_priv->perf.oa.test_config.flex_regs_len = ARRAY_SIZE(flex_eu_config_test_oa);
+	dev_priv->perf.test_config.flex_regs = flex_eu_config_test_oa;
+	dev_priv->perf.test_config.flex_regs_len = ARRAY_SIZE(flex_eu_config_test_oa);
 
-	dev_priv->perf.oa.test_config.sysfs_metric.name = "5ee72f5c-092f-421e-8b70-225f7c3e9612";
-	dev_priv->perf.oa.test_config.sysfs_metric.attrs = dev_priv->perf.oa.test_config.attrs;
+	dev_priv->perf.test_config.sysfs_metric.name = "5ee72f5c-092f-421e-8b70-225f7c3e9612";
+	dev_priv->perf.test_config.sysfs_metric.attrs = dev_priv->perf.test_config.attrs;
 
-	dev_priv->perf.oa.test_config.attrs[0] = &dev_priv->perf.oa.test_config.sysfs_metric_id.attr;
+	dev_priv->perf.test_config.attrs[0] = &dev_priv->perf.test_config.sysfs_metric_id.attr;
 
-	dev_priv->perf.oa.test_config.sysfs_metric_id.attr.name = "id";
-	dev_priv->perf.oa.test_config.sysfs_metric_id.attr.mode = 0444;
-	dev_priv->perf.oa.test_config.sysfs_metric_id.show = show_test_oa_id;
+	dev_priv->perf.test_config.sysfs_metric_id.attr.name = "id";
+	dev_priv->perf.test_config.sysfs_metric_id.attr.mode = 0444;
+	dev_priv->perf.test_config.sysfs_metric_id.show = show_test_oa_id;
 }
diff --git a/drivers/gpu/drm/i915/i915_oa_cflgt2.c b/drivers/gpu/drm/i915/i915_oa_cflgt2.c
index 7f60d51b8761..51930c71bf7c 100644
--- a/drivers/gpu/drm/i915/i915_oa_cflgt2.c
+++ b/drivers/gpu/drm/i915/i915_oa_cflgt2.c
@@ -65,26 +65,26 @@  show_test_oa_id(struct device *kdev, struct device_attribute *attr, char *buf)
 void
 i915_perf_load_test_config_cflgt2(struct drm_i915_private *dev_priv)
 {
-	strlcpy(dev_priv->perf.oa.test_config.uuid,
+	strlcpy(dev_priv->perf.test_config.uuid,
 		"74fb4902-d3d3-4237-9e90-cbdc68d0a446",
-		sizeof(dev_priv->perf.oa.test_config.uuid));
-	dev_priv->perf.oa.test_config.id = 1;
+		sizeof(dev_priv->perf.test_config.uuid));
+	dev_priv->perf.test_config.id = 1;
 
-	dev_priv->perf.oa.test_config.mux_regs = mux_config_test_oa;
-	dev_priv->perf.oa.test_config.mux_regs_len = ARRAY_SIZE(mux_config_test_oa);
+	dev_priv->perf.test_config.mux_regs = mux_config_test_oa;
+	dev_priv->perf.test_config.mux_regs_len = ARRAY_SIZE(mux_config_test_oa);
 
-	dev_priv->perf.oa.test_config.b_counter_regs = b_counter_config_test_oa;
-	dev_priv->perf.oa.test_config.b_counter_regs_len = ARRAY_SIZE(b_counter_config_test_oa);
+	dev_priv->perf.test_config.b_counter_regs = b_counter_config_test_oa;
+	dev_priv->perf.test_config.b_counter_regs_len = ARRAY_SIZE(b_counter_config_test_oa);
 
-	dev_priv->perf.oa.test_config.flex_regs = flex_eu_config_test_oa;
-	dev_priv->perf.oa.test_config.flex_regs_len = ARRAY_SIZE(flex_eu_config_test_oa);
+	dev_priv->perf.test_config.flex_regs = flex_eu_config_test_oa;
+	dev_priv->perf.test_config.flex_regs_len = ARRAY_SIZE(flex_eu_config_test_oa);
 
-	dev_priv->perf.oa.test_config.sysfs_metric.name = "74fb4902-d3d3-4237-9e90-cbdc68d0a446";
-	dev_priv->perf.oa.test_config.sysfs_metric.attrs = dev_priv->perf.oa.test_config.attrs;
+	dev_priv->perf.test_config.sysfs_metric.name = "74fb4902-d3d3-4237-9e90-cbdc68d0a446";
+	dev_priv->perf.test_config.sysfs_metric.attrs = dev_priv->perf.test_config.attrs;
 
-	dev_priv->perf.oa.test_config.attrs[0] = &dev_priv->perf.oa.test_config.sysfs_metric_id.attr;
+	dev_priv->perf.test_config.attrs[0] = &dev_priv->perf.test_config.sysfs_metric_id.attr;
 
-	dev_priv->perf.oa.test_config.sysfs_metric_id.attr.name = "id";
-	dev_priv->perf.oa.test_config.sysfs_metric_id.attr.mode = 0444;
-	dev_priv->perf.oa.test_config.sysfs_metric_id.show = show_test_oa_id;
+	dev_priv->perf.test_config.sysfs_metric_id.attr.name = "id";
+	dev_priv->perf.test_config.sysfs_metric_id.attr.mode = 0444;
+	dev_priv->perf.test_config.sysfs_metric_id.show = show_test_oa_id;
 }
diff --git a/drivers/gpu/drm/i915/i915_oa_cflgt3.c b/drivers/gpu/drm/i915/i915_oa_cflgt3.c
index a92c38e3a0ce..de630b53d364 100644
--- a/drivers/gpu/drm/i915/i915_oa_cflgt3.c
+++ b/drivers/gpu/drm/i915/i915_oa_cflgt3.c
@@ -65,26 +65,26 @@  show_test_oa_id(struct device *kdev, struct device_attribute *attr, char *buf)
 void
 i915_perf_load_test_config_cflgt3(struct drm_i915_private *dev_priv)
 {
-	strlcpy(dev_priv->perf.oa.test_config.uuid,
+	strlcpy(dev_priv->perf.test_config.uuid,
 		"577e8e2c-3fa0-4875-8743-3538d585e3b0",
-		sizeof(dev_priv->perf.oa.test_config.uuid));
-	dev_priv->perf.oa.test_config.id = 1;
+		sizeof(dev_priv->perf.test_config.uuid));
+	dev_priv->perf.test_config.id = 1;
 
-	dev_priv->perf.oa.test_config.mux_regs = mux_config_test_oa;
-	dev_priv->perf.oa.test_config.mux_regs_len = ARRAY_SIZE(mux_config_test_oa);
+	dev_priv->perf.test_config.mux_regs = mux_config_test_oa;
+	dev_priv->perf.test_config.mux_regs_len = ARRAY_SIZE(mux_config_test_oa);
 
-	dev_priv->perf.oa.test_config.b_counter_regs = b_counter_config_test_oa;
-	dev_priv->perf.oa.test_config.b_counter_regs_len = ARRAY_SIZE(b_counter_config_test_oa);
+	dev_priv->perf.test_config.b_counter_regs = b_counter_config_test_oa;
+	dev_priv->perf.test_config.b_counter_regs_len = ARRAY_SIZE(b_counter_config_test_oa);
 
-	dev_priv->perf.oa.test_config.flex_regs = flex_eu_config_test_oa;
-	dev_priv->perf.oa.test_config.flex_regs_len = ARRAY_SIZE(flex_eu_config_test_oa);
+	dev_priv->perf.test_config.flex_regs = flex_eu_config_test_oa;
+	dev_priv->perf.test_config.flex_regs_len = ARRAY_SIZE(flex_eu_config_test_oa);
 
-	dev_priv->perf.oa.test_config.sysfs_metric.name = "577e8e2c-3fa0-4875-8743-3538d585e3b0";
-	dev_priv->perf.oa.test_config.sysfs_metric.attrs = dev_priv->perf.oa.test_config.attrs;
+	dev_priv->perf.test_config.sysfs_metric.name = "577e8e2c-3fa0-4875-8743-3538d585e3b0";
+	dev_priv->perf.test_config.sysfs_metric.attrs = dev_priv->perf.test_config.attrs;
 
-	dev_priv->perf.oa.test_config.attrs[0] = &dev_priv->perf.oa.test_config.sysfs_metric_id.attr;
+	dev_priv->perf.test_config.attrs[0] = &dev_priv->perf.test_config.sysfs_metric_id.attr;
 
-	dev_priv->perf.oa.test_config.sysfs_metric_id.attr.name = "id";
-	dev_priv->perf.oa.test_config.sysfs_metric_id.attr.mode = 0444;
-	dev_priv->perf.oa.test_config.sysfs_metric_id.show = show_test_oa_id;
+	dev_priv->perf.test_config.sysfs_metric_id.attr.name = "id";
+	dev_priv->perf.test_config.sysfs_metric_id.attr.mode = 0444;
+	dev_priv->perf.test_config.sysfs_metric_id.show = show_test_oa_id;
 }
diff --git a/drivers/gpu/drm/i915/i915_oa_chv.c b/drivers/gpu/drm/i915/i915_oa_chv.c
index 71ec889a0114..7d7f33c4468f 100644
--- a/drivers/gpu/drm/i915/i915_oa_chv.c
+++ b/drivers/gpu/drm/i915/i915_oa_chv.c
@@ -65,26 +65,26 @@  show_test_oa_id(struct device *kdev, struct device_attribute *attr, char *buf)
 void
 i915_perf_load_test_config_chv(struct drm_i915_private *dev_priv)
 {
-	strlcpy(dev_priv->perf.oa.test_config.uuid,
+	strlcpy(dev_priv->perf.test_config.uuid,
 		"4a534b07-cba3-414d-8d60-874830e883aa",
-		sizeof(dev_priv->perf.oa.test_config.uuid));
-	dev_priv->perf.oa.test_config.id = 1;
+		sizeof(dev_priv->perf.test_config.uuid));
+	dev_priv->perf.test_config.id = 1;
 
-	dev_priv->perf.oa.test_config.mux_regs = mux_config_test_oa;
-	dev_priv->perf.oa.test_config.mux_regs_len = ARRAY_SIZE(mux_config_test_oa);
+	dev_priv->perf.test_config.mux_regs = mux_config_test_oa;
+	dev_priv->perf.test_config.mux_regs_len = ARRAY_SIZE(mux_config_test_oa);
 
-	dev_priv->perf.oa.test_config.b_counter_regs = b_counter_config_test_oa;
-	dev_priv->perf.oa.test_config.b_counter_regs_len = ARRAY_SIZE(b_counter_config_test_oa);
+	dev_priv->perf.test_config.b_counter_regs = b_counter_config_test_oa;
+	dev_priv->perf.test_config.b_counter_regs_len = ARRAY_SIZE(b_counter_config_test_oa);
 
-	dev_priv->perf.oa.test_config.flex_regs = flex_eu_config_test_oa;
-	dev_priv->perf.oa.test_config.flex_regs_len = ARRAY_SIZE(flex_eu_config_test_oa);
+	dev_priv->perf.test_config.flex_regs = flex_eu_config_test_oa;
+	dev_priv->perf.test_config.flex_regs_len = ARRAY_SIZE(flex_eu_config_test_oa);
 
-	dev_priv->perf.oa.test_config.sysfs_metric.name = "4a534b07-cba3-414d-8d60-874830e883aa";
-	dev_priv->perf.oa.test_config.sysfs_metric.attrs = dev_priv->perf.oa.test_config.attrs;
+	dev_priv->perf.test_config.sysfs_metric.name = "4a534b07-cba3-414d-8d60-874830e883aa";
+	dev_priv->perf.test_config.sysfs_metric.attrs = dev_priv->perf.test_config.attrs;
 
-	dev_priv->perf.oa.test_config.attrs[0] = &dev_priv->perf.oa.test_config.sysfs_metric_id.attr;
+	dev_priv->perf.test_config.attrs[0] = &dev_priv->perf.test_config.sysfs_metric_id.attr;
 
-	dev_priv->perf.oa.test_config.sysfs_metric_id.attr.name = "id";
-	dev_priv->perf.oa.test_config.sysfs_metric_id.attr.mode = 0444;
-	dev_priv->perf.oa.test_config.sysfs_metric_id.show = show_test_oa_id;
+	dev_priv->perf.test_config.sysfs_metric_id.attr.name = "id";
+	dev_priv->perf.test_config.sysfs_metric_id.attr.mode = 0444;
+	dev_priv->perf.test_config.sysfs_metric_id.show = show_test_oa_id;
 }
diff --git a/drivers/gpu/drm/i915/i915_oa_cnl.c b/drivers/gpu/drm/i915/i915_oa_cnl.c
index 5c23d883d6c9..4ae86a8983c3 100644
--- a/drivers/gpu/drm/i915/i915_oa_cnl.c
+++ b/drivers/gpu/drm/i915/i915_oa_cnl.c
@@ -77,26 +77,26 @@  show_test_oa_id(struct device *kdev, struct device_attribute *attr, char *buf)
 void
 i915_perf_load_test_config_cnl(struct drm_i915_private *dev_priv)
 {
-	strlcpy(dev_priv->perf.oa.test_config.uuid,
+	strlcpy(dev_priv->perf.test_config.uuid,
 		"db41edd4-d8e7-4730-ad11-b9a2d6833503",
-		sizeof(dev_priv->perf.oa.test_config.uuid));
-	dev_priv->perf.oa.test_config.id = 1;
+		sizeof(dev_priv->perf.test_config.uuid));
+	dev_priv->perf.test_config.id = 1;
 
-	dev_priv->perf.oa.test_config.mux_regs = mux_config_test_oa;
-	dev_priv->perf.oa.test_config.mux_regs_len = ARRAY_SIZE(mux_config_test_oa);
+	dev_priv->perf.test_config.mux_regs = mux_config_test_oa;
+	dev_priv->perf.test_config.mux_regs_len = ARRAY_SIZE(mux_config_test_oa);
 
-	dev_priv->perf.oa.test_config.b_counter_regs = b_counter_config_test_oa;
-	dev_priv->perf.oa.test_config.b_counter_regs_len = ARRAY_SIZE(b_counter_config_test_oa);
+	dev_priv->perf.test_config.b_counter_regs = b_counter_config_test_oa;
+	dev_priv->perf.test_config.b_counter_regs_len = ARRAY_SIZE(b_counter_config_test_oa);
 
-	dev_priv->perf.oa.test_config.flex_regs = flex_eu_config_test_oa;
-	dev_priv->perf.oa.test_config.flex_regs_len = ARRAY_SIZE(flex_eu_config_test_oa);
+	dev_priv->perf.test_config.flex_regs = flex_eu_config_test_oa;
+	dev_priv->perf.test_config.flex_regs_len = ARRAY_SIZE(flex_eu_config_test_oa);
 
-	dev_priv->perf.oa.test_config.sysfs_metric.name = "db41edd4-d8e7-4730-ad11-b9a2d6833503";
-	dev_priv->perf.oa.test_config.sysfs_metric.attrs = dev_priv->perf.oa.test_config.attrs;
+	dev_priv->perf.test_config.sysfs_metric.name = "db41edd4-d8e7-4730-ad11-b9a2d6833503";
+	dev_priv->perf.test_config.sysfs_metric.attrs = dev_priv->perf.test_config.attrs;
 
-	dev_priv->perf.oa.test_config.attrs[0] = &dev_priv->perf.oa.test_config.sysfs_metric_id.attr;
+	dev_priv->perf.test_config.attrs[0] = &dev_priv->perf.test_config.sysfs_metric_id.attr;
 
-	dev_priv->perf.oa.test_config.sysfs_metric_id.attr.name = "id";
-	dev_priv->perf.oa.test_config.sysfs_metric_id.attr.mode = 0444;
-	dev_priv->perf.oa.test_config.sysfs_metric_id.show = show_test_oa_id;
+	dev_priv->perf.test_config.sysfs_metric_id.attr.name = "id";
+	dev_priv->perf.test_config.sysfs_metric_id.attr.mode = 0444;
+	dev_priv->perf.test_config.sysfs_metric_id.show = show_test_oa_id;
 }
diff --git a/drivers/gpu/drm/i915/i915_oa_glk.c b/drivers/gpu/drm/i915/i915_oa_glk.c
index 4bdda66df7d2..d8d634dca158 100644
--- a/drivers/gpu/drm/i915/i915_oa_glk.c
+++ b/drivers/gpu/drm/i915/i915_oa_glk.c
@@ -64,26 +64,26 @@  show_test_oa_id(struct device *kdev, struct device_attribute *attr, char *buf)
 void
 i915_perf_load_test_config_glk(struct drm_i915_private *dev_priv)
 {
-	strlcpy(dev_priv->perf.oa.test_config.uuid,
+	strlcpy(dev_priv->perf.test_config.uuid,
 		"dd3fd789-e783-4204-8cd0-b671bbccb0cf",
-		sizeof(dev_priv->perf.oa.test_config.uuid));
-	dev_priv->perf.oa.test_config.id = 1;
+		sizeof(dev_priv->perf.test_config.uuid));
+	dev_priv->perf.test_config.id = 1;
 
-	dev_priv->perf.oa.test_config.mux_regs = mux_config_test_oa;
-	dev_priv->perf.oa.test_config.mux_regs_len = ARRAY_SIZE(mux_config_test_oa);
+	dev_priv->perf.test_config.mux_regs = mux_config_test_oa;
+	dev_priv->perf.test_config.mux_regs_len = ARRAY_SIZE(mux_config_test_oa);
 
-	dev_priv->perf.oa.test_config.b_counter_regs = b_counter_config_test_oa;
-	dev_priv->perf.oa.test_config.b_counter_regs_len = ARRAY_SIZE(b_counter_config_test_oa);
+	dev_priv->perf.test_config.b_counter_regs = b_counter_config_test_oa;
+	dev_priv->perf.test_config.b_counter_regs_len = ARRAY_SIZE(b_counter_config_test_oa);
 
-	dev_priv->perf.oa.test_config.flex_regs = flex_eu_config_test_oa;
-	dev_priv->perf.oa.test_config.flex_regs_len = ARRAY_SIZE(flex_eu_config_test_oa);
+	dev_priv->perf.test_config.flex_regs = flex_eu_config_test_oa;
+	dev_priv->perf.test_config.flex_regs_len = ARRAY_SIZE(flex_eu_config_test_oa);
 
-	dev_priv->perf.oa.test_config.sysfs_metric.name = "dd3fd789-e783-4204-8cd0-b671bbccb0cf";
-	dev_priv->perf.oa.test_config.sysfs_metric.attrs = dev_priv->perf.oa.test_config.attrs;
+	dev_priv->perf.test_config.sysfs_metric.name = "dd3fd789-e783-4204-8cd0-b671bbccb0cf";
+	dev_priv->perf.test_config.sysfs_metric.attrs = dev_priv->perf.test_config.attrs;
 
-	dev_priv->perf.oa.test_config.attrs[0] = &dev_priv->perf.oa.test_config.sysfs_metric_id.attr;
+	dev_priv->perf.test_config.attrs[0] = &dev_priv->perf.test_config.sysfs_metric_id.attr;
 
-	dev_priv->perf.oa.test_config.sysfs_metric_id.attr.name = "id";
-	dev_priv->perf.oa.test_config.sysfs_metric_id.attr.mode = 0444;
-	dev_priv->perf.oa.test_config.sysfs_metric_id.show = show_test_oa_id;
+	dev_priv->perf.test_config.sysfs_metric_id.attr.name = "id";
+	dev_priv->perf.test_config.sysfs_metric_id.attr.mode = 0444;
+	dev_priv->perf.test_config.sysfs_metric_id.show = show_test_oa_id;
 }
diff --git a/drivers/gpu/drm/i915/i915_oa_hsw.c b/drivers/gpu/drm/i915/i915_oa_hsw.c
index cc6526fdd2bd..7032277876db 100644
--- a/drivers/gpu/drm/i915/i915_oa_hsw.c
+++ b/drivers/gpu/drm/i915/i915_oa_hsw.c
@@ -94,26 +94,26 @@  show_render_basic_id(struct device *kdev, struct device_attribute *attr, char *b
 void
 i915_perf_load_test_config_hsw(struct drm_i915_private *dev_priv)
 {
-	strlcpy(dev_priv->perf.oa.test_config.uuid,
+	strlcpy(dev_priv->perf.test_config.uuid,
 		"403d8832-1a27-4aa6-a64e-f5389ce7b212",
-		sizeof(dev_priv->perf.oa.test_config.uuid));
-	dev_priv->perf.oa.test_config.id = 1;
+		sizeof(dev_priv->perf.test_config.uuid));
+	dev_priv->perf.test_config.id = 1;
 
-	dev_priv->perf.oa.test_config.mux_regs = mux_config_render_basic;
-	dev_priv->perf.oa.test_config.mux_regs_len = ARRAY_SIZE(mux_config_render_basic);
+	dev_priv->perf.test_config.mux_regs = mux_config_render_basic;
+	dev_priv->perf.test_config.mux_regs_len = ARRAY_SIZE(mux_config_render_basic);
 
-	dev_priv->perf.oa.test_config.b_counter_regs = b_counter_config_render_basic;
-	dev_priv->perf.oa.test_config.b_counter_regs_len = ARRAY_SIZE(b_counter_config_render_basic);
+	dev_priv->perf.test_config.b_counter_regs = b_counter_config_render_basic;
+	dev_priv->perf.test_config.b_counter_regs_len = ARRAY_SIZE(b_counter_config_render_basic);
 
-	dev_priv->perf.oa.test_config.flex_regs = flex_eu_config_render_basic;
-	dev_priv->perf.oa.test_config.flex_regs_len = ARRAY_SIZE(flex_eu_config_render_basic);
+	dev_priv->perf.test_config.flex_regs = flex_eu_config_render_basic;
+	dev_priv->perf.test_config.flex_regs_len = ARRAY_SIZE(flex_eu_config_render_basic);
 
-	dev_priv->perf.oa.test_config.sysfs_metric.name = "403d8832-1a27-4aa6-a64e-f5389ce7b212";
-	dev_priv->perf.oa.test_config.sysfs_metric.attrs = dev_priv->perf.oa.test_config.attrs;
+	dev_priv->perf.test_config.sysfs_metric.name = "403d8832-1a27-4aa6-a64e-f5389ce7b212";
+	dev_priv->perf.test_config.sysfs_metric.attrs = dev_priv->perf.test_config.attrs;
 
-	dev_priv->perf.oa.test_config.attrs[0] = &dev_priv->perf.oa.test_config.sysfs_metric_id.attr;
+	dev_priv->perf.test_config.attrs[0] = &dev_priv->perf.test_config.sysfs_metric_id.attr;
 
-	dev_priv->perf.oa.test_config.sysfs_metric_id.attr.name = "id";
-	dev_priv->perf.oa.test_config.sysfs_metric_id.attr.mode = 0444;
-	dev_priv->perf.oa.test_config.sysfs_metric_id.show = show_render_basic_id;
+	dev_priv->perf.test_config.sysfs_metric_id.attr.name = "id";
+	dev_priv->perf.test_config.sysfs_metric_id.attr.mode = 0444;
+	dev_priv->perf.test_config.sysfs_metric_id.show = show_render_basic_id;
 }
diff --git a/drivers/gpu/drm/i915/i915_oa_icl.c b/drivers/gpu/drm/i915/i915_oa_icl.c
index baa51427a543..bca23f150626 100644
--- a/drivers/gpu/drm/i915/i915_oa_icl.c
+++ b/drivers/gpu/drm/i915/i915_oa_icl.c
@@ -74,26 +74,26 @@  show_test_oa_id(struct device *kdev, struct device_attribute *attr, char *buf)
 void
 i915_perf_load_test_config_icl(struct drm_i915_private *dev_priv)
 {
-	strlcpy(dev_priv->perf.oa.test_config.uuid,
+	strlcpy(dev_priv->perf.test_config.uuid,
 		"a291665e-244b-4b76-9b9a-01de9d3c8068",
-		sizeof(dev_priv->perf.oa.test_config.uuid));
-	dev_priv->perf.oa.test_config.id = 1;
+		sizeof(dev_priv->perf.test_config.uuid));
+	dev_priv->perf.test_config.id = 1;
 
-	dev_priv->perf.oa.test_config.mux_regs = mux_config_test_oa;
-	dev_priv->perf.oa.test_config.mux_regs_len = ARRAY_SIZE(mux_config_test_oa);
+	dev_priv->perf.test_config.mux_regs = mux_config_test_oa;
+	dev_priv->perf.test_config.mux_regs_len = ARRAY_SIZE(mux_config_test_oa);
 
-	dev_priv->perf.oa.test_config.b_counter_regs = b_counter_config_test_oa;
-	dev_priv->perf.oa.test_config.b_counter_regs_len = ARRAY_SIZE(b_counter_config_test_oa);
+	dev_priv->perf.test_config.b_counter_regs = b_counter_config_test_oa;
+	dev_priv->perf.test_config.b_counter_regs_len = ARRAY_SIZE(b_counter_config_test_oa);
 
-	dev_priv->perf.oa.test_config.flex_regs = flex_eu_config_test_oa;
-	dev_priv->perf.oa.test_config.flex_regs_len = ARRAY_SIZE(flex_eu_config_test_oa);
+	dev_priv->perf.test_config.flex_regs = flex_eu_config_test_oa;
+	dev_priv->perf.test_config.flex_regs_len = ARRAY_SIZE(flex_eu_config_test_oa);
 
-	dev_priv->perf.oa.test_config.sysfs_metric.name = "a291665e-244b-4b76-9b9a-01de9d3c8068";
-	dev_priv->perf.oa.test_config.sysfs_metric.attrs = dev_priv->perf.oa.test_config.attrs;
+	dev_priv->perf.test_config.sysfs_metric.name = "a291665e-244b-4b76-9b9a-01de9d3c8068";
+	dev_priv->perf.test_config.sysfs_metric.attrs = dev_priv->perf.test_config.attrs;
 
-	dev_priv->perf.oa.test_config.attrs[0] = &dev_priv->perf.oa.test_config.sysfs_metric_id.attr;
+	dev_priv->perf.test_config.attrs[0] = &dev_priv->perf.test_config.sysfs_metric_id.attr;
 
-	dev_priv->perf.oa.test_config.sysfs_metric_id.attr.name = "id";
-	dev_priv->perf.oa.test_config.sysfs_metric_id.attr.mode = 0444;
-	dev_priv->perf.oa.test_config.sysfs_metric_id.show = show_test_oa_id;
+	dev_priv->perf.test_config.sysfs_metric_id.attr.name = "id";
+	dev_priv->perf.test_config.sysfs_metric_id.attr.mode = 0444;
+	dev_priv->perf.test_config.sysfs_metric_id.show = show_test_oa_id;
 }
diff --git a/drivers/gpu/drm/i915/i915_oa_kblgt2.c b/drivers/gpu/drm/i915/i915_oa_kblgt2.c
index 168e49ab0d4d..2e1d12f78c9b 100644
--- a/drivers/gpu/drm/i915/i915_oa_kblgt2.c
+++ b/drivers/gpu/drm/i915/i915_oa_kblgt2.c
@@ -65,26 +65,26 @@  show_test_oa_id(struct device *kdev, struct device_attribute *attr, char *buf)
 void
 i915_perf_load_test_config_kblgt2(struct drm_i915_private *dev_priv)
 {
-	strlcpy(dev_priv->perf.oa.test_config.uuid,
+	strlcpy(dev_priv->perf.test_config.uuid,
 		"baa3c7e4-52b6-4b85-801e-465a94b746dd",
-		sizeof(dev_priv->perf.oa.test_config.uuid));
-	dev_priv->perf.oa.test_config.id = 1;
+		sizeof(dev_priv->perf.test_config.uuid));
+	dev_priv->perf.test_config.id = 1;
 
-	dev_priv->perf.oa.test_config.mux_regs = mux_config_test_oa;
-	dev_priv->perf.oa.test_config.mux_regs_len = ARRAY_SIZE(mux_config_test_oa);
+	dev_priv->perf.test_config.mux_regs = mux_config_test_oa;
+	dev_priv->perf.test_config.mux_regs_len = ARRAY_SIZE(mux_config_test_oa);
 
-	dev_priv->perf.oa.test_config.b_counter_regs = b_counter_config_test_oa;
-	dev_priv->perf.oa.test_config.b_counter_regs_len = ARRAY_SIZE(b_counter_config_test_oa);
+	dev_priv->perf.test_config.b_counter_regs = b_counter_config_test_oa;
+	dev_priv->perf.test_config.b_counter_regs_len = ARRAY_SIZE(b_counter_config_test_oa);
 
-	dev_priv->perf.oa.test_config.flex_regs = flex_eu_config_test_oa;
-	dev_priv->perf.oa.test_config.flex_regs_len = ARRAY_SIZE(flex_eu_config_test_oa);
+	dev_priv->perf.test_config.flex_regs = flex_eu_config_test_oa;
+	dev_priv->perf.test_config.flex_regs_len = ARRAY_SIZE(flex_eu_config_test_oa);
 
-	dev_priv->perf.oa.test_config.sysfs_metric.name = "baa3c7e4-52b6-4b85-801e-465a94b746dd";
-	dev_priv->perf.oa.test_config.sysfs_metric.attrs = dev_priv->perf.oa.test_config.attrs;
+	dev_priv->perf.test_config.sysfs_metric.name = "baa3c7e4-52b6-4b85-801e-465a94b746dd";
+	dev_priv->perf.test_config.sysfs_metric.attrs = dev_priv->perf.test_config.attrs;
 
-	dev_priv->perf.oa.test_config.attrs[0] = &dev_priv->perf.oa.test_config.sysfs_metric_id.attr;
+	dev_priv->perf.test_config.attrs[0] = &dev_priv->perf.test_config.sysfs_metric_id.attr;
 
-	dev_priv->perf.oa.test_config.sysfs_metric_id.attr.name = "id";
-	dev_priv->perf.oa.test_config.sysfs_metric_id.attr.mode = 0444;
-	dev_priv->perf.oa.test_config.sysfs_metric_id.show = show_test_oa_id;
+	dev_priv->perf.test_config.sysfs_metric_id.attr.name = "id";
+	dev_priv->perf.test_config.sysfs_metric_id.attr.mode = 0444;
+	dev_priv->perf.test_config.sysfs_metric_id.show = show_test_oa_id;
 }
diff --git a/drivers/gpu/drm/i915/i915_oa_kblgt3.c b/drivers/gpu/drm/i915/i915_oa_kblgt3.c
index 6ffa553c388e..07a8567bd5be 100644
--- a/drivers/gpu/drm/i915/i915_oa_kblgt3.c
+++ b/drivers/gpu/drm/i915/i915_oa_kblgt3.c
@@ -65,26 +65,26 @@  show_test_oa_id(struct device *kdev, struct device_attribute *attr, char *buf)
 void
 i915_perf_load_test_config_kblgt3(struct drm_i915_private *dev_priv)
 {
-	strlcpy(dev_priv->perf.oa.test_config.uuid,
+	strlcpy(dev_priv->perf.test_config.uuid,
 		"f1792f32-6db2-4b50-b4b2-557128f1688d",
-		sizeof(dev_priv->perf.oa.test_config.uuid));
-	dev_priv->perf.oa.test_config.id = 1;
+		sizeof(dev_priv->perf.test_config.uuid));
+	dev_priv->perf.test_config.id = 1;
 
-	dev_priv->perf.oa.test_config.mux_regs = mux_config_test_oa;
-	dev_priv->perf.oa.test_config.mux_regs_len = ARRAY_SIZE(mux_config_test_oa);
+	dev_priv->perf.test_config.mux_regs = mux_config_test_oa;
+	dev_priv->perf.test_config.mux_regs_len = ARRAY_SIZE(mux_config_test_oa);
 
-	dev_priv->perf.oa.test_config.b_counter_regs = b_counter_config_test_oa;
-	dev_priv->perf.oa.test_config.b_counter_regs_len = ARRAY_SIZE(b_counter_config_test_oa);
+	dev_priv->perf.test_config.b_counter_regs = b_counter_config_test_oa;
+	dev_priv->perf.test_config.b_counter_regs_len = ARRAY_SIZE(b_counter_config_test_oa);
 
-	dev_priv->perf.oa.test_config.flex_regs = flex_eu_config_test_oa;
-	dev_priv->perf.oa.test_config.flex_regs_len = ARRAY_SIZE(flex_eu_config_test_oa);
+	dev_priv->perf.test_config.flex_regs = flex_eu_config_test_oa;
+	dev_priv->perf.test_config.flex_regs_len = ARRAY_SIZE(flex_eu_config_test_oa);
 
-	dev_priv->perf.oa.test_config.sysfs_metric.name = "f1792f32-6db2-4b50-b4b2-557128f1688d";
-	dev_priv->perf.oa.test_config.sysfs_metric.attrs = dev_priv->perf.oa.test_config.attrs;
+	dev_priv->perf.test_config.sysfs_metric.name = "f1792f32-6db2-4b50-b4b2-557128f1688d";
+	dev_priv->perf.test_config.sysfs_metric.attrs = dev_priv->perf.test_config.attrs;
 
-	dev_priv->perf.oa.test_config.attrs[0] = &dev_priv->perf.oa.test_config.sysfs_metric_id.attr;
+	dev_priv->perf.test_config.attrs[0] = &dev_priv->perf.test_config.sysfs_metric_id.attr;
 
-	dev_priv->perf.oa.test_config.sysfs_metric_id.attr.name = "id";
-	dev_priv->perf.oa.test_config.sysfs_metric_id.attr.mode = 0444;
-	dev_priv->perf.oa.test_config.sysfs_metric_id.show = show_test_oa_id;
+	dev_priv->perf.test_config.sysfs_metric_id.attr.name = "id";
+	dev_priv->perf.test_config.sysfs_metric_id.attr.mode = 0444;
+	dev_priv->perf.test_config.sysfs_metric_id.show = show_test_oa_id;
 }
diff --git a/drivers/gpu/drm/i915/i915_oa_sklgt2.c b/drivers/gpu/drm/i915/i915_oa_sklgt2.c
index 7ce6ee851d43..fa463a92f5bb 100644
--- a/drivers/gpu/drm/i915/i915_oa_sklgt2.c
+++ b/drivers/gpu/drm/i915/i915_oa_sklgt2.c
@@ -64,26 +64,26 @@  show_test_oa_id(struct device *kdev, struct device_attribute *attr, char *buf)
 void
 i915_perf_load_test_config_sklgt2(struct drm_i915_private *dev_priv)
 {
-	strlcpy(dev_priv->perf.oa.test_config.uuid,
+	strlcpy(dev_priv->perf.test_config.uuid,
 		"1651949f-0ac0-4cb1-a06f-dafd74a407d1",
-		sizeof(dev_priv->perf.oa.test_config.uuid));
-	dev_priv->perf.oa.test_config.id = 1;
+		sizeof(dev_priv->perf.test_config.uuid));
+	dev_priv->perf.test_config.id = 1;
 
-	dev_priv->perf.oa.test_config.mux_regs = mux_config_test_oa;
-	dev_priv->perf.oa.test_config.mux_regs_len = ARRAY_SIZE(mux_config_test_oa);
+	dev_priv->perf.test_config.mux_regs = mux_config_test_oa;
+	dev_priv->perf.test_config.mux_regs_len = ARRAY_SIZE(mux_config_test_oa);
 
-	dev_priv->perf.oa.test_config.b_counter_regs = b_counter_config_test_oa;
-	dev_priv->perf.oa.test_config.b_counter_regs_len = ARRAY_SIZE(b_counter_config_test_oa);
+	dev_priv->perf.test_config.b_counter_regs = b_counter_config_test_oa;
+	dev_priv->perf.test_config.b_counter_regs_len = ARRAY_SIZE(b_counter_config_test_oa);
 
-	dev_priv->perf.oa.test_config.flex_regs = flex_eu_config_test_oa;
-	dev_priv->perf.oa.test_config.flex_regs_len = ARRAY_SIZE(flex_eu_config_test_oa);
+	dev_priv->perf.test_config.flex_regs = flex_eu_config_test_oa;
+	dev_priv->perf.test_config.flex_regs_len = ARRAY_SIZE(flex_eu_config_test_oa);
 
-	dev_priv->perf.oa.test_config.sysfs_metric.name = "1651949f-0ac0-4cb1-a06f-dafd74a407d1";
-	dev_priv->perf.oa.test_config.sysfs_metric.attrs = dev_priv->perf.oa.test_config.attrs;
+	dev_priv->perf.test_config.sysfs_metric.name = "1651949f-0ac0-4cb1-a06f-dafd74a407d1";
+	dev_priv->perf.test_config.sysfs_metric.attrs = dev_priv->perf.test_config.attrs;
 
-	dev_priv->perf.oa.test_config.attrs[0] = &dev_priv->perf.oa.test_config.sysfs_metric_id.attr;
+	dev_priv->perf.test_config.attrs[0] = &dev_priv->perf.test_config.sysfs_metric_id.attr;
 
-	dev_priv->perf.oa.test_config.sysfs_metric_id.attr.name = "id";
-	dev_priv->perf.oa.test_config.sysfs_metric_id.attr.mode = 0444;
-	dev_priv->perf.oa.test_config.sysfs_metric_id.show = show_test_oa_id;
+	dev_priv->perf.test_config.sysfs_metric_id.attr.name = "id";
+	dev_priv->perf.test_config.sysfs_metric_id.attr.mode = 0444;
+	dev_priv->perf.test_config.sysfs_metric_id.show = show_test_oa_id;
 }
diff --git a/drivers/gpu/drm/i915/i915_oa_sklgt3.c b/drivers/gpu/drm/i915/i915_oa_sklgt3.c
index 086ca2631e1c..9c9497d7a9d5 100644
--- a/drivers/gpu/drm/i915/i915_oa_sklgt3.c
+++ b/drivers/gpu/drm/i915/i915_oa_sklgt3.c
@@ -65,26 +65,26 @@  show_test_oa_id(struct device *kdev, struct device_attribute *attr, char *buf)
 void
 i915_perf_load_test_config_sklgt3(struct drm_i915_private *dev_priv)
 {
-	strlcpy(dev_priv->perf.oa.test_config.uuid,
+	strlcpy(dev_priv->perf.test_config.uuid,
 		"2b985803-d3c9-4629-8a4f-634bfecba0e8",
-		sizeof(dev_priv->perf.oa.test_config.uuid));
-	dev_priv->perf.oa.test_config.id = 1;
+		sizeof(dev_priv->perf.test_config.uuid));
+	dev_priv->perf.test_config.id = 1;
 
-	dev_priv->perf.oa.test_config.mux_regs = mux_config_test_oa;
-	dev_priv->perf.oa.test_config.mux_regs_len = ARRAY_SIZE(mux_config_test_oa);
+	dev_priv->perf.test_config.mux_regs = mux_config_test_oa;
+	dev_priv->perf.test_config.mux_regs_len = ARRAY_SIZE(mux_config_test_oa);
 
-	dev_priv->perf.oa.test_config.b_counter_regs = b_counter_config_test_oa;
-	dev_priv->perf.oa.test_config.b_counter_regs_len = ARRAY_SIZE(b_counter_config_test_oa);
+	dev_priv->perf.test_config.b_counter_regs = b_counter_config_test_oa;
+	dev_priv->perf.test_config.b_counter_regs_len = ARRAY_SIZE(b_counter_config_test_oa);
 
-	dev_priv->perf.oa.test_config.flex_regs = flex_eu_config_test_oa;
-	dev_priv->perf.oa.test_config.flex_regs_len = ARRAY_SIZE(flex_eu_config_test_oa);
+	dev_priv->perf.test_config.flex_regs = flex_eu_config_test_oa;
+	dev_priv->perf.test_config.flex_regs_len = ARRAY_SIZE(flex_eu_config_test_oa);
 
-	dev_priv->perf.oa.test_config.sysfs_metric.name = "2b985803-d3c9-4629-8a4f-634bfecba0e8";
-	dev_priv->perf.oa.test_config.sysfs_metric.attrs = dev_priv->perf.oa.test_config.attrs;
+	dev_priv->perf.test_config.sysfs_metric.name = "2b985803-d3c9-4629-8a4f-634bfecba0e8";
+	dev_priv->perf.test_config.sysfs_metric.attrs = dev_priv->perf.test_config.attrs;
 
-	dev_priv->perf.oa.test_config.attrs[0] = &dev_priv->perf.oa.test_config.sysfs_metric_id.attr;
+	dev_priv->perf.test_config.attrs[0] = &dev_priv->perf.test_config.sysfs_metric_id.attr;
 
-	dev_priv->perf.oa.test_config.sysfs_metric_id.attr.name = "id";
-	dev_priv->perf.oa.test_config.sysfs_metric_id.attr.mode = 0444;
-	dev_priv->perf.oa.test_config.sysfs_metric_id.show = show_test_oa_id;
+	dev_priv->perf.test_config.sysfs_metric_id.attr.name = "id";
+	dev_priv->perf.test_config.sysfs_metric_id.attr.mode = 0444;
+	dev_priv->perf.test_config.sysfs_metric_id.show = show_test_oa_id;
 }
diff --git a/drivers/gpu/drm/i915/i915_oa_sklgt4.c b/drivers/gpu/drm/i915/i915_oa_sklgt4.c
index b291a6eb8a87..65ebc6b8dd70 100644
--- a/drivers/gpu/drm/i915/i915_oa_sklgt4.c
+++ b/drivers/gpu/drm/i915/i915_oa_sklgt4.c
@@ -65,26 +65,26 @@  show_test_oa_id(struct device *kdev, struct device_attribute *attr, char *buf)
 void
 i915_perf_load_test_config_sklgt4(struct drm_i915_private *dev_priv)
 {
-	strlcpy(dev_priv->perf.oa.test_config.uuid,
+	strlcpy(dev_priv->perf.test_config.uuid,
 		"882fa433-1f4a-4a67-a962-c741888fe5f5",
-		sizeof(dev_priv->perf.oa.test_config.uuid));
-	dev_priv->perf.oa.test_config.id = 1;
+		sizeof(dev_priv->perf.test_config.uuid));
+	dev_priv->perf.test_config.id = 1;
 
-	dev_priv->perf.oa.test_config.mux_regs = mux_config_test_oa;
-	dev_priv->perf.oa.test_config.mux_regs_len = ARRAY_SIZE(mux_config_test_oa);
+	dev_priv->perf.test_config.mux_regs = mux_config_test_oa;
+	dev_priv->perf.test_config.mux_regs_len = ARRAY_SIZE(mux_config_test_oa);
 
-	dev_priv->perf.oa.test_config.b_counter_regs = b_counter_config_test_oa;
-	dev_priv->perf.oa.test_config.b_counter_regs_len = ARRAY_SIZE(b_counter_config_test_oa);
+	dev_priv->perf.test_config.b_counter_regs = b_counter_config_test_oa;
+	dev_priv->perf.test_config.b_counter_regs_len = ARRAY_SIZE(b_counter_config_test_oa);
 
-	dev_priv->perf.oa.test_config.flex_regs = flex_eu_config_test_oa;
-	dev_priv->perf.oa.test_config.flex_regs_len = ARRAY_SIZE(flex_eu_config_test_oa);
+	dev_priv->perf.test_config.flex_regs = flex_eu_config_test_oa;
+	dev_priv->perf.test_config.flex_regs_len = ARRAY_SIZE(flex_eu_config_test_oa);
 
-	dev_priv->perf.oa.test_config.sysfs_metric.name = "882fa433-1f4a-4a67-a962-c741888fe5f5";
-	dev_priv->perf.oa.test_config.sysfs_metric.attrs = dev_priv->perf.oa.test_config.attrs;
+	dev_priv->perf.test_config.sysfs_metric.name = "882fa433-1f4a-4a67-a962-c741888fe5f5";
+	dev_priv->perf.test_config.sysfs_metric.attrs = dev_priv->perf.test_config.attrs;
 
-	dev_priv->perf.oa.test_config.attrs[0] = &dev_priv->perf.oa.test_config.sysfs_metric_id.attr;
+	dev_priv->perf.test_config.attrs[0] = &dev_priv->perf.test_config.sysfs_metric_id.attr;
 
-	dev_priv->perf.oa.test_config.sysfs_metric_id.attr.name = "id";
-	dev_priv->perf.oa.test_config.sysfs_metric_id.attr.mode = 0444;
-	dev_priv->perf.oa.test_config.sysfs_metric_id.show = show_test_oa_id;
+	dev_priv->perf.test_config.sysfs_metric_id.attr.name = "id";
+	dev_priv->perf.test_config.sysfs_metric_id.attr.mode = 0444;
+	dev_priv->perf.test_config.sysfs_metric_id.show = show_test_oa_id;
 }
diff --git a/drivers/gpu/drm/i915/i915_perf.c b/drivers/gpu/drm/i915/i915_perf.c
index c4995d5a16d2..be3f68461c50 100644
--- a/drivers/gpu/drm/i915/i915_perf.c
+++ b/drivers/gpu/drm/i915/i915_perf.c
@@ -364,6 +364,8 @@  struct perf_open_properties {
 	int oa_period_exponent;
 };
 
+static enum hrtimer_restart oa_poll_check_timer_cb(struct hrtimer *hrtimer);
+
 static void free_oa_config(struct drm_i915_private *dev_priv,
 			   struct i915_oa_config *oa_config)
 {
@@ -392,8 +394,8 @@  static int get_oa_config(struct drm_i915_private *dev_priv,
 	int ret;
 
 	if (metrics_set == 1) {
-		*out_config = &dev_priv->perf.oa.test_config;
-		atomic_inc(&dev_priv->perf.oa.test_config.ref_count);
+		*out_config = &dev_priv->perf.test_config;
+		atomic_inc(&dev_priv->perf.test_config.ref_count);
 		return 0;
 	}
 
@@ -412,13 +414,16 @@  static int get_oa_config(struct drm_i915_private *dev_priv,
 	return ret;
 }
 
-static u32 gen8_oa_hw_tail_read(struct drm_i915_private *dev_priv)
+static u32 gen8_oa_hw_tail_read(struct i915_perf_stream *stream)
 {
+	struct drm_i915_private *dev_priv = stream->dev_priv;
+
 	return I915_READ(GEN8_OATAILPTR) & GEN8_OATAILPTR_MASK;
 }
 
-static u32 gen7_oa_hw_tail_read(struct drm_i915_private *dev_priv)
+static u32 gen7_oa_hw_tail_read(struct i915_perf_stream *stream)
 {
+	struct drm_i915_private *dev_priv = stream->dev_priv;
 	u32 oastatus1 = I915_READ(GEN7_OASTATUS1);
 
 	return oastatus1 & GEN7_OASTATUS1_TAIL_MASK;
@@ -426,7 +431,7 @@  static u32 gen7_oa_hw_tail_read(struct drm_i915_private *dev_priv)
 
 /**
  * oa_buffer_check_unlocked - check for data and update tail ptr state
- * @dev_priv: i915 device instance
+ * @stream: i915 stream instance
  *
  * This is either called via fops (for blocking reads in user ctx) or the poll
  * check hrtimer (atomic ctx) to check the OA buffer tail pointer and check
@@ -448,9 +453,10 @@  static u32 gen7_oa_hw_tail_read(struct drm_i915_private *dev_priv)
  *
  * Returns: %true if the OA buffer contains data, else %false
  */
-static bool oa_buffer_check_unlocked(struct drm_i915_private *dev_priv)
+static bool oa_buffer_check_unlocked(struct i915_perf_stream *stream)
 {
-	int report_size = dev_priv->perf.oa.oa_buffer.format_size;
+	struct drm_i915_private *dev_priv = stream->dev_priv;
+	int report_size = stream->oa_buffer.format_size;
 	unsigned long flags;
 	unsigned int aged_idx;
 	u32 head, hw_tail, aged_tail, aging_tail;
@@ -460,19 +466,19 @@  static bool oa_buffer_check_unlocked(struct drm_i915_private *dev_priv)
 	 * could result in an OA buffer reset which might reset the head,
 	 * tails[] and aged_tail state.
 	 */
-	spin_lock_irqsave(&dev_priv->perf.oa.oa_buffer.ptr_lock, flags);
+	spin_lock_irqsave(&stream->oa_buffer.ptr_lock, flags);
 
 	/* NB: The head we observe here might effectively be a little out of
 	 * date (between head and tails[aged_idx].offset if there is currently
 	 * a read() in progress.
 	 */
-	head = dev_priv->perf.oa.oa_buffer.head;
+	head = stream->oa_buffer.head;
 
-	aged_idx = dev_priv->perf.oa.oa_buffer.aged_tail_idx;
-	aged_tail = dev_priv->perf.oa.oa_buffer.tails[aged_idx].offset;
-	aging_tail = dev_priv->perf.oa.oa_buffer.tails[!aged_idx].offset;
+	aged_idx = stream->oa_buffer.aged_tail_idx;
+	aged_tail = stream->oa_buffer.tails[aged_idx].offset;
+	aging_tail = stream->oa_buffer.tails[!aged_idx].offset;
 
-	hw_tail = dev_priv->perf.oa.ops.oa_hw_tail_read(dev_priv);
+	hw_tail = dev_priv->perf.ops.oa_hw_tail_read(stream);
 
 	/* The tail pointer increases in 64 byte increments,
 	 * not in report_size steps...
@@ -492,16 +498,16 @@  static bool oa_buffer_check_unlocked(struct drm_i915_private *dev_priv)
 	 * available) without needing to wait for a later hrtimer callback.
 	 */
 	if (aging_tail != INVALID_TAIL_PTR &&
-	    ((now - dev_priv->perf.oa.oa_buffer.aging_timestamp) >
+	    ((now - stream->oa_buffer.aging_timestamp) >
 	     OA_TAIL_MARGIN_NSEC)) {
 
 		aged_idx ^= 1;
-		dev_priv->perf.oa.oa_buffer.aged_tail_idx = aged_idx;
+		stream->oa_buffer.aged_tail_idx = aged_idx;
 
 		aged_tail = aging_tail;
 
 		/* Mark that we need a new pointer to start aging... */
-		dev_priv->perf.oa.oa_buffer.tails[!aged_idx].offset = INVALID_TAIL_PTR;
+		stream->oa_buffer.tails[!aged_idx].offset = INVALID_TAIL_PTR;
 		aging_tail = INVALID_TAIL_PTR;
 	}
 
@@ -516,7 +522,7 @@  static bool oa_buffer_check_unlocked(struct drm_i915_private *dev_priv)
 	if (aging_tail == INVALID_TAIL_PTR &&
 	    (aged_tail == INVALID_TAIL_PTR ||
 	     OA_TAKEN(hw_tail, aged_tail) >= report_size)) {
-		struct i915_vma *vma = dev_priv->perf.oa.oa_buffer.vma;
+		struct i915_vma *vma = stream->oa_buffer.vma;
 		u32 gtt_offset = i915_ggtt_offset(vma);
 
 		/* Be paranoid and do a bounds check on the pointer read back
@@ -525,16 +531,16 @@  static bool oa_buffer_check_unlocked(struct drm_i915_private *dev_priv)
 		 */
 		if (hw_tail >= gtt_offset &&
 		    hw_tail < (gtt_offset + OA_BUFFER_SIZE)) {
-			dev_priv->perf.oa.oa_buffer.tails[!aged_idx].offset =
+			stream->oa_buffer.tails[!aged_idx].offset =
 				aging_tail = hw_tail;
-			dev_priv->perf.oa.oa_buffer.aging_timestamp = now;
+			stream->oa_buffer.aging_timestamp = now;
 		} else {
 			DRM_ERROR("Ignoring spurious out of range OA buffer tail pointer = %u\n",
 				  hw_tail);
 		}
 	}
 
-	spin_unlock_irqrestore(&dev_priv->perf.oa.oa_buffer.ptr_lock, flags);
+	spin_unlock_irqrestore(&stream->oa_buffer.ptr_lock, flags);
 
 	return aged_tail == INVALID_TAIL_PTR ?
 		false : OA_TAKEN(aged_tail, head) >= report_size;
@@ -597,8 +603,7 @@  static int append_oa_sample(struct i915_perf_stream *stream,
 			    size_t *offset,
 			    const u8 *report)
 {
-	struct drm_i915_private *dev_priv = stream->dev_priv;
-	int report_size = dev_priv->perf.oa.oa_buffer.format_size;
+	int report_size = stream->oa_buffer.format_size;
 	struct drm_i915_perf_record_header header;
 	u32 sample_flags = stream->sample_flags;
 
@@ -650,9 +655,9 @@  static int gen8_append_oa_reports(struct i915_perf_stream *stream,
 				  size_t *offset)
 {
 	struct drm_i915_private *dev_priv = stream->dev_priv;
-	int report_size = dev_priv->perf.oa.oa_buffer.format_size;
-	u8 *oa_buf_base = dev_priv->perf.oa.oa_buffer.vaddr;
-	u32 gtt_offset = i915_ggtt_offset(dev_priv->perf.oa.oa_buffer.vma);
+	int report_size = stream->oa_buffer.format_size;
+	u8 *oa_buf_base = stream->oa_buffer.vaddr;
+	u32 gtt_offset = i915_ggtt_offset(stream->oa_buffer.vma);
 	u32 mask = (OA_BUFFER_SIZE - 1);
 	size_t start_offset = *offset;
 	unsigned long flags;
@@ -664,13 +669,13 @@  static int gen8_append_oa_reports(struct i915_perf_stream *stream,
 	if (WARN_ON(!stream->enabled))
 		return -EIO;
 
-	spin_lock_irqsave(&dev_priv->perf.oa.oa_buffer.ptr_lock, flags);
+	spin_lock_irqsave(&stream->oa_buffer.ptr_lock, flags);
 
-	head = dev_priv->perf.oa.oa_buffer.head;
-	aged_tail_idx = dev_priv->perf.oa.oa_buffer.aged_tail_idx;
-	tail = dev_priv->perf.oa.oa_buffer.tails[aged_tail_idx].offset;
+	head = stream->oa_buffer.head;
+	aged_tail_idx = stream->oa_buffer.aged_tail_idx;
+	tail = stream->oa_buffer.tails[aged_tail_idx].offset;
 
-	spin_unlock_irqrestore(&dev_priv->perf.oa.oa_buffer.ptr_lock, flags);
+	spin_unlock_irqrestore(&stream->oa_buffer.ptr_lock, flags);
 
 	/*
 	 * An invalid tail pointer here means we're still waiting for the poll
@@ -734,12 +739,12 @@  static int gen8_append_oa_reports(struct i915_perf_stream *stream,
 		reason = ((report32[0] >> OAREPORT_REASON_SHIFT) &
 			  OAREPORT_REASON_MASK);
 		if (reason == 0) {
-			if (__ratelimit(&dev_priv->perf.oa.spurious_report_rs))
+			if (__ratelimit(&dev_priv->perf.spurious_report_rs))
 				DRM_NOTE("Skipping spurious, invalid OA report\n");
 			continue;
 		}
 
-		ctx_id = report32[2] & dev_priv->perf.oa.specific_ctx_id_mask;
+		ctx_id = report32[2] & stream->specific_ctx_id_mask;
 
 		/*
 		 * Squash whatever is in the CTX_ID field if it's marked as
@@ -749,7 +754,7 @@  static int gen8_append_oa_reports(struct i915_perf_stream *stream,
 		 * Note: that we don't clear the valid_ctx_bit so userspace can
 		 * understand that the ID has been squashed by the kernel.
 		 */
-		if (!(report32[0] & dev_priv->perf.oa.gen8_valid_ctx_bit))
+		if (!(report32[0] & dev_priv->perf.gen8_valid_ctx_bit))
 			ctx_id = report32[2] = INVALID_CTX_ID;
 
 		/*
@@ -783,18 +788,18 @@  static int gen8_append_oa_reports(struct i915_perf_stream *stream,
 		 * switches since it's not-uncommon for periodic samples to
 		 * identify a switch before any 'context switch' report.
 		 */
-		if (!dev_priv->perf.oa.exclusive_stream->ctx ||
-		    dev_priv->perf.oa.specific_ctx_id == ctx_id ||
-		    (dev_priv->perf.oa.oa_buffer.last_ctx_id ==
-		     dev_priv->perf.oa.specific_ctx_id) ||
+		if (!dev_priv->perf.exclusive_stream->ctx ||
+		    stream->specific_ctx_id == ctx_id ||
+		    (stream->oa_buffer.last_ctx_id ==
+		     stream->specific_ctx_id) ||
 		    reason & OAREPORT_REASON_CTX_SWITCH) {
 
 			/*
 			 * While filtering for a single context we avoid
 			 * leaking the IDs of other contexts.
 			 */
-			if (dev_priv->perf.oa.exclusive_stream->ctx &&
-			    dev_priv->perf.oa.specific_ctx_id != ctx_id) {
+			if (dev_priv->perf.exclusive_stream->ctx &&
+			    stream->specific_ctx_id != ctx_id) {
 				report32[2] = INVALID_CTX_ID;
 			}
 
@@ -803,7 +808,7 @@  static int gen8_append_oa_reports(struct i915_perf_stream *stream,
 			if (ret)
 				break;
 
-			dev_priv->perf.oa.oa_buffer.last_ctx_id = ctx_id;
+			stream->oa_buffer.last_ctx_id = ctx_id;
 		}
 
 		/*
@@ -817,7 +822,7 @@  static int gen8_append_oa_reports(struct i915_perf_stream *stream,
 	}
 
 	if (start_offset != *offset) {
-		spin_lock_irqsave(&dev_priv->perf.oa.oa_buffer.ptr_lock, flags);
+		spin_lock_irqsave(&stream->oa_buffer.ptr_lock, flags);
 
 		/*
 		 * We removed the gtt_offset for the copy loop above, indexing
@@ -826,9 +831,9 @@  static int gen8_append_oa_reports(struct i915_perf_stream *stream,
 		head += gtt_offset;
 
 		I915_WRITE(GEN8_OAHEADPTR, head & GEN8_OAHEADPTR_MASK);
-		dev_priv->perf.oa.oa_buffer.head = head;
+		stream->oa_buffer.head = head;
 
-		spin_unlock_irqrestore(&dev_priv->perf.oa.oa_buffer.ptr_lock, flags);
+		spin_unlock_irqrestore(&stream->oa_buffer.ptr_lock, flags);
 	}
 
 	return ret;
@@ -863,7 +868,7 @@  static int gen8_oa_read(struct i915_perf_stream *stream,
 	u32 oastatus;
 	int ret;
 
-	if (WARN_ON(!dev_priv->perf.oa.oa_buffer.vaddr))
+	if (WARN_ON(!stream->oa_buffer.vaddr))
 		return -EIO;
 
 	oastatus = I915_READ(GEN8_OASTATUS);
@@ -889,10 +894,10 @@  static int gen8_oa_read(struct i915_perf_stream *stream,
 			return ret;
 
 		DRM_DEBUG("OA buffer overflow (exponent = %d): force restart\n",
-			  dev_priv->perf.oa.period_exponent);
+			  stream->period_exponent);
 
-		dev_priv->perf.oa.ops.oa_disable(stream);
-		dev_priv->perf.oa.ops.oa_enable(stream);
+		dev_priv->perf.ops.oa_disable(stream);
+		dev_priv->perf.ops.oa_enable(stream);
 
 		/*
 		 * Note: .oa_enable() is expected to re-init the oabuffer and
@@ -939,9 +944,9 @@  static int gen7_append_oa_reports(struct i915_perf_stream *stream,
 				  size_t *offset)
 {
 	struct drm_i915_private *dev_priv = stream->dev_priv;
-	int report_size = dev_priv->perf.oa.oa_buffer.format_size;
-	u8 *oa_buf_base = dev_priv->perf.oa.oa_buffer.vaddr;
-	u32 gtt_offset = i915_ggtt_offset(dev_priv->perf.oa.oa_buffer.vma);
+	int report_size = stream->oa_buffer.format_size;
+	u8 *oa_buf_base = stream->oa_buffer.vaddr;
+	u32 gtt_offset = i915_ggtt_offset(stream->oa_buffer.vma);
 	u32 mask = (OA_BUFFER_SIZE - 1);
 	size_t start_offset = *offset;
 	unsigned long flags;
@@ -953,13 +958,13 @@  static int gen7_append_oa_reports(struct i915_perf_stream *stream,
 	if (WARN_ON(!stream->enabled))
 		return -EIO;
 
-	spin_lock_irqsave(&dev_priv->perf.oa.oa_buffer.ptr_lock, flags);
+	spin_lock_irqsave(&stream->oa_buffer.ptr_lock, flags);
 
-	head = dev_priv->perf.oa.oa_buffer.head;
-	aged_tail_idx = dev_priv->perf.oa.oa_buffer.aged_tail_idx;
-	tail = dev_priv->perf.oa.oa_buffer.tails[aged_tail_idx].offset;
+	head = stream->oa_buffer.head;
+	aged_tail_idx = stream->oa_buffer.aged_tail_idx;
+	tail = stream->oa_buffer.tails[aged_tail_idx].offset;
 
-	spin_unlock_irqrestore(&dev_priv->perf.oa.oa_buffer.ptr_lock, flags);
+	spin_unlock_irqrestore(&stream->oa_buffer.ptr_lock, flags);
 
 	/* An invalid tail pointer here means we're still waiting for the poll
 	 * hrtimer callback to give us a pointer
@@ -1012,7 +1017,7 @@  static int gen7_append_oa_reports(struct i915_perf_stream *stream,
 		 * copying it to userspace...
 		 */
 		if (report32[0] == 0) {
-			if (__ratelimit(&dev_priv->perf.oa.spurious_report_rs))
+			if (__ratelimit(&dev_priv->perf.spurious_report_rs))
 				DRM_NOTE("Skipping spurious, invalid OA report\n");
 			continue;
 		}
@@ -1031,7 +1036,7 @@  static int gen7_append_oa_reports(struct i915_perf_stream *stream,
 	}
 
 	if (start_offset != *offset) {
-		spin_lock_irqsave(&dev_priv->perf.oa.oa_buffer.ptr_lock, flags);
+		spin_lock_irqsave(&stream->oa_buffer.ptr_lock, flags);
 
 		/* We removed the gtt_offset for the copy loop above, indexing
 		 * relative to oa_buf_base so put back here...
@@ -1041,9 +1046,9 @@  static int gen7_append_oa_reports(struct i915_perf_stream *stream,
 		I915_WRITE(GEN7_OASTATUS2,
 			   ((head & GEN7_OASTATUS2_HEAD_MASK) |
 			    GEN7_OASTATUS2_MEM_SELECT_GGTT));
-		dev_priv->perf.oa.oa_buffer.head = head;
+		stream->oa_buffer.head = head;
 
-		spin_unlock_irqrestore(&dev_priv->perf.oa.oa_buffer.ptr_lock, flags);
+		spin_unlock_irqrestore(&stream->oa_buffer.ptr_lock, flags);
 	}
 
 	return ret;
@@ -1074,7 +1079,7 @@  static int gen7_oa_read(struct i915_perf_stream *stream,
 	u32 oastatus1;
 	int ret;
 
-	if (WARN_ON(!dev_priv->perf.oa.oa_buffer.vaddr))
+	if (WARN_ON(!stream->oa_buffer.vaddr))
 		return -EIO;
 
 	oastatus1 = I915_READ(GEN7_OASTATUS1);
@@ -1084,7 +1089,7 @@  static int gen7_oa_read(struct i915_perf_stream *stream,
 	 * may be updated asynchronously) so we ignore status bits
 	 * that have already been reported to userspace.
 	 */
-	oastatus1 &= ~dev_priv->perf.oa.gen7_latched_oastatus1;
+	oastatus1 &= ~dev_priv->perf.gen7_latched_oastatus1;
 
 	/* We treat OABUFFER_OVERFLOW as a significant error:
 	 *
@@ -1113,10 +1118,10 @@  static int gen7_oa_read(struct i915_perf_stream *stream,
 			return ret;
 
 		DRM_DEBUG("OA buffer overflow (exponent = %d): force restart\n",
-			  dev_priv->perf.oa.period_exponent);
+			  stream->period_exponent);
 
-		dev_priv->perf.oa.ops.oa_disable(stream);
-		dev_priv->perf.oa.ops.oa_enable(stream);
+		dev_priv->perf.ops.oa_disable(stream);
+		dev_priv->perf.ops.oa_enable(stream);
 
 		oastatus1 = I915_READ(GEN7_OASTATUS1);
 	}
@@ -1126,7 +1131,7 @@  static int gen7_oa_read(struct i915_perf_stream *stream,
 				       DRM_I915_PERF_RECORD_OA_REPORT_LOST);
 		if (ret)
 			return ret;
-		dev_priv->perf.oa.gen7_latched_oastatus1 |=
+		dev_priv->perf.gen7_latched_oastatus1 |=
 			GEN7_OASTATUS1_REPORT_LOST;
 	}
 
@@ -1149,14 +1154,12 @@  static int gen7_oa_read(struct i915_perf_stream *stream,
  */
 static int i915_oa_wait_unlocked(struct i915_perf_stream *stream)
 {
-	struct drm_i915_private *dev_priv = stream->dev_priv;
-
 	/* We would wait indefinitely if periodic sampling is not enabled */
-	if (!dev_priv->perf.oa.periodic)
+	if (!stream->periodic)
 		return -EIO;
 
-	return wait_event_interruptible(dev_priv->perf.oa.poll_wq,
-					oa_buffer_check_unlocked(dev_priv));
+	return wait_event_interruptible(stream->poll_wq,
+					oa_buffer_check_unlocked(stream));
 }
 
 /**
@@ -1173,9 +1176,7 @@  static void i915_oa_poll_wait(struct i915_perf_stream *stream,
 			      struct file *file,
 			      poll_table *wait)
 {
-	struct drm_i915_private *dev_priv = stream->dev_priv;
-
-	poll_wait(file, &dev_priv->perf.oa.poll_wq, wait);
+	poll_wait(file, &stream->poll_wq, wait);
 }
 
 /**
@@ -1197,13 +1198,14 @@  static int i915_oa_read(struct i915_perf_stream *stream,
 {
 	struct drm_i915_private *dev_priv = stream->dev_priv;
 
-	return dev_priv->perf.oa.ops.read(stream, buf, count, offset);
+	return dev_priv->perf.ops.read(stream, buf, count, offset);
 }
 
-static struct intel_context *oa_pin_context(struct drm_i915_private *i915,
-					    struct i915_gem_context *ctx)
+static struct intel_context *oa_pin_context(struct i915_perf_stream *stream)
 {
 	struct i915_gem_engines_iter it;
+	struct drm_i915_private *i915 = stream->dev_priv;
+	struct i915_gem_context *ctx = stream->ctx;
 	struct intel_context *ce;
 	int err;
 
@@ -1221,7 +1223,7 @@  static struct intel_context *oa_pin_context(struct drm_i915_private *i915,
 		 */
 		err = intel_context_pin(ce);
 		if (err == 0) {
-			i915->perf.oa.pinned_ctx = ce;
+			stream->pinned_ctx = ce;
 			break;
 		}
 	}
@@ -1231,7 +1233,7 @@  static struct intel_context *oa_pin_context(struct drm_i915_private *i915,
 	if (err)
 		return ERR_PTR(err);
 
-	return i915->perf.oa.pinned_ctx;
+	return stream->pinned_ctx;
 }
 
 /**
@@ -1249,7 +1251,7 @@  static int oa_get_render_ctx_id(struct i915_perf_stream *stream)
 	struct drm_i915_private *i915 = stream->dev_priv;
 	struct intel_context *ce;
 
-	ce = oa_pin_context(i915, stream->ctx);
+	ce = oa_pin_context(stream);
 	if (IS_ERR(ce))
 		return PTR_ERR(ce);
 
@@ -1259,8 +1261,8 @@  static int oa_get_render_ctx_id(struct i915_perf_stream *stream)
 		 * On Haswell we don't do any post processing of the reports
 		 * and don't need to use the mask.
 		 */
-		i915->perf.oa.specific_ctx_id = i915_ggtt_offset(ce->state);
-		i915->perf.oa.specific_ctx_id_mask = 0;
+		stream->specific_ctx_id = i915_ggtt_offset(ce->state);
+		stream->specific_ctx_id_mask = 0;
 		break;
 	}
 
@@ -1278,33 +1280,36 @@  static int oa_get_render_ctx_id(struct i915_perf_stream *stream)
 			 * dropped by GuC. They won't be part of the context
 			 * ID in the OA reports, so squash those lower bits.
 			 */
-			i915->perf.oa.specific_ctx_id =
+			stream->specific_ctx_id =
 				lower_32_bits(ce->lrc_desc) >> 12;
 
 			/*
 			 * GuC uses the top bit to signal proxy submission, so
 			 * ignore that bit.
 			 */
-			i915->perf.oa.specific_ctx_id_mask =
+			stream->specific_ctx_id_mask =
 				(1U << (GEN8_CTX_ID_WIDTH - 1)) - 1;
 		} else {
-			i915->perf.oa.specific_ctx_id_mask =
+			stream->specific_ctx_id_mask =
 				(1U << GEN8_CTX_ID_WIDTH) - 1;
-			i915->perf.oa.specific_ctx_id =
+			stream->specific_ctx_id =
 				upper_32_bits(ce->lrc_desc);
-			i915->perf.oa.specific_ctx_id &=
-				i915->perf.oa.specific_ctx_id_mask;
+			stream->specific_ctx_id &=
+				stream->specific_ctx_id_mask;
 		}
 		break;
 
 	case 11: {
-		i915->perf.oa.specific_ctx_id_mask =
-			((1U << GEN11_SW_CTX_ID_WIDTH) - 1) << (GEN11_SW_CTX_ID_SHIFT - 32) |
-			((1U << GEN11_ENGINE_INSTANCE_WIDTH) - 1) << (GEN11_ENGINE_INSTANCE_SHIFT - 32) |
-			((1 << GEN11_ENGINE_CLASS_WIDTH) - 1) << (GEN11_ENGINE_CLASS_SHIFT - 32);
-		i915->perf.oa.specific_ctx_id = upper_32_bits(ce->lrc_desc);
-		i915->perf.oa.specific_ctx_id &=
-			i915->perf.oa.specific_ctx_id_mask;
+		stream->specific_ctx_id_mask =
+			((1U << GEN11_SW_CTX_ID_WIDTH) - 1)
+				<< (GEN11_SW_CTX_ID_SHIFT - 32) |
+			((1U << GEN11_ENGINE_INSTANCE_WIDTH) - 1)
+				<< (GEN11_ENGINE_INSTANCE_SHIFT - 32) |
+			((1 << GEN11_ENGINE_CLASS_WIDTH) - 1)
+				<< (GEN11_ENGINE_CLASS_SHIFT - 32);
+		stream->specific_ctx_id = upper_32_bits(ce->lrc_desc);
+		stream->specific_ctx_id &=
+			stream->specific_ctx_id_mask;
 		break;
 	}
 
@@ -1313,8 +1318,8 @@  static int oa_get_render_ctx_id(struct i915_perf_stream *stream)
 	}
 
 	DRM_DEBUG_DRIVER("filtering on ctx_id=0x%x ctx_id_mask=0x%x\n",
-			 i915->perf.oa.specific_ctx_id,
-			 i915->perf.oa.specific_ctx_id_mask);
+			 stream->specific_ctx_id,
+			 stream->specific_ctx_id_mask);
 
 	return 0;
 }
@@ -1331,10 +1336,10 @@  static void oa_put_render_ctx_id(struct i915_perf_stream *stream)
 	struct drm_i915_private *dev_priv = stream->dev_priv;
 	struct intel_context *ce;
 
-	dev_priv->perf.oa.specific_ctx_id = INVALID_CTX_ID;
-	dev_priv->perf.oa.specific_ctx_id_mask = 0;
+	stream->specific_ctx_id = INVALID_CTX_ID;
+	stream->specific_ctx_id_mask = 0;
 
-	ce = fetch_and_zero(&dev_priv->perf.oa.pinned_ctx);
+	ce = fetch_and_zero(&stream->pinned_ctx);
 	if (ce) {
 		mutex_lock(&dev_priv->drm.struct_mutex);
 		intel_context_unpin(ce);
@@ -1343,34 +1348,34 @@  static void oa_put_render_ctx_id(struct i915_perf_stream *stream)
 }
 
 static void
-free_oa_buffer(struct drm_i915_private *i915)
+free_oa_buffer(struct i915_perf_stream *stream)
 {
-	mutex_lock(&i915->drm.struct_mutex);
+	struct drm_i915_private *i915 = stream->dev_priv;
 
-	i915_vma_unpin_and_release(&i915->perf.oa.oa_buffer.vma,
+	mutex_lock(&i915->drm.struct_mutex);
+	i915_vma_unpin_and_release(&stream->oa_buffer.vma,
 				   I915_VMA_RELEASE_MAP);
-
 	mutex_unlock(&i915->drm.struct_mutex);
 
-	i915->perf.oa.oa_buffer.vaddr = NULL;
+	stream->oa_buffer.vaddr = NULL;
 }
 
 static void i915_oa_stream_destroy(struct i915_perf_stream *stream)
 {
 	struct drm_i915_private *dev_priv = stream->dev_priv;
 
-	BUG_ON(stream != dev_priv->perf.oa.exclusive_stream);
+	BUG_ON(stream != dev_priv->perf.exclusive_stream);
 
 	/*
 	 * Unset exclusive_stream first, it will be checked while disabling
 	 * the metric set on gen8+.
 	 */
 	mutex_lock(&dev_priv->drm.struct_mutex);
-	dev_priv->perf.oa.exclusive_stream = NULL;
-	dev_priv->perf.oa.ops.disable_metric_set(dev_priv);
+	dev_priv->perf.exclusive_stream = NULL;
+	dev_priv->perf.ops.disable_metric_set(stream);
 	mutex_unlock(&dev_priv->drm.struct_mutex);
 
-	free_oa_buffer(dev_priv);
+	free_oa_buffer(stream);
 
 	intel_uncore_forcewake_put(&dev_priv->uncore, FORCEWAKE_ALL);
 	intel_runtime_pm_put(dev_priv, stream->wakeref);
@@ -1380,41 +1385,42 @@  static void i915_oa_stream_destroy(struct i915_perf_stream *stream)
 
 	put_oa_config(dev_priv, stream->oa_config);
 
-	if (dev_priv->perf.oa.spurious_report_rs.missed) {
+	if (dev_priv->perf.spurious_report_rs.missed) {
 		DRM_NOTE("%d spurious OA report notices suppressed due to ratelimiting\n",
-			 dev_priv->perf.oa.spurious_report_rs.missed);
+			 dev_priv->perf.spurious_report_rs.missed);
 	}
 }
 
-static void gen7_init_oa_buffer(struct drm_i915_private *dev_priv)
+static void gen7_init_oa_buffer(struct i915_perf_stream *stream)
 {
-	u32 gtt_offset = i915_ggtt_offset(dev_priv->perf.oa.oa_buffer.vma);
+	struct drm_i915_private *dev_priv = stream->dev_priv;
+	u32 gtt_offset = i915_ggtt_offset(stream->oa_buffer.vma);
 	unsigned long flags;
 
-	spin_lock_irqsave(&dev_priv->perf.oa.oa_buffer.ptr_lock, flags);
+	spin_lock_irqsave(&stream->oa_buffer.ptr_lock, flags);
 
 	/* Pre-DevBDW: OABUFFER must be set with counters off,
 	 * before OASTATUS1, but after OASTATUS2
 	 */
 	I915_WRITE(GEN7_OASTATUS2,
 		   gtt_offset | GEN7_OASTATUS2_MEM_SELECT_GGTT); /* head */
-	dev_priv->perf.oa.oa_buffer.head = gtt_offset;
+	stream->oa_buffer.head = gtt_offset;
 
 	I915_WRITE(GEN7_OABUFFER, gtt_offset);
 
 	I915_WRITE(GEN7_OASTATUS1, gtt_offset | OABUFFER_SIZE_16M); /* tail */
 
 	/* Mark that we need updated tail pointers to read from... */
-	dev_priv->perf.oa.oa_buffer.tails[0].offset = INVALID_TAIL_PTR;
-	dev_priv->perf.oa.oa_buffer.tails[1].offset = INVALID_TAIL_PTR;
+	stream->oa_buffer.tails[0].offset = INVALID_TAIL_PTR;
+	stream->oa_buffer.tails[1].offset = INVALID_TAIL_PTR;
 
-	spin_unlock_irqrestore(&dev_priv->perf.oa.oa_buffer.ptr_lock, flags);
+	spin_unlock_irqrestore(&stream->oa_buffer.ptr_lock, flags);
 
 	/* On Haswell we have to track which OASTATUS1 flags we've
 	 * already seen since they can't be cleared while periodic
 	 * sampling is enabled.
 	 */
-	dev_priv->perf.oa.gen7_latched_oastatus1 = 0;
+	dev_priv->perf.gen7_latched_oastatus1 = 0;
 
 	/* NB: although the OA buffer will initially be allocated
 	 * zeroed via shmfs (and so this memset is redundant when
@@ -1427,24 +1433,25 @@  static void gen7_init_oa_buffer(struct drm_i915_private *dev_priv)
 	 * the assumption that new reports are being written to zeroed
 	 * memory...
 	 */
-	memset(dev_priv->perf.oa.oa_buffer.vaddr, 0, OA_BUFFER_SIZE);
+	memset(stream->oa_buffer.vaddr, 0, OA_BUFFER_SIZE);
 
 	/* Maybe make ->pollin per-stream state if we support multiple
 	 * concurrent streams in the future.
 	 */
-	dev_priv->perf.oa.pollin = false;
+	stream->pollin = false;
 }
 
-static void gen8_init_oa_buffer(struct drm_i915_private *dev_priv)
+static void gen8_init_oa_buffer(struct i915_perf_stream *stream)
 {
-	u32 gtt_offset = i915_ggtt_offset(dev_priv->perf.oa.oa_buffer.vma);
+	struct drm_i915_private *dev_priv = stream->dev_priv;
+	u32 gtt_offset = i915_ggtt_offset(stream->oa_buffer.vma);
 	unsigned long flags;
 
-	spin_lock_irqsave(&dev_priv->perf.oa.oa_buffer.ptr_lock, flags);
+	spin_lock_irqsave(&stream->oa_buffer.ptr_lock, flags);
 
 	I915_WRITE(GEN8_OASTATUS, 0);
 	I915_WRITE(GEN8_OAHEADPTR, gtt_offset);
-	dev_priv->perf.oa.oa_buffer.head = gtt_offset;
+	stream->oa_buffer.head = gtt_offset;
 
 	I915_WRITE(GEN8_OABUFFER_UDW, 0);
 
@@ -1461,17 +1468,17 @@  static void gen8_init_oa_buffer(struct drm_i915_private *dev_priv)
 	I915_WRITE(GEN8_OATAILPTR, gtt_offset & GEN8_OATAILPTR_MASK);
 
 	/* Mark that we need updated tail pointers to read from... */
-	dev_priv->perf.oa.oa_buffer.tails[0].offset = INVALID_TAIL_PTR;
-	dev_priv->perf.oa.oa_buffer.tails[1].offset = INVALID_TAIL_PTR;
+	stream->oa_buffer.tails[0].offset = INVALID_TAIL_PTR;
+	stream->oa_buffer.tails[1].offset = INVALID_TAIL_PTR;
 
 	/*
 	 * Reset state used to recognise context switches, affecting which
 	 * reports we will forward to userspace while filtering for a single
 	 * context.
 	 */
-	dev_priv->perf.oa.oa_buffer.last_ctx_id = INVALID_CTX_ID;
+	stream->oa_buffer.last_ctx_id = INVALID_CTX_ID;
 
-	spin_unlock_irqrestore(&dev_priv->perf.oa.oa_buffer.ptr_lock, flags);
+	spin_unlock_irqrestore(&stream->oa_buffer.ptr_lock, flags);
 
 	/*
 	 * NB: although the OA buffer will initially be allocated
@@ -1485,22 +1492,23 @@  static void gen8_init_oa_buffer(struct drm_i915_private *dev_priv)
 	 * the assumption that new reports are being written to zeroed
 	 * memory...
 	 */
-	memset(dev_priv->perf.oa.oa_buffer.vaddr, 0, OA_BUFFER_SIZE);
+	memset(stream->oa_buffer.vaddr, 0, OA_BUFFER_SIZE);
 
 	/*
 	 * Maybe make ->pollin per-stream state if we support multiple
 	 * concurrent streams in the future.
 	 */
-	dev_priv->perf.oa.pollin = false;
+	stream->pollin = false;
 }
 
-static int alloc_oa_buffer(struct drm_i915_private *dev_priv)
+static int alloc_oa_buffer(struct i915_perf_stream *stream)
 {
 	struct drm_i915_gem_object *bo;
+	struct drm_i915_private *dev_priv = stream->dev_priv;
 	struct i915_vma *vma;
 	int ret;
 
-	if (WARN_ON(dev_priv->perf.oa.oa_buffer.vma))
+	if (WARN_ON(stream->oa_buffer.vma))
 		return -ENODEV;
 
 	ret = i915_mutex_lock_interruptible(&dev_priv->drm);
@@ -1525,18 +1533,18 @@  static int alloc_oa_buffer(struct drm_i915_private *dev_priv)
 		ret = PTR_ERR(vma);
 		goto err_unref;
 	}
-	dev_priv->perf.oa.oa_buffer.vma = vma;
+	stream->oa_buffer.vma = vma;
 
-	dev_priv->perf.oa.oa_buffer.vaddr =
+	stream->oa_buffer.vaddr =
 		i915_gem_object_pin_map(bo, I915_MAP_WB);
-	if (IS_ERR(dev_priv->perf.oa.oa_buffer.vaddr)) {
-		ret = PTR_ERR(dev_priv->perf.oa.oa_buffer.vaddr);
+	if (IS_ERR(stream->oa_buffer.vaddr)) {
+		ret = PTR_ERR(stream->oa_buffer.vaddr);
 		goto err_unpin;
 	}
 
 	DRM_DEBUG_DRIVER("OA Buffer initialized, gtt offset = 0x%x, vaddr = %p\n",
-			 i915_ggtt_offset(dev_priv->perf.oa.oa_buffer.vma),
-			 dev_priv->perf.oa.oa_buffer.vaddr);
+			 i915_ggtt_offset(stream->oa_buffer.vma),
+			 stream->oa_buffer.vaddr);
 
 	goto unlock;
 
@@ -1546,8 +1554,8 @@  static int alloc_oa_buffer(struct drm_i915_private *dev_priv)
 err_unref:
 	i915_gem_object_put(bo);
 
-	dev_priv->perf.oa.oa_buffer.vaddr = NULL;
-	dev_priv->perf.oa.oa_buffer.vma = NULL;
+	stream->oa_buffer.vaddr = NULL;
+	stream->oa_buffer.vma = NULL;
 
 unlock:
 	mutex_unlock(&dev_priv->drm.struct_mutex);
@@ -1617,8 +1625,10 @@  static int hsw_enable_metric_set(struct i915_perf_stream *stream)
 	return 0;
 }
 
-static void hsw_disable_metric_set(struct drm_i915_private *dev_priv)
+static void hsw_disable_metric_set(struct i915_perf_stream *stream)
 {
+	struct drm_i915_private *dev_priv = stream->dev_priv;
+
 	I915_WRITE(GEN6_UCGCTL1, (I915_READ(GEN6_UCGCTL1) &
 				  ~GEN6_CSUNIT_CLOCK_GATE_DISABLE));
 	I915_WRITE(GEN7_MISCCPCTL, (I915_READ(GEN7_MISCCPCTL) |
@@ -1636,13 +1646,14 @@  static void hsw_disable_metric_set(struct drm_i915_private *dev_priv)
  * in the case that the OA unit has been disabled.
  */
 static void
-gen8_update_reg_state_unlocked(struct intel_context *ce,
+gen8_update_reg_state_unlocked(struct i915_perf_stream *stream,
+			       struct intel_context *ce,
 			       u32 *reg_state,
 			       const struct i915_oa_config *oa_config)
 {
 	struct drm_i915_private *i915 = ce->gem_context->i915;
-	u32 ctx_oactxctrl = i915->perf.oa.ctx_oactxctrl_offset;
-	u32 ctx_flexeu0 = i915->perf.oa.ctx_flexeu0_offset;
+	u32 ctx_oactxctrl = i915->perf.ctx_oactxctrl_offset;
+	u32 ctx_flexeu0 = i915->perf.ctx_flexeu0_offset;
 	/* The MMIO offsets for Flex EU registers aren't contiguous */
 	i915_reg_t flex_regs[] = {
 		EU_PERF_CNTL0,
@@ -1656,8 +1667,8 @@  gen8_update_reg_state_unlocked(struct intel_context *ce,
 	int i;
 
 	CTX_REG(reg_state, ctx_oactxctrl, GEN8_OACTXCONTROL,
-		(i915->perf.oa.period_exponent << GEN8_OA_TIMER_PERIOD_SHIFT) |
-		(i915->perf.oa.periodic ? GEN8_OA_TIMER_ENABLE : 0) |
+		(stream->period_exponent << GEN8_OA_TIMER_PERIOD_SHIFT) |
+		(stream->periodic ? GEN8_OA_TIMER_ENABLE : 0) |
 		GEN8_OA_COUNTER_RESUME);
 
 	for (i = 0; i < ARRAY_SIZE(flex_regs); i++) {
@@ -1673,10 +1684,12 @@  gen8_update_reg_state_unlocked(struct intel_context *ce,
 
 		if (oa_config) {
 			u32 j;
+			struct i915_oa_reg reg;
 
 			for (j = 0; j < oa_config->flex_regs_len; j++) {
-				if (i915_mmio_reg_offset(oa_config->flex_regs[j].addr) == mmio) {
-					value = oa_config->flex_regs[j].value;
+				reg = oa_config->flex_regs[j];
+				if (i915_mmio_reg_offset(reg.addr) == mmio) {
+					value = reg.value;
 					break;
 				}
 			}
@@ -1714,9 +1727,10 @@  gen8_update_reg_state_unlocked(struct intel_context *ce,
  *
  * Note: it's only the RCS/Render context that has any OA state.
  */
-static int gen8_configure_all_contexts(struct drm_i915_private *dev_priv,
+static int gen8_configure_all_contexts(struct i915_perf_stream *stream,
 				       const struct i915_oa_config *oa_config)
 {
+	struct drm_i915_private *dev_priv = stream->dev_priv;
 	unsigned int map_type = i915_coherent_map_type(dev_priv);
 	struct i915_gem_context *ctx;
 	struct i915_request *rq;
@@ -1770,7 +1784,7 @@  static int gen8_configure_all_contexts(struct drm_i915_private *dev_priv,
 			ce->state->obj->mm.dirty = true;
 			regs += LRC_STATE_PN * PAGE_SIZE / sizeof(*regs);
 
-			gen8_update_reg_state_unlocked(ce, regs, oa_config);
+			gen8_update_reg_state_unlocked(stream, ce, regs, oa_config);
 
 			i915_gem_object_unpin_map(ce->state->obj);
 		}
@@ -1821,8 +1835,9 @@  static int gen8_enable_metric_set(struct i915_perf_stream *stream)
 	 */
 	if (IS_GEN_RANGE(dev_priv, 9, 11)) {
 		I915_WRITE(GEN8_OA_DEBUG,
-			   _MASKED_BIT_ENABLE(GEN9_OA_DEBUG_DISABLE_CLK_RATIO_REPORTS |
-					      GEN9_OA_DEBUG_INCLUDE_CLK_RATIO));
+			   _MASKED_BIT_ENABLE(
+				   GEN9_OA_DEBUG_DISABLE_CLK_RATIO_REPORTS |
+				   GEN9_OA_DEBUG_INCLUDE_CLK_RATIO));
 	}
 
 	/*
@@ -1830,7 +1845,7 @@  static int gen8_enable_metric_set(struct i915_perf_stream *stream)
 	 * to make sure all slices/subslices are ON before writing to NOA
 	 * registers.
 	 */
-	ret = gen8_configure_all_contexts(dev_priv, oa_config);
+	ret = gen8_configure_all_contexts(stream, oa_config);
 	if (ret)
 		return ret;
 
@@ -1842,19 +1857,23 @@  static int gen8_enable_metric_set(struct i915_perf_stream *stream)
 	return 0;
 }
 
-static void gen8_disable_metric_set(struct drm_i915_private *dev_priv)
+static void gen8_disable_metric_set(struct i915_perf_stream *stream)
 {
+	struct drm_i915_private *dev_priv = stream->dev_priv;
+
 	/* Reset all contexts' slices/subslices configurations. */
-	gen8_configure_all_contexts(dev_priv, NULL);
+	gen8_configure_all_contexts(stream, NULL);
 
 	I915_WRITE(GDT_CHICKEN_BITS, (I915_READ(GDT_CHICKEN_BITS) &
 				      ~GT_NOA_ENABLE));
 }
 
-static void gen10_disable_metric_set(struct drm_i915_private *dev_priv)
+static void gen10_disable_metric_set(struct i915_perf_stream *stream)
 {
+	struct drm_i915_private *dev_priv = stream->dev_priv;
+
 	/* Reset all contexts' slices/subslices configurations. */
-	gen8_configure_all_contexts(dev_priv, NULL);
+	gen8_configure_all_contexts(stream, NULL);
 
 	/* Make sure we disable noa to save power. */
 	I915_WRITE(RPM_CONFIG1,
@@ -1865,10 +1884,10 @@  static void gen7_oa_enable(struct i915_perf_stream *stream)
 {
 	struct drm_i915_private *dev_priv = stream->dev_priv;
 	struct i915_gem_context *ctx = stream->ctx;
-	u32 ctx_id = dev_priv->perf.oa.specific_ctx_id;
-	bool periodic = dev_priv->perf.oa.periodic;
-	u32 period_exponent = dev_priv->perf.oa.period_exponent;
-	u32 report_format = dev_priv->perf.oa.oa_buffer.format;
+	u32 ctx_id = stream->specific_ctx_id;
+	bool periodic = stream->periodic;
+	u32 period_exponent = stream->period_exponent;
+	u32 report_format = stream->oa_buffer.format;
 
 	/*
 	 * Reset buf pointers so we don't forward reports from before now.
@@ -1879,7 +1898,7 @@  static void gen7_oa_enable(struct i915_perf_stream *stream)
 	 * on the assumption that certain fields are written to zeroed
 	 * memory which this helps maintains.
 	 */
-	gen7_init_oa_buffer(dev_priv);
+	gen7_init_oa_buffer(stream);
 
 	I915_WRITE(GEN7_OACONTROL,
 		   (ctx_id & GEN7_OACONTROL_CTX_MASK) |
@@ -1894,7 +1913,7 @@  static void gen7_oa_enable(struct i915_perf_stream *stream)
 static void gen8_oa_enable(struct i915_perf_stream *stream)
 {
 	struct drm_i915_private *dev_priv = stream->dev_priv;
-	u32 report_format = dev_priv->perf.oa.oa_buffer.format;
+	u32 report_format = stream->oa_buffer.format;
 
 	/*
 	 * Reset buf pointers so we don't forward reports from before now.
@@ -1905,7 +1924,7 @@  static void gen8_oa_enable(struct i915_perf_stream *stream)
 	 * on the assumption that certain fields are written to zeroed
 	 * memory which this helps maintains.
 	 */
-	gen8_init_oa_buffer(dev_priv);
+	gen8_init_oa_buffer(stream);
 
 	/*
 	 * Note: we don't rely on the hardware to perform single context
@@ -1930,10 +1949,10 @@  static void i915_oa_stream_enable(struct i915_perf_stream *stream)
 {
 	struct drm_i915_private *dev_priv = stream->dev_priv;
 
-	dev_priv->perf.oa.ops.oa_enable(stream);
+	dev_priv->perf.ops.oa_enable(stream);
 
-	if (dev_priv->perf.oa.periodic)
-		hrtimer_start(&dev_priv->perf.oa.poll_check_timer,
+	if (stream->periodic)
+		hrtimer_start(&stream->poll_check_timer,
 			      ns_to_ktime(POLL_PERIOD),
 			      HRTIMER_MODE_REL_PINNED);
 }
@@ -1972,10 +1991,10 @@  static void i915_oa_stream_disable(struct i915_perf_stream *stream)
 {
 	struct drm_i915_private *dev_priv = stream->dev_priv;
 
-	dev_priv->perf.oa.ops.oa_disable(stream);
+	dev_priv->perf.ops.oa_disable(stream);
 
-	if (dev_priv->perf.oa.periodic)
-		hrtimer_cancel(&dev_priv->perf.oa.poll_check_timer);
+	if (stream->periodic)
+		hrtimer_cancel(&stream->poll_check_timer);
 }
 
 static const struct i915_perf_stream_ops i915_oa_stream_ops = {
@@ -2027,7 +2046,7 @@  static int i915_oa_stream_init(struct i915_perf_stream *stream,
 		return -EINVAL;
 	}
 
-	if (!dev_priv->perf.oa.ops.enable_metric_set) {
+	if (!dev_priv->perf.ops.enable_metric_set) {
 		DRM_DEBUG("OA unit not supported\n");
 		return -ENODEV;
 	}
@@ -2036,7 +2055,7 @@  static int i915_oa_stream_init(struct i915_perf_stream *stream,
 	 * counter reports and marshal to the appropriate client
 	 * we currently only allow exclusive access
 	 */
-	if (dev_priv->perf.oa.exclusive_stream) {
+	if (dev_priv->perf.exclusive_stream) {
 		DRM_DEBUG("OA unit already in use\n");
 		return -EBUSY;
 	}
@@ -2046,43 +2065,23 @@  static int i915_oa_stream_init(struct i915_perf_stream *stream,
 		return -EINVAL;
 	}
 
-	/* We set up some ratelimit state to potentially throttle any _NOTES
-	 * about spurious, invalid OA reports which we don't forward to
-	 * userspace.
-	 *
-	 * The initialization is associated with opening the stream (not driver
-	 * init) considering we print a _NOTE about any throttling when closing
-	 * the stream instead of waiting until driver _fini which no one would
-	 * ever see.
-	 *
-	 * Using the same limiting factors as printk_ratelimit()
-	 */
-	ratelimit_state_init(&dev_priv->perf.oa.spurious_report_rs,
-			     5 * HZ, 10);
-	/* Since we use a DRM_NOTE for spurious reports it would be
-	 * inconsistent to let __ratelimit() automatically print a warning for
-	 * throttling.
-	 */
-	ratelimit_set_flags(&dev_priv->perf.oa.spurious_report_rs,
-			    RATELIMIT_MSG_ON_RELEASE);
-
 	stream->sample_size = sizeof(struct drm_i915_perf_record_header);
 
-	format_size = dev_priv->perf.oa.oa_formats[props->oa_format].size;
+	format_size = dev_priv->perf.oa_formats[props->oa_format].size;
 
 	stream->sample_flags |= SAMPLE_OA_REPORT;
 	stream->sample_size += format_size;
 
-	dev_priv->perf.oa.oa_buffer.format_size = format_size;
-	if (WARN_ON(dev_priv->perf.oa.oa_buffer.format_size == 0))
+	stream->oa_buffer.format_size = format_size;
+	if (WARN_ON(stream->oa_buffer.format_size == 0))
 		return -EINVAL;
 
-	dev_priv->perf.oa.oa_buffer.format =
-		dev_priv->perf.oa.oa_formats[props->oa_format].format;
+	stream->oa_buffer.format =
+		dev_priv->perf.oa_formats[props->oa_format].format;
 
-	dev_priv->perf.oa.periodic = props->oa_periodic;
-	if (dev_priv->perf.oa.periodic)
-		dev_priv->perf.oa.period_exponent = props->oa_period_exponent;
+	stream->periodic = props->oa_periodic;
+	if (stream->periodic)
+		stream->period_exponent = props->oa_period_exponent;
 
 	if (stream->ctx) {
 		ret = oa_get_render_ctx_id(stream);
@@ -2113,7 +2112,7 @@  static int i915_oa_stream_init(struct i915_perf_stream *stream,
 	stream->wakeref = intel_runtime_pm_get(dev_priv);
 	intel_uncore_forcewake_get(&dev_priv->uncore, FORCEWAKE_ALL);
 
-	ret = alloc_oa_buffer(dev_priv);
+	ret = alloc_oa_buffer(stream);
 	if (ret)
 		goto err_oa_buf_alloc;
 
@@ -2122,9 +2121,9 @@  static int i915_oa_stream_init(struct i915_perf_stream *stream,
 		goto err_lock;
 
 	stream->ops = &i915_oa_stream_ops;
-	dev_priv->perf.oa.exclusive_stream = stream;
+	dev_priv->perf.exclusive_stream = stream;
 
-	ret = dev_priv->perf.oa.ops.enable_metric_set(stream);
+	ret = dev_priv->perf.ops.enable_metric_set(stream);
 	if (ret) {
 		DRM_DEBUG("Unable to enable metric set\n");
 		goto err_enable;
@@ -2132,15 +2131,21 @@  static int i915_oa_stream_init(struct i915_perf_stream *stream,
 
 	mutex_unlock(&dev_priv->drm.struct_mutex);
 
+	hrtimer_init(&stream->poll_check_timer,
+		     CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+	stream->poll_check_timer.function = oa_poll_check_timer_cb;
+	init_waitqueue_head(&stream->poll_wq);
+	spin_lock_init(&stream->oa_buffer.ptr_lock);
+
 	return 0;
 
 err_enable:
-	dev_priv->perf.oa.exclusive_stream = NULL;
-	dev_priv->perf.oa.ops.disable_metric_set(dev_priv);
+	dev_priv->perf.exclusive_stream = NULL;
+	dev_priv->perf.ops.disable_metric_set(stream);
 	mutex_unlock(&dev_priv->drm.struct_mutex);
 
 err_lock:
-	free_oa_buffer(dev_priv);
+	free_oa_buffer(stream);
 
 err_oa_buf_alloc:
 	put_oa_config(dev_priv, stream->oa_config);
@@ -2164,9 +2169,12 @@  void i915_oa_init_reg_state(struct intel_engine_cs *engine,
 	if (engine->class != RENDER_CLASS)
 		return;
 
-	stream = engine->i915->perf.oa.exclusive_stream;
+	stream = engine->i915->perf.exclusive_stream;
 	if (stream)
-		gen8_update_reg_state_unlocked(ce, regs, stream->oa_config);
+		gen8_update_reg_state_unlocked(stream,
+					       ce,
+					       regs,
+					       stream->oa_config);
 }
 
 /**
@@ -2282,7 +2290,7 @@  static ssize_t i915_perf_read(struct file *file,
 		/* Maybe make ->pollin per-stream state if we support multiple
 		 * concurrent streams in the future.
 		 */
-		dev_priv->perf.oa.pollin = false;
+		stream->pollin = false;
 	}
 
 	return ret;
@@ -2290,13 +2298,13 @@  static ssize_t i915_perf_read(struct file *file,
 
 static enum hrtimer_restart oa_poll_check_timer_cb(struct hrtimer *hrtimer)
 {
-	struct drm_i915_private *dev_priv =
-		container_of(hrtimer, typeof(*dev_priv),
-			     perf.oa.poll_check_timer);
+	struct i915_perf_stream *stream = container_of(hrtimer,
+						       typeof(*stream),
+						       poll_check_timer);
 
-	if (oa_buffer_check_unlocked(dev_priv)) {
-		dev_priv->perf.oa.pollin = true;
-		wake_up(&dev_priv->perf.oa.poll_wq);
+	if (oa_buffer_check_unlocked(stream)) {
+		stream->pollin = true;
+		wake_up(&stream->poll_wq);
 	}
 
 	hrtimer_forward_now(hrtimer, ns_to_ktime(POLL_PERIOD));
@@ -2335,7 +2343,7 @@  static __poll_t i915_perf_poll_locked(struct drm_i915_private *dev_priv,
 	 * the hrtimer/oa_poll_check_timer_cb to notify us when there are
 	 * samples to read.
 	 */
-	if (dev_priv->perf.oa.pollin)
+	if (stream->pollin)
 		events |= EPOLLIN;
 
 	return events;
@@ -2668,8 +2676,10 @@  i915_perf_open_ioctl_locked(struct drm_i915_private *dev_priv,
 
 static u64 oa_exponent_to_ns(struct drm_i915_private *dev_priv, int exponent)
 {
+	struct intel_runtime_info *ri = RUNTIME_INFO(dev_priv);
+
 	return div64_u64(1000000000ULL * (2ULL << exponent),
-			 1000ULL * RUNTIME_INFO(dev_priv)->cs_timestamp_frequency_khz);
+			 1000ULL * ri->cs_timestamp_frequency_khz);
 }
 
 /**
@@ -2753,7 +2763,7 @@  static int read_properties_unlocked(struct drm_i915_private *dev_priv,
 					  value);
 				return -EINVAL;
 			}
-			if (!dev_priv->perf.oa.oa_formats[value].size) {
+			if (!dev_priv->perf.oa_formats[value].size) {
 				DRM_DEBUG("Unsupported OA report format %llu\n",
 					  value);
 				return -EINVAL;
@@ -2897,7 +2907,7 @@  void i915_perf_register(struct drm_i915_private *dev_priv)
 	if (!dev_priv->perf.metrics_kobj)
 		goto exit;
 
-	sysfs_attr_init(&dev_priv->perf.oa.test_config.sysfs_metric_id.attr);
+	sysfs_attr_init(&dev_priv->perf.test_config.sysfs_metric_id.attr);
 
 	if (INTEL_GEN(dev_priv) >= 11) {
 		i915_perf_load_test_config_icl(dev_priv);
@@ -2932,15 +2942,15 @@  void i915_perf_register(struct drm_i915_private *dev_priv)
 		i915_perf_load_test_config_hsw(dev_priv);
 }
 
-	if (dev_priv->perf.oa.test_config.id == 0)
+	if (dev_priv->perf.test_config.id == 0)
 		goto sysfs_error;
 
 	ret = sysfs_create_group(dev_priv->perf.metrics_kobj,
-				 &dev_priv->perf.oa.test_config.sysfs_metric);
+				 &dev_priv->perf.test_config.sysfs_metric);
 	if (ret)
 		goto sysfs_error;
 
-	atomic_set(&dev_priv->perf.oa.test_config.ref_count, 1);
+	atomic_set(&dev_priv->perf.test_config.ref_count, 1);
 
 	goto exit;
 
@@ -2967,7 +2977,7 @@  void i915_perf_unregister(struct drm_i915_private *dev_priv)
 		return;
 
 	sysfs_remove_group(dev_priv->perf.metrics_kobj,
-			   &dev_priv->perf.oa.test_config.sysfs_metric);
+			   &dev_priv->perf.test_config.sysfs_metric);
 
 	kobject_put(dev_priv->perf.metrics_kobj);
 	dev_priv->perf.metrics_kobj = NULL;
@@ -2993,7 +3003,8 @@  static bool gen8_is_valid_flex_addr(struct drm_i915_private *dev_priv, u32 addr)
 	return false;
 }
 
-static bool gen7_is_valid_b_counter_addr(struct drm_i915_private *dev_priv, u32 addr)
+static bool gen7_is_valid_b_counter_addr(struct drm_i915_private *dev_priv,
+					 u32 addr)
 {
 	return (addr >= i915_mmio_reg_offset(OASTARTTRIG1) &&
 		addr <= i915_mmio_reg_offset(OASTARTTRIG8)) ||
@@ -3078,7 +3089,9 @@  static struct i915_oa_reg *alloc_oa_regs(struct drm_i915_private *dev_priv,
 	if (!access_ok(regs, n_regs * sizeof(u32) * 2))
 		return ERR_PTR(-EFAULT);
 
-	/* No is_valid function means we're not allowing any register to be programmed. */
+	/* No is_valid function means we're not allowing any register to be
+	 * programmed.
+	 */
 	GEM_BUG_ON(!is_valid);
 	if (!is_valid)
 		return ERR_PTR(-EINVAL);
@@ -3211,7 +3224,7 @@  int i915_perf_add_config_ioctl(struct drm_device *dev, void *data,
 	oa_config->mux_regs_len = args->n_mux_regs;
 	oa_config->mux_regs =
 		alloc_oa_regs(dev_priv,
-			      dev_priv->perf.oa.ops.is_valid_mux_reg,
+			      dev_priv->perf.ops.is_valid_mux_reg,
 			      u64_to_user_ptr(args->mux_regs_ptr),
 			      args->n_mux_regs);
 
@@ -3224,7 +3237,7 @@  int i915_perf_add_config_ioctl(struct drm_device *dev, void *data,
 	oa_config->b_counter_regs_len = args->n_boolean_regs;
 	oa_config->b_counter_regs =
 		alloc_oa_regs(dev_priv,
-			      dev_priv->perf.oa.ops.is_valid_b_counter_reg,
+			      dev_priv->perf.ops.is_valid_b_counter_reg,
 			      u64_to_user_ptr(args->boolean_regs_ptr),
 			      args->n_boolean_regs);
 
@@ -3243,7 +3256,7 @@  int i915_perf_add_config_ioctl(struct drm_device *dev, void *data,
 		oa_config->flex_regs_len = args->n_flex_regs;
 		oa_config->flex_regs =
 			alloc_oa_regs(dev_priv,
-				      dev_priv->perf.oa.ops.is_valid_flex_reg,
+				      dev_priv->perf.ops.is_valid_flex_reg,
 				      u64_to_user_ptr(args->flex_regs_ptr),
 				      args->n_flex_regs);
 
@@ -3300,7 +3313,8 @@  int i915_perf_add_config_ioctl(struct drm_device *dev, void *data,
 }
 
 /**
- * i915_perf_remove_config_ioctl - DRM ioctl() for userspace to remove an OA config
+ * i915_perf_remove_config_ioctl - DRM ioctl() for userspace to remove an OA
+ * config
  * @dev: drm device
  * @data: ioctl data (pointer to u64 integer) copied from userspace
  * @file: drm file
@@ -3409,21 +3423,23 @@  static struct ctl_table dev_root[] = {
  */
 void i915_perf_init(struct drm_i915_private *dev_priv)
 {
+	struct intel_runtime_info *ri;
+
 	if (IS_HASWELL(dev_priv)) {
-		dev_priv->perf.oa.ops.is_valid_b_counter_reg =
+		dev_priv->perf.ops.is_valid_b_counter_reg =
 			gen7_is_valid_b_counter_addr;
-		dev_priv->perf.oa.ops.is_valid_mux_reg =
+		dev_priv->perf.ops.is_valid_mux_reg =
 			hsw_is_valid_mux_addr;
-		dev_priv->perf.oa.ops.is_valid_flex_reg = NULL;
-		dev_priv->perf.oa.ops.enable_metric_set = hsw_enable_metric_set;
-		dev_priv->perf.oa.ops.disable_metric_set = hsw_disable_metric_set;
-		dev_priv->perf.oa.ops.oa_enable = gen7_oa_enable;
-		dev_priv->perf.oa.ops.oa_disable = gen7_oa_disable;
-		dev_priv->perf.oa.ops.read = gen7_oa_read;
-		dev_priv->perf.oa.ops.oa_hw_tail_read =
+		dev_priv->perf.ops.is_valid_flex_reg = NULL;
+		dev_priv->perf.ops.enable_metric_set = hsw_enable_metric_set;
+		dev_priv->perf.ops.disable_metric_set = hsw_disable_metric_set;
+		dev_priv->perf.ops.oa_enable = gen7_oa_enable;
+		dev_priv->perf.ops.oa_disable = gen7_oa_disable;
+		dev_priv->perf.ops.read = gen7_oa_read;
+		dev_priv->perf.ops.oa_hw_tail_read =
 			gen7_oa_hw_tail_read;
 
-		dev_priv->perf.oa.oa_formats = hsw_oa_formats;
+		dev_priv->perf.oa_formats = hsw_oa_formats;
 	} else if (HAS_LOGICAL_RING_CONTEXTS(dev_priv)) {
 		/* Note: that although we could theoretically also support the
 		 * legacy ringbuffer mode on BDW (and earlier iterations of
@@ -3431,75 +3447,93 @@  void i915_perf_init(struct drm_i915_private *dev_priv)
 		 * worth the complexity to maintain now that BDW+ enable
 		 * execlist mode by default.
 		 */
-		dev_priv->perf.oa.oa_formats = gen8_plus_oa_formats;
+		dev_priv->perf.oa_formats = gen8_plus_oa_formats;
 
-		dev_priv->perf.oa.ops.oa_enable = gen8_oa_enable;
-		dev_priv->perf.oa.ops.oa_disable = gen8_oa_disable;
-		dev_priv->perf.oa.ops.read = gen8_oa_read;
-		dev_priv->perf.oa.ops.oa_hw_tail_read = gen8_oa_hw_tail_read;
+		dev_priv->perf.ops.oa_enable = gen8_oa_enable;
+		dev_priv->perf.ops.oa_disable = gen8_oa_disable;
+		dev_priv->perf.ops.read = gen8_oa_read;
+		dev_priv->perf.ops.oa_hw_tail_read = gen8_oa_hw_tail_read;
 
 		if (IS_GEN_RANGE(dev_priv, 8, 9)) {
-			dev_priv->perf.oa.ops.is_valid_b_counter_reg =
+			dev_priv->perf.ops.is_valid_b_counter_reg =
 				gen7_is_valid_b_counter_addr;
-			dev_priv->perf.oa.ops.is_valid_mux_reg =
+			dev_priv->perf.ops.is_valid_mux_reg =
 				gen8_is_valid_mux_addr;
-			dev_priv->perf.oa.ops.is_valid_flex_reg =
+			dev_priv->perf.ops.is_valid_flex_reg =
 				gen8_is_valid_flex_addr;
 
 			if (IS_CHERRYVIEW(dev_priv)) {
-				dev_priv->perf.oa.ops.is_valid_mux_reg =
+				dev_priv->perf.ops.is_valid_mux_reg =
 					chv_is_valid_mux_addr;
 			}
 
-			dev_priv->perf.oa.ops.enable_metric_set = gen8_enable_metric_set;
-			dev_priv->perf.oa.ops.disable_metric_set = gen8_disable_metric_set;
+			dev_priv->perf.ops.enable_metric_set =
+				gen8_enable_metric_set;
+			dev_priv->perf.ops.disable_metric_set =
+				gen8_disable_metric_set;
 
 			if (IS_GEN(dev_priv, 8)) {
-				dev_priv->perf.oa.ctx_oactxctrl_offset = 0x120;
-				dev_priv->perf.oa.ctx_flexeu0_offset = 0x2ce;
+				dev_priv->perf.ctx_oactxctrl_offset = 0x120;
+				dev_priv->perf.ctx_flexeu0_offset = 0x2ce;
 
-				dev_priv->perf.oa.gen8_valid_ctx_bit = (1<<25);
+				dev_priv->perf.gen8_valid_ctx_bit = (1<<25);
 			} else {
-				dev_priv->perf.oa.ctx_oactxctrl_offset = 0x128;
-				dev_priv->perf.oa.ctx_flexeu0_offset = 0x3de;
+				dev_priv->perf.ctx_oactxctrl_offset = 0x128;
+				dev_priv->perf.ctx_flexeu0_offset = 0x3de;
 
-				dev_priv->perf.oa.gen8_valid_ctx_bit = (1<<16);
+				dev_priv->perf.gen8_valid_ctx_bit = (1<<16);
 			}
 		} else if (IS_GEN_RANGE(dev_priv, 10, 11)) {
-			dev_priv->perf.oa.ops.is_valid_b_counter_reg =
+			dev_priv->perf.ops.is_valid_b_counter_reg =
 				gen7_is_valid_b_counter_addr;
-			dev_priv->perf.oa.ops.is_valid_mux_reg =
+			dev_priv->perf.ops.is_valid_mux_reg =
 				gen10_is_valid_mux_addr;
-			dev_priv->perf.oa.ops.is_valid_flex_reg =
+			dev_priv->perf.ops.is_valid_flex_reg =
 				gen8_is_valid_flex_addr;
 
-			dev_priv->perf.oa.ops.enable_metric_set = gen8_enable_metric_set;
-			dev_priv->perf.oa.ops.disable_metric_set = gen10_disable_metric_set;
+			dev_priv->perf.ops.enable_metric_set =
+				gen8_enable_metric_set;
+			dev_priv->perf.ops.disable_metric_set =
+				gen10_disable_metric_set;
 
-			dev_priv->perf.oa.ctx_oactxctrl_offset = 0x128;
-			dev_priv->perf.oa.ctx_flexeu0_offset = 0x3de;
+			dev_priv->perf.ctx_oactxctrl_offset = 0x128;
+			dev_priv->perf.ctx_flexeu0_offset = 0x3de;
 
-			dev_priv->perf.oa.gen8_valid_ctx_bit = (1<<16);
+			dev_priv->perf.gen8_valid_ctx_bit = (1<<16);
 		}
 	}
 
-	if (dev_priv->perf.oa.ops.enable_metric_set) {
-		hrtimer_init(&dev_priv->perf.oa.poll_check_timer,
-				CLOCK_MONOTONIC, HRTIMER_MODE_REL);
-		dev_priv->perf.oa.poll_check_timer.function = oa_poll_check_timer_cb;
-		init_waitqueue_head(&dev_priv->perf.oa.poll_wq);
-
+	if (dev_priv->perf.ops.enable_metric_set) {
 		INIT_LIST_HEAD(&dev_priv->perf.streams);
 		mutex_init(&dev_priv->perf.lock);
-		spin_lock_init(&dev_priv->perf.oa.oa_buffer.ptr_lock);
 
+		ri = RUNTIME_INFO(dev_priv);
 		oa_sample_rate_hard_limit = 1000 *
-			(RUNTIME_INFO(dev_priv)->cs_timestamp_frequency_khz / 2);
+			(ri->cs_timestamp_frequency_khz / 2);
 		dev_priv->perf.sysctl_header = register_sysctl_table(dev_root);
 
 		mutex_init(&dev_priv->perf.metrics_lock);
 		idr_init(&dev_priv->perf.metrics_idr);
 
+		/* We set up some ratelimit state to potentially throttle any
+		 * _NOTES about spurious, invalid OA reports which we don't
+		 * forward to userspace.
+		 *
+		 * We print a _NOTE about any throttling when closing the
+		 * stream instead of waiting until driver _fini which no one
+		 * would ever see.
+		 *
+		 * Using the same limiting factors as printk_ratelimit()
+		 */
+		ratelimit_state_init(&dev_priv->perf.spurious_report_rs,
+				     5 * HZ, 10);
+		/* Since we use a DRM_NOTE for spurious reports it would be
+		 * inconsistent to let __ratelimit() automatically print a
+		 * warning for throttling.
+		 */
+		ratelimit_set_flags(&dev_priv->perf.spurious_report_rs,
+				    RATELIMIT_MSG_ON_RELEASE);
+
 		dev_priv->perf.initialized = true;
 	}
 }
@@ -3528,7 +3562,7 @@  void i915_perf_fini(struct drm_i915_private *dev_priv)
 
 	unregister_sysctl_table(dev_priv->perf.sysctl_header);
 
-	memset(&dev_priv->perf.oa.ops, 0, sizeof(dev_priv->perf.oa.ops));
+	memset(&dev_priv->perf.ops, 0, sizeof(dev_priv->perf.ops));
 
 	dev_priv->perf.initialized = false;
 }