diff mbox

[v8,11/12] drm/i915: Add more Haswell OA metric sets

Message ID 20161028021430.2177-12-robert@sixbynine.org (mailing list archive)
State New, archived
Headers show

Commit Message

Robert Bragg Oct. 28, 2016, 2:14 a.m. UTC
This adds 'compute', 'compute extended', 'memory reads', 'memory writes'
and 'sampler balance' metric sets for Haswell.

The code is auto generated from an XML description of metric sets,
currently maintained in gputop, ref:

 https://github.com/rib/gputop
 > gputop-data/oa-*.xml
 > scripts/i915-perf-kernelgen.py

 $ make -C gputop-data -f Makefile.xml

Signed-off-by: Robert Bragg <robert@sixbynine.org>
Reviewed-by: Matthew Auld <matthew.auld@intel.com>
---
 drivers/gpu/drm/i915/i915_oa_hsw.c | 559 ++++++++++++++++++++++++++++++++++++-
 1 file changed, 558 insertions(+), 1 deletion(-)

Comments

Chris Wilson Nov. 1, 2016, 2:57 p.m. UTC | #1
On Fri, Oct 28, 2016 at 03:14:29AM +0100, Robert Bragg wrote:
> This adds 'compute', 'compute extended', 'memory reads', 'memory writes'
> and 'sampler balance' metric sets for Haswell.
> 
> The code is auto generated from an XML description of metric sets,
> currently maintained in gputop, ref:
> 
>  https://github.com/rib/gputop
>  > gputop-data/oa-*.xml
>  > scripts/i915-perf-kernelgen.py
> 
>  $ make -C gputop-data -f Makefile.xml
> 
> Signed-off-by: Robert Bragg <robert@sixbynine.org>
> Reviewed-by: Matthew Auld <matthew.auld@intel.com>
> ---
>  drivers/gpu/drm/i915/i915_oa_hsw.c | 559 ++++++++++++++++++++++++++++++++++++-
>  1 file changed, 558 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_oa_hsw.c b/drivers/gpu/drm/i915/i915_oa_hsw.c
> index 6af25cf..4ddf756 100644
> --- a/drivers/gpu/drm/i915/i915_oa_hsw.c
> +++ b/drivers/gpu/drm/i915/i915_oa_hsw.c
> @@ -31,9 +31,14 @@
>  
>  enum metric_set_id {
>  	METRIC_SET_ID_RENDER_BASIC = 1,
> +	METRIC_SET_ID_COMPUTE_BASIC,
> +	METRIC_SET_ID_COMPUTE_EXTENDED,
> +	METRIC_SET_ID_MEMORY_READS,
> +	METRIC_SET_ID_MEMORY_WRITES,
> +	METRIC_SET_ID_SAMPLER_BALANCE,
>  };
>  
> -int i915_oa_n_builtin_metric_sets_hsw = 1;
> +int i915_oa_n_builtin_metric_sets_hsw = 6;
>  
>  static const struct i915_oa_reg b_counter_config_render_basic[] = {
>  	{ _MMIO(0x2724), 0x00800000 },
> @@ -112,6 +117,298 @@ get_render_basic_mux_config(struct drm_i915_private *dev_priv,
>  	return mux_config_render_basic;
>  }
>  
> +static const struct i915_oa_reg b_counter_config_compute_basic[] = {
> +	{ _MMIO(0x2710), 0x00000000 },
> +	{ _MMIO(0x2714), 0x00800000 },
> +	{ _MMIO(0x2718), 0xaaaaaaaa },
> +	{ _MMIO(0x271c), 0xaaaaaaaa },
> +	{ _MMIO(0x2720), 0x00000000 },
> +	{ _MMIO(0x2724), 0x00800000 },
> +	{ _MMIO(0x2728), 0xaaaaaaaa },
> +	{ _MMIO(0x272c), 0xaaaaaaaa },
> +	{ _MMIO(0x2740), 0x00000000 },
> +	{ _MMIO(0x2744), 0x00000000 },
> +	{ _MMIO(0x2748), 0x00000000 },
> +	{ _MMIO(0x274c), 0x00000000 },
> +	{ _MMIO(0x2750), 0x00000000 },
> +	{ _MMIO(0x2754), 0x00000000 },
> +	{ _MMIO(0x2758), 0x00000000 },
> +	{ _MMIO(0x275c), 0x00000000 },
> +	{ _MMIO(0x236c), 0x00000000 },
> +};
> +
> +static const struct i915_oa_reg mux_config_compute_basic[] = {
> +	{ _MMIO(0x253a4), 0x00000000 },
> +	{ _MMIO(0x2681c), 0x01f00800 },
> +	{ _MMIO(0x26820), 0x00001000 },
> +	{ _MMIO(0x2781c), 0x01f00800 },
> +	{ _MMIO(0x26520), 0x00000007 },
> +	{ _MMIO(0x265a0), 0x00000007 },
> +	{ _MMIO(0x25380), 0x00000010 },
> +	{ _MMIO(0x2538c), 0x00300000 },
> +	{ _MMIO(0x25384), 0xaa8aaaaa },
> +	{ _MMIO(0x25404), 0xffffffff },
> +	{ _MMIO(0x26800), 0x00004202 },
> +	{ _MMIO(0x26808), 0x00605817 },
> +	{ _MMIO(0x2680c), 0x10001005 },
> +	{ _MMIO(0x26804), 0x00000000 },
> +	{ _MMIO(0x27800), 0x00000102 },
> +	{ _MMIO(0x27808), 0x0c0701e0 },
> +	{ _MMIO(0x2780c), 0x000200a0 },
> +	{ _MMIO(0x27804), 0x00000000 },
> +	{ _MMIO(0x26484), 0x44000000 },
> +	{ _MMIO(0x26704), 0x44000000 },
> +	{ _MMIO(0x26500), 0x00000006 },
> +	{ _MMIO(0x26510), 0x00000001 },
> +	{ _MMIO(0x26504), 0x88000000 },
> +	{ _MMIO(0x26580), 0x00000006 },
> +	{ _MMIO(0x26590), 0x00000020 },
> +	{ _MMIO(0x26584), 0x00000000 },
> +	{ _MMIO(0x26104), 0x55822222 },
> +	{ _MMIO(0x26184), 0xaa866666 },
> +	{ _MMIO(0x25420), 0x08320c83 },
> +	{ _MMIO(0x25424), 0x06820c83 },
> +	{ _MMIO(0x2541c), 0x00000000 },
> +	{ _MMIO(0x25428), 0x00000c03 },
> +};
> +
> +static const struct i915_oa_reg *
> +get_compute_basic_mux_config(struct drm_i915_private *dev_priv,
> +			     int *len)
> +{
> +	*len = ARRAY_SIZE(mux_config_compute_basic);
> +	return mux_config_compute_basic;
> +}

> @@ -140,6 +437,106 @@ int i915_oa_select_metric_set_hsw(struct drm_i915_private *dev_priv)
>  			ARRAY_SIZE(b_counter_config_render_basic);
>  
>  		return 0;
> +	case METRIC_SET_ID_COMPUTE_BASIC:
> +		dev_priv->perf.oa.mux_regs =
> +			get_compute_basic_mux_config(dev_priv,
> +						     &dev_priv->perf.oa.mux_regs_len);
> +		if (!dev_priv->perf.oa.mux_regs) {
> +			DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_BASIC\" metric set");
> +
> +			/* EINVAL because *_register_sysfs already checked this
> +			 * and so it wouldn't have been advertised so userspace and
> +			 * so shouldn't have been requested
> +			 */
> +			return -EINVAL;
> +		}
> +
> +		dev_priv->perf.oa.b_counter_regs =
> +			b_counter_config_compute_basic;
> +		dev_priv->perf.oa.b_counter_regs_len =
> +			ARRAY_SIZE(b_counter_config_compute_basic);
> +
> +		return 0;

>  int
>  i915_perf_register_sysfs_hsw(struct drm_i915_private *dev_priv)
>  {
> @@ -178,9 +685,49 @@ i915_perf_register_sysfs_hsw(struct drm_i915_private *dev_priv)
>  		if (ret)
>  			goto error_render_basic;
>  	}
> +	if (get_compute_basic_mux_config(dev_priv, &mux_len)) {

Why not use the derived state in dev_priv->perf.oa.mux_regs? Then we
only expose what is initialised.
-Chris
Robert Bragg Nov. 1, 2016, 4:53 p.m. UTC | #2
On Tue, Nov 1, 2016 at 2:57 PM, Chris Wilson <chris@chris-wilson.co.uk>
wrote:

> On Fri, Oct 28, 2016 at 03:14:29AM +0100, Robert Bragg wrote:
> > This adds 'compute', 'compute extended', 'memory reads', 'memory writes'
> > and 'sampler balance' metric sets for Haswell.
> >
> > The code is auto generated from an XML description of metric sets,
> > currently maintained in gputop, ref:
> >
> >  https://github.com/rib/gputop
> >  > gputop-data/oa-*.xml
> >  > scripts/i915-perf-kernelgen.py
> >
> >  $ make -C gputop-data -f Makefile.xml
> >
> > Signed-off-by: Robert Bragg <robert@sixbynine.org>
> > Reviewed-by: Matthew Auld <matthew.auld@intel.com>
> > ---
> >  drivers/gpu/drm/i915/i915_oa_hsw.c | 559 ++++++++++++++++++++++++++++++
> ++++++-
> >  1 file changed, 558 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/gpu/drm/i915/i915_oa_hsw.c
> b/drivers/gpu/drm/i915/i915_oa_hsw.c
> > index 6af25cf..4ddf756 100644
> > --- a/drivers/gpu/drm/i915/i915_oa_hsw.c
> > +++ b/drivers/gpu/drm/i915/i915_oa_hsw.c
> > @@ -31,9 +31,14 @@
> >
> >  enum metric_set_id {
> >       METRIC_SET_ID_RENDER_BASIC = 1,
> > +     METRIC_SET_ID_COMPUTE_BASIC,
> > +     METRIC_SET_ID_COMPUTE_EXTENDED,
> > +     METRIC_SET_ID_MEMORY_READS,
> > +     METRIC_SET_ID_MEMORY_WRITES,
> > +     METRIC_SET_ID_SAMPLER_BALANCE,
> >  };
> >
> > -int i915_oa_n_builtin_metric_sets_hsw = 1;
> > +int i915_oa_n_builtin_metric_sets_hsw = 6;
> >
> >  static const struct i915_oa_reg b_counter_config_render_basic[] = {
> >       { _MMIO(0x2724), 0x00800000 },
> > @@ -112,6 +117,298 @@ get_render_basic_mux_config(struct
> drm_i915_private *dev_priv,
> >       return mux_config_render_basic;
> >  }
> >
> > +static const struct i915_oa_reg b_counter_config_compute_basic[] = {
> > +     { _MMIO(0x2710), 0x00000000 },
> > +     { _MMIO(0x2714), 0x00800000 },
> > +     { _MMIO(0x2718), 0xaaaaaaaa },
> > +     { _MMIO(0x271c), 0xaaaaaaaa },
> > +     { _MMIO(0x2720), 0x00000000 },
> > +     { _MMIO(0x2724), 0x00800000 },
> > +     { _MMIO(0x2728), 0xaaaaaaaa },
> > +     { _MMIO(0x272c), 0xaaaaaaaa },
> > +     { _MMIO(0x2740), 0x00000000 },
> > +     { _MMIO(0x2744), 0x00000000 },
> > +     { _MMIO(0x2748), 0x00000000 },
> > +     { _MMIO(0x274c), 0x00000000 },
> > +     { _MMIO(0x2750), 0x00000000 },
> > +     { _MMIO(0x2754), 0x00000000 },
> > +     { _MMIO(0x2758), 0x00000000 },
> > +     { _MMIO(0x275c), 0x00000000 },
> > +     { _MMIO(0x236c), 0x00000000 },
> > +};
> > +
> > +static const struct i915_oa_reg mux_config_compute_basic[] = {
> > +     { _MMIO(0x253a4), 0x00000000 },
> > +     { _MMIO(0x2681c), 0x01f00800 },
> > +     { _MMIO(0x26820), 0x00001000 },
> > +     { _MMIO(0x2781c), 0x01f00800 },
> > +     { _MMIO(0x26520), 0x00000007 },
> > +     { _MMIO(0x265a0), 0x00000007 },
> > +     { _MMIO(0x25380), 0x00000010 },
> > +     { _MMIO(0x2538c), 0x00300000 },
> > +     { _MMIO(0x25384), 0xaa8aaaaa },
> > +     { _MMIO(0x25404), 0xffffffff },
> > +     { _MMIO(0x26800), 0x00004202 },
> > +     { _MMIO(0x26808), 0x00605817 },
> > +     { _MMIO(0x2680c), 0x10001005 },
> > +     { _MMIO(0x26804), 0x00000000 },
> > +     { _MMIO(0x27800), 0x00000102 },
> > +     { _MMIO(0x27808), 0x0c0701e0 },
> > +     { _MMIO(0x2780c), 0x000200a0 },
> > +     { _MMIO(0x27804), 0x00000000 },
> > +     { _MMIO(0x26484), 0x44000000 },
> > +     { _MMIO(0x26704), 0x44000000 },
> > +     { _MMIO(0x26500), 0x00000006 },
> > +     { _MMIO(0x26510), 0x00000001 },
> > +     { _MMIO(0x26504), 0x88000000 },
> > +     { _MMIO(0x26580), 0x00000006 },
> > +     { _MMIO(0x26590), 0x00000020 },
> > +     { _MMIO(0x26584), 0x00000000 },
> > +     { _MMIO(0x26104), 0x55822222 },
> > +     { _MMIO(0x26184), 0xaa866666 },
> > +     { _MMIO(0x25420), 0x08320c83 },
> > +     { _MMIO(0x25424), 0x06820c83 },
> > +     { _MMIO(0x2541c), 0x00000000 },
> > +     { _MMIO(0x25428), 0x00000c03 },
> > +};
> > +
> > +static const struct i915_oa_reg *
> > +get_compute_basic_mux_config(struct drm_i915_private *dev_priv,
> > +                          int *len)
> > +{
> > +     *len = ARRAY_SIZE(mux_config_compute_basic);
> > +     return mux_config_compute_basic;
> > +}
>
> > @@ -140,6 +437,106 @@ int i915_oa_select_metric_set_hsw(struct
> drm_i915_private *dev_priv)
> >                       ARRAY_SIZE(b_counter_config_render_basic);
> >
> >               return 0;
> > +     case METRIC_SET_ID_COMPUTE_BASIC:
> > +             dev_priv->perf.oa.mux_regs =
> > +                     get_compute_basic_mux_config(dev_priv,
> > +
> &dev_priv->perf.oa.mux_regs_len);
> > +             if (!dev_priv->perf.oa.mux_regs) {
> > +                     DRM_DEBUG_DRIVER("No suitable MUX config for
> \"COMPUTE_BASIC\" metric set");
> > +
> > +                     /* EINVAL because *_register_sysfs already checked
> this
> > +                      * and so it wouldn't have been advertised so
> userspace and
> > +                      * so shouldn't have been requested
> > +                      */
> > +                     return -EINVAL;
> > +             }
> > +
> > +             dev_priv->perf.oa.b_counter_regs =
> > +                     b_counter_config_compute_basic;
> > +             dev_priv->perf.oa.b_counter_regs_len =
> > +                     ARRAY_SIZE(b_counter_config_compute_basic);
> > +
> > +             return 0;
>
> >  int
> >  i915_perf_register_sysfs_hsw(struct drm_i915_private *dev_priv)
> >  {
> > @@ -178,9 +685,49 @@ i915_perf_register_sysfs_hsw(struct
> drm_i915_private *dev_priv)
> >               if (ret)
> >                       goto error_render_basic;
> >       }
> > +     if (get_compute_basic_mux_config(dev_priv, &mux_len)) {
>
> Why not use the derived state in dev_priv->perf.oa.mux_regs? Then we
> only expose what is initialised.
>

Although for Haswell none of our metric sets have conditional MUX
configurations, the generated code should already be in shape to only
advertising metric sets applicable to the system (which becomes an issue
for gen8+). This was changed relatively recently in the gen8+ series after
Mark Janes was hitting issues on Skylake in some of his tooling due to Mesa
advertising one of the compute metric sets that wasn't really available on
the system he had, which was only discoverable as a GL error when
attempting to use it.

The perf.oa.mux_regs state only pertains to one current metric set that the
OA unit has been configured with, after calling the generated
i915_oa_select_metric_set_hsw() function in hsw_enable_metric_set(). Until
an OA stream is opened and enabled perf.oa.mux_regs won't be initialised.

Notably the recent change for gen8+ mentioned above was to have the
_select_metric_set_<gen>() code and the _register_sysfs_<gen>() code both
work in terms of the get_<metric_set>_mux_config() functions since it's
these functions that will check the fiddly sku specfic details on gen8+ to
select the right MUX config or potentially fail if the metric set isn't
available on the current system. So for gen8+ we can expect
get_compute_basic_mux_config() will fail if the config isn't available and
then won't be advertised via sysfs. On Haswell it looks a little redundant
having these get_ functions unconditionally return a pointer to a
corresponding array.

Hope that clarifies,
- Robert



> -Chris
>
> --
> Chris Wilson, Intel Open Source Technology Centre
>
diff mbox

Patch

diff --git a/drivers/gpu/drm/i915/i915_oa_hsw.c b/drivers/gpu/drm/i915/i915_oa_hsw.c
index 6af25cf..4ddf756 100644
--- a/drivers/gpu/drm/i915/i915_oa_hsw.c
+++ b/drivers/gpu/drm/i915/i915_oa_hsw.c
@@ -31,9 +31,14 @@ 
 
 enum metric_set_id {
 	METRIC_SET_ID_RENDER_BASIC = 1,
+	METRIC_SET_ID_COMPUTE_BASIC,
+	METRIC_SET_ID_COMPUTE_EXTENDED,
+	METRIC_SET_ID_MEMORY_READS,
+	METRIC_SET_ID_MEMORY_WRITES,
+	METRIC_SET_ID_SAMPLER_BALANCE,
 };
 
-int i915_oa_n_builtin_metric_sets_hsw = 1;
+int i915_oa_n_builtin_metric_sets_hsw = 6;
 
 static const struct i915_oa_reg b_counter_config_render_basic[] = {
 	{ _MMIO(0x2724), 0x00800000 },
@@ -112,6 +117,298 @@  get_render_basic_mux_config(struct drm_i915_private *dev_priv,
 	return mux_config_render_basic;
 }
 
+static const struct i915_oa_reg b_counter_config_compute_basic[] = {
+	{ _MMIO(0x2710), 0x00000000 },
+	{ _MMIO(0x2714), 0x00800000 },
+	{ _MMIO(0x2718), 0xaaaaaaaa },
+	{ _MMIO(0x271c), 0xaaaaaaaa },
+	{ _MMIO(0x2720), 0x00000000 },
+	{ _MMIO(0x2724), 0x00800000 },
+	{ _MMIO(0x2728), 0xaaaaaaaa },
+	{ _MMIO(0x272c), 0xaaaaaaaa },
+	{ _MMIO(0x2740), 0x00000000 },
+	{ _MMIO(0x2744), 0x00000000 },
+	{ _MMIO(0x2748), 0x00000000 },
+	{ _MMIO(0x274c), 0x00000000 },
+	{ _MMIO(0x2750), 0x00000000 },
+	{ _MMIO(0x2754), 0x00000000 },
+	{ _MMIO(0x2758), 0x00000000 },
+	{ _MMIO(0x275c), 0x00000000 },
+	{ _MMIO(0x236c), 0x00000000 },
+};
+
+static const struct i915_oa_reg mux_config_compute_basic[] = {
+	{ _MMIO(0x253a4), 0x00000000 },
+	{ _MMIO(0x2681c), 0x01f00800 },
+	{ _MMIO(0x26820), 0x00001000 },
+	{ _MMIO(0x2781c), 0x01f00800 },
+	{ _MMIO(0x26520), 0x00000007 },
+	{ _MMIO(0x265a0), 0x00000007 },
+	{ _MMIO(0x25380), 0x00000010 },
+	{ _MMIO(0x2538c), 0x00300000 },
+	{ _MMIO(0x25384), 0xaa8aaaaa },
+	{ _MMIO(0x25404), 0xffffffff },
+	{ _MMIO(0x26800), 0x00004202 },
+	{ _MMIO(0x26808), 0x00605817 },
+	{ _MMIO(0x2680c), 0x10001005 },
+	{ _MMIO(0x26804), 0x00000000 },
+	{ _MMIO(0x27800), 0x00000102 },
+	{ _MMIO(0x27808), 0x0c0701e0 },
+	{ _MMIO(0x2780c), 0x000200a0 },
+	{ _MMIO(0x27804), 0x00000000 },
+	{ _MMIO(0x26484), 0x44000000 },
+	{ _MMIO(0x26704), 0x44000000 },
+	{ _MMIO(0x26500), 0x00000006 },
+	{ _MMIO(0x26510), 0x00000001 },
+	{ _MMIO(0x26504), 0x88000000 },
+	{ _MMIO(0x26580), 0x00000006 },
+	{ _MMIO(0x26590), 0x00000020 },
+	{ _MMIO(0x26584), 0x00000000 },
+	{ _MMIO(0x26104), 0x55822222 },
+	{ _MMIO(0x26184), 0xaa866666 },
+	{ _MMIO(0x25420), 0x08320c83 },
+	{ _MMIO(0x25424), 0x06820c83 },
+	{ _MMIO(0x2541c), 0x00000000 },
+	{ _MMIO(0x25428), 0x00000c03 },
+};
+
+static const struct i915_oa_reg *
+get_compute_basic_mux_config(struct drm_i915_private *dev_priv,
+			     int *len)
+{
+	*len = ARRAY_SIZE(mux_config_compute_basic);
+	return mux_config_compute_basic;
+}
+
+static const struct i915_oa_reg b_counter_config_compute_extended[] = {
+	{ _MMIO(0x2724), 0xf0800000 },
+	{ _MMIO(0x2720), 0x00000000 },
+	{ _MMIO(0x2714), 0xf0800000 },
+	{ _MMIO(0x2710), 0x00000000 },
+	{ _MMIO(0x2770), 0x0007fe2a },
+	{ _MMIO(0x2774), 0x0000ff00 },
+	{ _MMIO(0x2778), 0x0007fe6a },
+	{ _MMIO(0x277c), 0x0000ff00 },
+	{ _MMIO(0x2780), 0x0007fe92 },
+	{ _MMIO(0x2784), 0x0000ff00 },
+	{ _MMIO(0x2788), 0x0007fea2 },
+	{ _MMIO(0x278c), 0x0000ff00 },
+	{ _MMIO(0x2790), 0x0007fe32 },
+	{ _MMIO(0x2794), 0x0000ff00 },
+	{ _MMIO(0x2798), 0x0007fe9a },
+	{ _MMIO(0x279c), 0x0000ff00 },
+	{ _MMIO(0x27a0), 0x0007ff23 },
+	{ _MMIO(0x27a4), 0x0000ff00 },
+	{ _MMIO(0x27a8), 0x0007fff3 },
+	{ _MMIO(0x27ac), 0x0000fffe },
+};
+
+static const struct i915_oa_reg mux_config_compute_extended[] = {
+	{ _MMIO(0x2681c), 0x3eb00800 },
+	{ _MMIO(0x26820), 0x00900000 },
+	{ _MMIO(0x25384), 0x02aaaaaa },
+	{ _MMIO(0x25404), 0x03ffffff },
+	{ _MMIO(0x26800), 0x00142284 },
+	{ _MMIO(0x26808), 0x0e629062 },
+	{ _MMIO(0x2680c), 0x3f6f55cb },
+	{ _MMIO(0x26810), 0x00000014 },
+	{ _MMIO(0x26804), 0x00000000 },
+	{ _MMIO(0x26104), 0x02aaaaaa },
+	{ _MMIO(0x26184), 0x02aaaaaa },
+	{ _MMIO(0x25420), 0x00000000 },
+	{ _MMIO(0x25424), 0x00000000 },
+	{ _MMIO(0x2541c), 0x00000000 },
+	{ _MMIO(0x25428), 0x00000000 },
+};
+
+static const struct i915_oa_reg *
+get_compute_extended_mux_config(struct drm_i915_private *dev_priv,
+				int *len)
+{
+	*len = ARRAY_SIZE(mux_config_compute_extended);
+	return mux_config_compute_extended;
+}
+
+static const struct i915_oa_reg b_counter_config_memory_reads[] = {
+	{ _MMIO(0x2724), 0xf0800000 },
+	{ _MMIO(0x2720), 0x00000000 },
+	{ _MMIO(0x2714), 0xf0800000 },
+	{ _MMIO(0x2710), 0x00000000 },
+	{ _MMIO(0x274c), 0x76543298 },
+	{ _MMIO(0x2748), 0x98989898 },
+	{ _MMIO(0x2744), 0x000000e4 },
+	{ _MMIO(0x2740), 0x00000000 },
+	{ _MMIO(0x275c), 0x98a98a98 },
+	{ _MMIO(0x2758), 0x88888888 },
+	{ _MMIO(0x2754), 0x000c5500 },
+	{ _MMIO(0x2750), 0x00000000 },
+	{ _MMIO(0x2770), 0x0007f81a },
+	{ _MMIO(0x2774), 0x0000fc00 },
+	{ _MMIO(0x2778), 0x0007f82a },
+	{ _MMIO(0x277c), 0x0000fc00 },
+	{ _MMIO(0x2780), 0x0007f872 },
+	{ _MMIO(0x2784), 0x0000fc00 },
+	{ _MMIO(0x2788), 0x0007f8ba },
+	{ _MMIO(0x278c), 0x0000fc00 },
+	{ _MMIO(0x2790), 0x0007f87a },
+	{ _MMIO(0x2794), 0x0000fc00 },
+	{ _MMIO(0x2798), 0x0007f8ea },
+	{ _MMIO(0x279c), 0x0000fc00 },
+	{ _MMIO(0x27a0), 0x0007f8e2 },
+	{ _MMIO(0x27a4), 0x0000fc00 },
+	{ _MMIO(0x27a8), 0x0007f8f2 },
+	{ _MMIO(0x27ac), 0x0000fc00 },
+};
+
+static const struct i915_oa_reg mux_config_memory_reads[] = {
+	{ _MMIO(0x253a4), 0x34300000 },
+	{ _MMIO(0x25440), 0x2d800000 },
+	{ _MMIO(0x25444), 0x00000008 },
+	{ _MMIO(0x25128), 0x0e600000 },
+	{ _MMIO(0x25380), 0x00000450 },
+	{ _MMIO(0x25390), 0x00052c43 },
+	{ _MMIO(0x25384), 0x00000000 },
+	{ _MMIO(0x25400), 0x00006144 },
+	{ _MMIO(0x25408), 0x0a418820 },
+	{ _MMIO(0x2540c), 0x000820e6 },
+	{ _MMIO(0x25404), 0xff500000 },
+	{ _MMIO(0x25100), 0x000005d6 },
+	{ _MMIO(0x2510c), 0x0ef00000 },
+	{ _MMIO(0x25104), 0x00000000 },
+	{ _MMIO(0x25420), 0x02108421 },
+	{ _MMIO(0x25424), 0x00008421 },
+	{ _MMIO(0x2541c), 0x00000000 },
+	{ _MMIO(0x25428), 0x00000000 },
+};
+
+static const struct i915_oa_reg *
+get_memory_reads_mux_config(struct drm_i915_private *dev_priv,
+			    int *len)
+{
+	*len = ARRAY_SIZE(mux_config_memory_reads);
+	return mux_config_memory_reads;
+}
+
+static const struct i915_oa_reg b_counter_config_memory_writes[] = {
+	{ _MMIO(0x2724), 0xf0800000 },
+	{ _MMIO(0x2720), 0x00000000 },
+	{ _MMIO(0x2714), 0xf0800000 },
+	{ _MMIO(0x2710), 0x00000000 },
+	{ _MMIO(0x274c), 0x76543298 },
+	{ _MMIO(0x2748), 0x98989898 },
+	{ _MMIO(0x2744), 0x000000e4 },
+	{ _MMIO(0x2740), 0x00000000 },
+	{ _MMIO(0x275c), 0xbabababa },
+	{ _MMIO(0x2758), 0x88888888 },
+	{ _MMIO(0x2754), 0x000c5500 },
+	{ _MMIO(0x2750), 0x00000000 },
+	{ _MMIO(0x2770), 0x0007f81a },
+	{ _MMIO(0x2774), 0x0000fc00 },
+	{ _MMIO(0x2778), 0x0007f82a },
+	{ _MMIO(0x277c), 0x0000fc00 },
+	{ _MMIO(0x2780), 0x0007f822 },
+	{ _MMIO(0x2784), 0x0000fc00 },
+	{ _MMIO(0x2788), 0x0007f8ba },
+	{ _MMIO(0x278c), 0x0000fc00 },
+	{ _MMIO(0x2790), 0x0007f87a },
+	{ _MMIO(0x2794), 0x0000fc00 },
+	{ _MMIO(0x2798), 0x0007f8ea },
+	{ _MMIO(0x279c), 0x0000fc00 },
+	{ _MMIO(0x27a0), 0x0007f8e2 },
+	{ _MMIO(0x27a4), 0x0000fc00 },
+	{ _MMIO(0x27a8), 0x0007f8f2 },
+	{ _MMIO(0x27ac), 0x0000fc00 },
+};
+
+static const struct i915_oa_reg mux_config_memory_writes[] = {
+	{ _MMIO(0x253a4), 0x34300000 },
+	{ _MMIO(0x25440), 0x01500000 },
+	{ _MMIO(0x25444), 0x00000120 },
+	{ _MMIO(0x25128), 0x0c200000 },
+	{ _MMIO(0x25380), 0x00000450 },
+	{ _MMIO(0x25390), 0x00052c43 },
+	{ _MMIO(0x25384), 0x00000000 },
+	{ _MMIO(0x25400), 0x00007184 },
+	{ _MMIO(0x25408), 0x0a418820 },
+	{ _MMIO(0x2540c), 0x000820e6 },
+	{ _MMIO(0x25404), 0xff500000 },
+	{ _MMIO(0x25100), 0x000005d6 },
+	{ _MMIO(0x2510c), 0x1e700000 },
+	{ _MMIO(0x25104), 0x00000000 },
+	{ _MMIO(0x25420), 0x02108421 },
+	{ _MMIO(0x25424), 0x00008421 },
+	{ _MMIO(0x2541c), 0x00000000 },
+	{ _MMIO(0x25428), 0x00000000 },
+};
+
+static const struct i915_oa_reg *
+get_memory_writes_mux_config(struct drm_i915_private *dev_priv,
+			     int *len)
+{
+	*len = ARRAY_SIZE(mux_config_memory_writes);
+	return mux_config_memory_writes;
+}
+
+static const struct i915_oa_reg b_counter_config_sampler_balance[] = {
+	{ _MMIO(0x2740), 0x00000000 },
+	{ _MMIO(0x2744), 0x00800000 },
+	{ _MMIO(0x2710), 0x00000000 },
+	{ _MMIO(0x2714), 0x00800000 },
+	{ _MMIO(0x2720), 0x00000000 },
+	{ _MMIO(0x2724), 0x00800000 },
+};
+
+static const struct i915_oa_reg mux_config_sampler_balance[] = {
+	{ _MMIO(0x2eb9c), 0x01906400 },
+	{ _MMIO(0x2fb9c), 0x01906400 },
+	{ _MMIO(0x253a4), 0x00000000 },
+	{ _MMIO(0x26b9c), 0x01906400 },
+	{ _MMIO(0x27b9c), 0x01906400 },
+	{ _MMIO(0x27104), 0x00a00000 },
+	{ _MMIO(0x27184), 0x00a50000 },
+	{ _MMIO(0x2e804), 0x00500000 },
+	{ _MMIO(0x2e984), 0x00500000 },
+	{ _MMIO(0x2eb04), 0x00500000 },
+	{ _MMIO(0x2eb80), 0x00000084 },
+	{ _MMIO(0x2eb8c), 0x14200000 },
+	{ _MMIO(0x2eb84), 0x00000000 },
+	{ _MMIO(0x2f804), 0x00050000 },
+	{ _MMIO(0x2f984), 0x00050000 },
+	{ _MMIO(0x2fb04), 0x00050000 },
+	{ _MMIO(0x2fb80), 0x00000084 },
+	{ _MMIO(0x2fb8c), 0x00050800 },
+	{ _MMIO(0x2fb84), 0x00000000 },
+	{ _MMIO(0x25380), 0x00000010 },
+	{ _MMIO(0x2538c), 0x000000c0 },
+	{ _MMIO(0x25384), 0xaa550000 },
+	{ _MMIO(0x25404), 0xffffc000 },
+	{ _MMIO(0x26804), 0x50000000 },
+	{ _MMIO(0x26984), 0x50000000 },
+	{ _MMIO(0x26b04), 0x50000000 },
+	{ _MMIO(0x26b80), 0x00000084 },
+	{ _MMIO(0x26b90), 0x00050800 },
+	{ _MMIO(0x26b84), 0x00000000 },
+	{ _MMIO(0x27804), 0x05000000 },
+	{ _MMIO(0x27984), 0x05000000 },
+	{ _MMIO(0x27b04), 0x05000000 },
+	{ _MMIO(0x27b80), 0x00000084 },
+	{ _MMIO(0x27b90), 0x00000142 },
+	{ _MMIO(0x27b84), 0x00000000 },
+	{ _MMIO(0x26104), 0xa0000000 },
+	{ _MMIO(0x26184), 0xa5000000 },
+	{ _MMIO(0x25424), 0x00008620 },
+	{ _MMIO(0x2541c), 0x00000000 },
+	{ _MMIO(0x25428), 0x0004a54a },
+};
+
+static const struct i915_oa_reg *
+get_sampler_balance_mux_config(struct drm_i915_private *dev_priv,
+			       int *len)
+{
+	*len = ARRAY_SIZE(mux_config_sampler_balance);
+	return mux_config_sampler_balance;
+}
+
 int i915_oa_select_metric_set_hsw(struct drm_i915_private *dev_priv)
 {
 	dev_priv->perf.oa.mux_regs = NULL;
@@ -140,6 +437,106 @@  int i915_oa_select_metric_set_hsw(struct drm_i915_private *dev_priv)
 			ARRAY_SIZE(b_counter_config_render_basic);
 
 		return 0;
+	case METRIC_SET_ID_COMPUTE_BASIC:
+		dev_priv->perf.oa.mux_regs =
+			get_compute_basic_mux_config(dev_priv,
+						     &dev_priv->perf.oa.mux_regs_len);
+		if (!dev_priv->perf.oa.mux_regs) {
+			DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_BASIC\" metric set");
+
+			/* EINVAL because *_register_sysfs already checked this
+			 * and so it wouldn't have been advertised so userspace and
+			 * so shouldn't have been requested
+			 */
+			return -EINVAL;
+		}
+
+		dev_priv->perf.oa.b_counter_regs =
+			b_counter_config_compute_basic;
+		dev_priv->perf.oa.b_counter_regs_len =
+			ARRAY_SIZE(b_counter_config_compute_basic);
+
+		return 0;
+	case METRIC_SET_ID_COMPUTE_EXTENDED:
+		dev_priv->perf.oa.mux_regs =
+			get_compute_extended_mux_config(dev_priv,
+							&dev_priv->perf.oa.mux_regs_len);
+		if (!dev_priv->perf.oa.mux_regs) {
+			DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_EXTENDED\" metric set");
+
+			/* EINVAL because *_register_sysfs already checked this
+			 * and so it wouldn't have been advertised so userspace and
+			 * so shouldn't have been requested
+			 */
+			return -EINVAL;
+		}
+
+		dev_priv->perf.oa.b_counter_regs =
+			b_counter_config_compute_extended;
+		dev_priv->perf.oa.b_counter_regs_len =
+			ARRAY_SIZE(b_counter_config_compute_extended);
+
+		return 0;
+	case METRIC_SET_ID_MEMORY_READS:
+		dev_priv->perf.oa.mux_regs =
+			get_memory_reads_mux_config(dev_priv,
+						    &dev_priv->perf.oa.mux_regs_len);
+		if (!dev_priv->perf.oa.mux_regs) {
+			DRM_DEBUG_DRIVER("No suitable MUX config for \"MEMORY_READS\" metric set");
+
+			/* EINVAL because *_register_sysfs already checked this
+			 * and so it wouldn't have been advertised so userspace and
+			 * so shouldn't have been requested
+			 */
+			return -EINVAL;
+		}
+
+		dev_priv->perf.oa.b_counter_regs =
+			b_counter_config_memory_reads;
+		dev_priv->perf.oa.b_counter_regs_len =
+			ARRAY_SIZE(b_counter_config_memory_reads);
+
+		return 0;
+	case METRIC_SET_ID_MEMORY_WRITES:
+		dev_priv->perf.oa.mux_regs =
+			get_memory_writes_mux_config(dev_priv,
+						     &dev_priv->perf.oa.mux_regs_len);
+		if (!dev_priv->perf.oa.mux_regs) {
+			DRM_DEBUG_DRIVER("No suitable MUX config for \"MEMORY_WRITES\" metric set");
+
+			/* EINVAL because *_register_sysfs already checked this
+			 * and so it wouldn't have been advertised so userspace and
+			 * so shouldn't have been requested
+			 */
+			return -EINVAL;
+		}
+
+		dev_priv->perf.oa.b_counter_regs =
+			b_counter_config_memory_writes;
+		dev_priv->perf.oa.b_counter_regs_len =
+			ARRAY_SIZE(b_counter_config_memory_writes);
+
+		return 0;
+	case METRIC_SET_ID_SAMPLER_BALANCE:
+		dev_priv->perf.oa.mux_regs =
+			get_sampler_balance_mux_config(dev_priv,
+						       &dev_priv->perf.oa.mux_regs_len);
+		if (!dev_priv->perf.oa.mux_regs) {
+			DRM_DEBUG_DRIVER("No suitable MUX config for \"SAMPLER_BALANCE\" metric set");
+
+			/* EINVAL because *_register_sysfs already checked this
+			 * and so it wouldn't have been advertised so userspace and
+			 * so shouldn't have been requested
+			 */
+			return -EINVAL;
+		}
+
+		dev_priv->perf.oa.b_counter_regs =
+			b_counter_config_sampler_balance;
+		dev_priv->perf.oa.b_counter_regs_len =
+			ARRAY_SIZE(b_counter_config_sampler_balance);
+
+		return 0;
 	default:
 		return -ENODEV;
 	}
@@ -167,6 +564,116 @@  static struct attribute_group group_render_basic = {
 	.attrs =  attrs_render_basic,
 };
 
+static ssize_t
+show_compute_basic_id(struct device *kdev, struct device_attribute *attr, char *buf)
+{
+	return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_BASIC);
+}
+
+static struct device_attribute dev_attr_compute_basic_id = {
+	.attr = { .name = "id", .mode = 0444 },
+	.show = show_compute_basic_id,
+	.store = NULL,
+};
+
+static struct attribute *attrs_compute_basic[] = {
+	&dev_attr_compute_basic_id.attr,
+	NULL,
+};
+
+static struct attribute_group group_compute_basic = {
+	.name = "39ad14bc-2380-45c4-91eb-fbcb3aa7ae7b",
+	.attrs =  attrs_compute_basic,
+};
+
+static ssize_t
+show_compute_extended_id(struct device *kdev, struct device_attribute *attr, char *buf)
+{
+	return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_EXTENDED);
+}
+
+static struct device_attribute dev_attr_compute_extended_id = {
+	.attr = { .name = "id", .mode = 0444 },
+	.show = show_compute_extended_id,
+	.store = NULL,
+};
+
+static struct attribute *attrs_compute_extended[] = {
+	&dev_attr_compute_extended_id.attr,
+	NULL,
+};
+
+static struct attribute_group group_compute_extended = {
+	.name = "3865be28-6982-49fe-9494-e4d1b4795413",
+	.attrs =  attrs_compute_extended,
+};
+
+static ssize_t
+show_memory_reads_id(struct device *kdev, struct device_attribute *attr, char *buf)
+{
+	return sprintf(buf, "%d\n", METRIC_SET_ID_MEMORY_READS);
+}
+
+static struct device_attribute dev_attr_memory_reads_id = {
+	.attr = { .name = "id", .mode = 0444 },
+	.show = show_memory_reads_id,
+	.store = NULL,
+};
+
+static struct attribute *attrs_memory_reads[] = {
+	&dev_attr_memory_reads_id.attr,
+	NULL,
+};
+
+static struct attribute_group group_memory_reads = {
+	.name = "bb5ed49b-2497-4095-94f6-26ba294db88a",
+	.attrs =  attrs_memory_reads,
+};
+
+static ssize_t
+show_memory_writes_id(struct device *kdev, struct device_attribute *attr, char *buf)
+{
+	return sprintf(buf, "%d\n", METRIC_SET_ID_MEMORY_WRITES);
+}
+
+static struct device_attribute dev_attr_memory_writes_id = {
+	.attr = { .name = "id", .mode = 0444 },
+	.show = show_memory_writes_id,
+	.store = NULL,
+};
+
+static struct attribute *attrs_memory_writes[] = {
+	&dev_attr_memory_writes_id.attr,
+	NULL,
+};
+
+static struct attribute_group group_memory_writes = {
+	.name = "3358d639-9b5f-45ab-976d-9b08cbfc6240",
+	.attrs =  attrs_memory_writes,
+};
+
+static ssize_t
+show_sampler_balance_id(struct device *kdev, struct device_attribute *attr, char *buf)
+{
+	return sprintf(buf, "%d\n", METRIC_SET_ID_SAMPLER_BALANCE);
+}
+
+static struct device_attribute dev_attr_sampler_balance_id = {
+	.attr = { .name = "id", .mode = 0444 },
+	.show = show_sampler_balance_id,
+	.store = NULL,
+};
+
+static struct attribute *attrs_sampler_balance[] = {
+	&dev_attr_sampler_balance_id.attr,
+	NULL,
+};
+
+static struct attribute_group group_sampler_balance = {
+	.name = "bc274488-b4b6-40c7-90da-b77d7ad16189",
+	.attrs =  attrs_sampler_balance,
+};
+
 int
 i915_perf_register_sysfs_hsw(struct drm_i915_private *dev_priv)
 {
@@ -178,9 +685,49 @@  i915_perf_register_sysfs_hsw(struct drm_i915_private *dev_priv)
 		if (ret)
 			goto error_render_basic;
 	}
+	if (get_compute_basic_mux_config(dev_priv, &mux_len)) {
+		ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_basic);
+		if (ret)
+			goto error_compute_basic;
+	}
+	if (get_compute_extended_mux_config(dev_priv, &mux_len)) {
+		ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_extended);
+		if (ret)
+			goto error_compute_extended;
+	}
+	if (get_memory_reads_mux_config(dev_priv, &mux_len)) {
+		ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_memory_reads);
+		if (ret)
+			goto error_memory_reads;
+	}
+	if (get_memory_writes_mux_config(dev_priv, &mux_len)) {
+		ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_memory_writes);
+		if (ret)
+			goto error_memory_writes;
+	}
+	if (get_sampler_balance_mux_config(dev_priv, &mux_len)) {
+		ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_sampler_balance);
+		if (ret)
+			goto error_sampler_balance;
+	}
 
 	return 0;
 
+error_sampler_balance:
+	if (get_sampler_balance_mux_config(dev_priv, &mux_len))
+		sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_writes);
+error_memory_writes:
+	if (get_sampler_balance_mux_config(dev_priv, &mux_len))
+		sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_reads);
+error_memory_reads:
+	if (get_sampler_balance_mux_config(dev_priv, &mux_len))
+		sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extended);
+error_compute_extended:
+	if (get_sampler_balance_mux_config(dev_priv, &mux_len))
+		sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_basic);
+error_compute_basic:
+	if (get_sampler_balance_mux_config(dev_priv, &mux_len))
+		sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_basic);
 error_render_basic:
 	return ret;
 }
@@ -192,4 +739,14 @@  i915_perf_unregister_sysfs_hsw(struct drm_i915_private *dev_priv)
 
 	if (get_render_basic_mux_config(dev_priv, &mux_len))
 		sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_basic);
+	if (get_compute_basic_mux_config(dev_priv, &mux_len))
+		sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_basic);
+	if (get_compute_extended_mux_config(dev_priv, &mux_len))
+		sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extended);
+	if (get_memory_reads_mux_config(dev_priv, &mux_len))
+		sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_reads);
+	if (get_memory_writes_mux_config(dev_priv, &mux_len))
+		sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_writes);
+	if (get_sampler_balance_mux_config(dev_priv, &mux_len))
+		sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_sampler_balance);
 }