diff mbox series

i915/guc/slpc: Provide sysfs for efficient freq

Message ID 20230401020049.3843873-1-vinay.belgaumkar@intel.com (mailing list archive)
State New, archived
Headers show
Series i915/guc/slpc: Provide sysfs for efficient freq | expand

Commit Message

Vinay Belgaumkar April 1, 2023, 2 a.m. UTC
SLPC enables use of efficient freq at init by default. It is
possible for GuC to request frequencies that are higher than
the 'software' max if user has set it lower than the efficient
level.

Scenarios/tests that require strict fixing of freq below the efficient
level will need to disable it through this interface. Another way
to disable it is to set min frequency below the efficient level.

Signed-off-by: Vinay Belgaumkar <vinay.belgaumkar@intel.com>
---
 drivers/gpu/drm/i915/gt/intel_gt_sysfs_pm.c   | 35 +++++++++++++
 drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c   | 49 ++++++++++++++-----
 drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.h   |  1 +
 .../gpu/drm/i915/gt/uc/intel_guc_slpc_types.h |  1 +
 4 files changed, 75 insertions(+), 11 deletions(-)

Comments

Dixit, Ashutosh April 1, 2023, 3:11 a.m. UTC | #1
On Fri, 31 Mar 2023 19:00:49 -0700, Vinay Belgaumkar wrote:
>

Hi Vinay,

> @@ -478,20 +507,15 @@ int intel_guc_slpc_set_min_freq(struct intel_guc_slpc *slpc, u32 val)
>	    val > slpc->max_freq_softlimit)
>		return -EINVAL;
>
> +	/* Ignore efficient freq if lower min freq is requested */
> +	ret = intel_guc_slpc_set_ignore_eff_freq(slpc, val < slpc->rp1_freq);
> +	if (ret)
> +		goto out;
> +

I don't agree with this. If we are now providing an interface explicitly to
ignore RPe, that should be /only/ way to ignore RPe. There should be no
other "under the hood" ignoring of RPe. In other words, ignoring RPe should
be minimized unless explicitly requested.

I don't clearly understand why this was done previously but it makes even
less sense to me now after this patch.

Thanks.
--
Ashutosh


>	/* Need a lock now since waitboost can be modifying min as well */
>	mutex_lock(&slpc->lock);
>	wakeref = intel_runtime_pm_get(&i915->runtime_pm);
>
> -	/* Ignore efficient freq if lower min freq is requested */
> -	ret = slpc_set_param(slpc,
> -			     SLPC_PARAM_IGNORE_EFFICIENT_FREQUENCY,
> -			     val < slpc->rp1_freq);
> -	if (ret) {
> -		guc_probe_error(slpc_to_guc(slpc), "Failed to toggle efficient freq: %pe\n",
> -				ERR_PTR(ret));
> -		goto out;
> -	}
> -
>	ret = slpc_set_param(slpc,
>			     SLPC_PARAM_GLOBAL_MIN_GT_UNSLICE_FREQ_MHZ,
>			     val);
Rodrigo Vivi April 5, 2023, 1:57 p.m. UTC | #2
On Fri, Mar 31, 2023 at 08:11:29PM -0700, Dixit, Ashutosh wrote:
> On Fri, 31 Mar 2023 19:00:49 -0700, Vinay Belgaumkar wrote:
> >
> 
> Hi Vinay,
> 
> > @@ -478,20 +507,15 @@ int intel_guc_slpc_set_min_freq(struct intel_guc_slpc *slpc, u32 val)
> >	    val > slpc->max_freq_softlimit)
> >		return -EINVAL;
> >
> > +	/* Ignore efficient freq if lower min freq is requested */
> > +	ret = intel_guc_slpc_set_ignore_eff_freq(slpc, val < slpc->rp1_freq);
> > +	if (ret)
> > +		goto out;
> > +
> 
> I don't agree with this. If we are now providing an interface explicitly to
> ignore RPe, that should be /only/ way to ignore RPe. There should be no
> other "under the hood" ignoring of RPe. In other words, ignoring RPe should
> be minimized unless explicitly requested.
> 
> I don't clearly understand why this was done previously but it makes even
> less sense to me now after this patch.

well, I had suggested this previously. And just because without this we would
be breaking API expectations.

When user selects a minimal frequency it expect that to stick. But with the
efficient freq enabled in guc if minimal is less than the efficient one,
this request is likely ignored.

Well, even worse is that we are actually caching the request in the soft values.
So we show a minimal, but the hardware without any workload is operating at
efficient.

So, the thought process was: 'if user requested a very low minimal, we give them
the minimal requested, even if that means to disable the efficient freq.'

So, that was introduced to avoid API breakage. Removing it now would mean
breaking API. (Not sure if the IGT tests for the API got merged already,
but think that as the API contract).

But I do agree with you that having something selected from multiple places
also has the potential to cause some miss-expectations. So I was thinking
about multiple even orders where the user select the RP0 as minimal, then
enable the efficient or vice versa, but I couldn't think of a bad case.
Or at least not as bad as the user asking to get RP0 as minimal and only
getting RPe back.

With this in mind, and having checked the code:

Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>

But I won't push this immediately because I'm still open to hear another
side/angle.

> 
> Thanks.
> --
> Ashutosh
> 
> 
> >	/* Need a lock now since waitboost can be modifying min as well */
> >	mutex_lock(&slpc->lock);
> >	wakeref = intel_runtime_pm_get(&i915->runtime_pm);
> >
> > -	/* Ignore efficient freq if lower min freq is requested */
> > -	ret = slpc_set_param(slpc,
> > -			     SLPC_PARAM_IGNORE_EFFICIENT_FREQUENCY,
> > -			     val < slpc->rp1_freq);
> > -	if (ret) {
> > -		guc_probe_error(slpc_to_guc(slpc), "Failed to toggle efficient freq: %pe\n",
> > -				ERR_PTR(ret));
> > -		goto out;
> > -	}
> > -
> >	ret = slpc_set_param(slpc,
> >			     SLPC_PARAM_GLOBAL_MIN_GT_UNSLICE_FREQ_MHZ,
> >			     val);
Dixit, Ashutosh April 5, 2023, 7:42 p.m. UTC | #3
On Wed, 05 Apr 2023 06:57:42 -0700, Rodrigo Vivi wrote:
>

Hi Rodrigo,

> On Fri, Mar 31, 2023 at 08:11:29PM -0700, Dixit, Ashutosh wrote:
> > On Fri, 31 Mar 2023 19:00:49 -0700, Vinay Belgaumkar wrote:
> > >
> >
> > Hi Vinay,
> >
> > > @@ -478,20 +507,15 @@ int intel_guc_slpc_set_min_freq(struct intel_guc_slpc *slpc, u32 val)
> > >	    val > slpc->max_freq_softlimit)
> > >		return -EINVAL;
> > >
> > > +	/* Ignore efficient freq if lower min freq is requested */
> > > +	ret = intel_guc_slpc_set_ignore_eff_freq(slpc, val < slpc->rp1_freq);
> > > +	if (ret)
> > > +		goto out;
> > > +
> >
> > I don't agree with this. If we are now providing an interface explicitly to
> > ignore RPe, that should be /only/ way to ignore RPe. There should be no
> > other "under the hood" ignoring of RPe. In other words, ignoring RPe should
> > be minimized unless explicitly requested.
> >
> > I don't clearly understand why this was done previously but it makes even
> > less sense to me now after this patch.
>
> well, I had suggested this previously. And just because without this we would
> be breaking API expectations.
>
> When user selects a minimal frequency it expect that to stick. But with the
> efficient freq enabled in guc if minimal is less than the efficient one,
> this request is likely ignored.
>
> Well, even worse is that we are actually caching the request in the soft values.
> So we show a minimal, but the hardware without any workload is operating at
> efficient.
>
> So, the thought process was: 'if user requested a very low minimal, we give them
> the minimal requested, even if that means to disable the efficient freq.'

Hmm, I understand this even less now :)

* Why is RPe ignored when min < RPe? Since the freq can be between min and
  max? Shouldn't the condition be min > RPe, that is turn RPe off if min
  higher that RPe is requested?

* Also isn't RPe dynamic, so we can't say RPe == rp1 when using in KMD?

* Finally, we know that enabling RPe broke the kernel freq API because RPe
  could go over max_freq. So it is actually the max freq which is not
  obeyed after RPe is enabled.

So we ignore RPe in some select cases (which also I don't understand as
mentioned above but maybe I am missing something) to claim that we are
obeying the freq API, but let the freq API stay broken in other cases?

> So, that was introduced to avoid API breakage. Removing it now would mean
> breaking API. (Not sure if the IGT tests for the API got merged already,
> but think that as the API contract).

I think we should take this patch as an opportunity to fix this and give
the user a clean interface to ignore RPe and remove this other implicit way
to ignore RPe. All IGT changes are unmerged at present.

Thanks.
--
Ashutosh



>
> But I do agree with you that having something selected from multiple places
> also has the potential to cause some miss-expectations. So I was thinking
> about multiple even orders where the user select the RP0 as minimal, then
> enable the efficient or vice versa, but I couldn't think of a bad case.
> Or at least not as bad as the user asking to get RP0 as minimal and only
> getting RPe back.
>
> With this in mind, and having checked the code:
>
> Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
>
> But I won't push this immediately because I'm still open to hear another
> side/angle.
>
> >
> > Thanks.
> > --
> > Ashutosh
> >
> >
> > >	/* Need a lock now since waitboost can be modifying min as well */
> > >	mutex_lock(&slpc->lock);
> > >	wakeref = intel_runtime_pm_get(&i915->runtime_pm);
> > >
> > > -	/* Ignore efficient freq if lower min freq is requested */
> > > -	ret = slpc_set_param(slpc,
> > > -			     SLPC_PARAM_IGNORE_EFFICIENT_FREQUENCY,
> > > -			     val < slpc->rp1_freq);
> > > -	if (ret) {
> > > -		guc_probe_error(slpc_to_guc(slpc), "Failed to toggle efficient freq: %pe\n",
> > > -				ERR_PTR(ret));
> > > -		goto out;
> > > -	}
> > > -
> > >	ret = slpc_set_param(slpc,
> > >			     SLPC_PARAM_GLOBAL_MIN_GT_UNSLICE_FREQ_MHZ,
> > >			     val);
Rodrigo Vivi April 5, 2023, 8:12 p.m. UTC | #4
On Wed, Apr 05, 2023 at 12:42:30PM -0700, Dixit, Ashutosh wrote:
> On Wed, 05 Apr 2023 06:57:42 -0700, Rodrigo Vivi wrote:
> >
> 
> Hi Rodrigo,
> 
> > On Fri, Mar 31, 2023 at 08:11:29PM -0700, Dixit, Ashutosh wrote:
> > > On Fri, 31 Mar 2023 19:00:49 -0700, Vinay Belgaumkar wrote:
> > > >
> > >
> > > Hi Vinay,
> > >
> > > > @@ -478,20 +507,15 @@ int intel_guc_slpc_set_min_freq(struct intel_guc_slpc *slpc, u32 val)
> > > >	    val > slpc->max_freq_softlimit)
> > > >		return -EINVAL;
> > > >
> > > > +	/* Ignore efficient freq if lower min freq is requested */
> > > > +	ret = intel_guc_slpc_set_ignore_eff_freq(slpc, val < slpc->rp1_freq);
> > > > +	if (ret)
> > > > +		goto out;
> > > > +
> > >
> > > I don't agree with this. If we are now providing an interface explicitly to
> > > ignore RPe, that should be /only/ way to ignore RPe. There should be no
> > > other "under the hood" ignoring of RPe. In other words, ignoring RPe should
> > > be minimized unless explicitly requested.
> > >
> > > I don't clearly understand why this was done previously but it makes even
> > > less sense to me now after this patch.
> >
> > well, I had suggested this previously. And just because without this we would
> > be breaking API expectations.
> >
> > When user selects a minimal frequency it expect that to stick. But with the
> > efficient freq enabled in guc if minimal is less than the efficient one,
> > this request is likely ignored.
> >
> > Well, even worse is that we are actually caching the request in the soft values.
> > So we show a minimal, but the hardware without any workload is operating at
> > efficient.
> >
> > So, the thought process was: 'if user requested a very low minimal, we give them
> > the minimal requested, even if that means to disable the efficient freq.'
> 
> Hmm, I understand this even less now :)
> 
> * Why is RPe ignored when min < RPe? Since the freq can be between min and
>   max? Shouldn't the condition be min > RPe, that is turn RPe off if min
>   higher that RPe is requested?

that is not how guc efficient freq selection works. (unless my memory is
tricking me right now.)

So, if we select a min that is between RPe and RP0, guc will respect and
use the selected min. So we don't need to disable guc selection of the
efficient.

This is not true when we select a very low min like RPn. If we select RPn
as min and guc efficient freq selection is enabled guc will simply ignore
our request. So the only way to give the user what is asked, is to also
disable guc's efficient freq selection. (I probably confused you in the
previous email because I used 'RP0' when I meant 'RPn'. I hope it gets
clear now).

> 
> * Also isn't RPe dynamic, so we can't say RPe == rp1 when using in KMD?

Oh... yeap, this is an issue indeed. Specially with i915 where we have
the soft values cached instead of asking guc everytime.

That's a good point. The variance is not big, but we will hit corner cases.
One way is to keep checking and updating everytime a sysfs is touched.
Other way is do what you are suggesting and let's just accept and deal
with the reality that is: "we cannot guarantee a min freq selection if user
doesn't disable the efficient freq selection".

> 
> * Finally, we know that enabling RPe broke the kernel freq API because RPe
>   could go over max_freq. So it is actually the max freq which is not
>   obeyed after RPe is enabled.

Oh! so it was my bad memory indeed and everything is the other way around?
But I just looked to Xe code, my most recent memory, and I just needed
to toggle the efficient freq off on the case that I mentioned, when min
selection is below the efficient one. With that all the API expectation
that I coded in IGT works neatly.

> 
> So we ignore RPe in some select cases (which also I don't understand as
> mentioned above but maybe I am missing something) to claim that we are
> obeying the freq API, but let the freq API stay broken in other cases?

what cases it stays broken? This is why we need the IGT tests for all the
API behavior in place.

> 
> > So, that was introduced to avoid API breakage. Removing it now would mean
> > breaking API. (Not sure if the IGT tests for the API got merged already,
> > but think that as the API contract).
> 
> I think we should take this patch as an opportunity to fix this and give
> the user a clean interface to ignore RPe and remove this other implicit way
> to ignore RPe. All IGT changes are unmerged at present.

Yeap, the IGT needs to come with whatever we concluded here and we need to
stick with that afterwards, so let's think with care.

Vinay, Ashutosh's strongest argument is the variable RPe. Do you have thoughts
on that?

> 
> Thanks.
> --
> Ashutosh
> 
> 
> 
> >
> > But I do agree with you that having something selected from multiple places
> > also has the potential to cause some miss-expectations. So I was thinking
> > about multiple even orders where the user select the RP0 as minimal, then
> > enable the efficient or vice versa, but I couldn't think of a bad case.
> > Or at least not as bad as the user asking to get RP0 as minimal and only
> > getting RPe back.

in case I let you confused here, what I meant was RPn, not RP0.

> >
> > With this in mind, and having checked the code:
> >
> > Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
> >
> > But I won't push this immediately because I'm still open to hear another
> > side/angle.
> >
> > >
> > > Thanks.
> > > --
> > > Ashutosh
> > >
> > >
> > > >	/* Need a lock now since waitboost can be modifying min as well */
> > > >	mutex_lock(&slpc->lock);
> > > >	wakeref = intel_runtime_pm_get(&i915->runtime_pm);
> > > >
> > > > -	/* Ignore efficient freq if lower min freq is requested */
> > > > -	ret = slpc_set_param(slpc,
> > > > -			     SLPC_PARAM_IGNORE_EFFICIENT_FREQUENCY,
> > > > -			     val < slpc->rp1_freq);
> > > > -	if (ret) {
> > > > -		guc_probe_error(slpc_to_guc(slpc), "Failed to toggle efficient freq: %pe\n",
> > > > -				ERR_PTR(ret));
> > > > -		goto out;
> > > > -	}
> > > > -
> > > >	ret = slpc_set_param(slpc,
> > > >			     SLPC_PARAM_GLOBAL_MIN_GT_UNSLICE_FREQ_MHZ,
> > > >			     val);
Dixit, Ashutosh April 6, 2023, 5:08 a.m. UTC | #5
On Wed, 05 Apr 2023 13:12:29 -0700, Rodrigo Vivi wrote:
>
> On Wed, Apr 05, 2023 at 12:42:30PM -0700, Dixit, Ashutosh wrote:
> > On Wed, 05 Apr 2023 06:57:42 -0700, Rodrigo Vivi wrote:
> > >

Hi Rodrigo,

> >
> > > On Fri, Mar 31, 2023 at 08:11:29PM -0700, Dixit, Ashutosh wrote:
> > > > On Fri, 31 Mar 2023 19:00:49 -0700, Vinay Belgaumkar wrote:
> > > > >
> > > >
> > > > Hi Vinay,
> > > >
> > > > > @@ -478,20 +507,15 @@ int intel_guc_slpc_set_min_freq(struct intel_guc_slpc *slpc, u32 val)
> > > > >	    val > slpc->max_freq_softlimit)
> > > > >		return -EINVAL;
> > > > >
> > > > > +	/* Ignore efficient freq if lower min freq is requested */
> > > > > +	ret = intel_guc_slpc_set_ignore_eff_freq(slpc, val < slpc->rp1_freq);
> > > > > +	if (ret)
> > > > > +		goto out;
> > > > > +
> > > >
> > > > I don't agree with this. If we are now providing an interface explicitly to
> > > > ignore RPe, that should be /only/ way to ignore RPe. There should be no
> > > > other "under the hood" ignoring of RPe. In other words, ignoring RPe should
> > > > be minimized unless explicitly requested.
> > > >
> > > > I don't clearly understand why this was done previously but it makes even
> > > > less sense to me now after this patch.
> > >
> > > well, I had suggested this previously. And just because without this we would
> > > be breaking API expectations.
> > >
> > > When user selects a minimal frequency it expect that to stick. But with the
> > > efficient freq enabled in guc if minimal is less than the efficient one,
> > > this request is likely ignored.
> > >
> > > Well, even worse is that we are actually caching the request in the soft values.
> > > So we show a minimal, but the hardware without any workload is operating at
> > > efficient.
> > >
> > > So, the thought process was: 'if user requested a very low minimal, we give them
> > > the minimal requested, even if that means to disable the efficient freq.'
> >
> > Hmm, I understand this even less now :)
> >
> > * Why is RPe ignored when min < RPe? Since the freq can be between min and
> >   max? Shouldn't the condition be min > RPe, that is turn RPe off if min
> >   higher that RPe is requested?
>
> that is not how guc efficient freq selection works. (unless my memory is
> tricking me right now.)
>
> So, if we select a min that is between RPe and RP0, guc will respect and
> use the selected min. So we don't need to disable guc selection of the
> efficient.
>
> This is not true when we select a very low min like RPn. If we select RPn
> as min and guc efficient freq selection is enabled guc will simply ignore
> our request. So the only way to give the user what is asked, is to also
> disable guc's efficient freq selection. (I probably confused you in the
> previous email because I used 'RP0' when I meant 'RPn'. I hope it gets
> clear now).
>
> >
> > * Also isn't RPe dynamic, so we can't say RPe == rp1 when using in KMD?
>
> Oh... yeap, this is an issue indeed. Specially with i915 where we have
> the soft values cached instead of asking guc everytime.
>
> That's a good point. The variance is not big, but we will hit corner cases.
> One way is to keep checking and updating everytime a sysfs is touched.

This I believe not possible in all cases. Say the freq's are set through
sysfs first and the workload starts later. In this case RPe will probably
start changing after the workload starts, not when freq's are set in sysfs.

> Other way is do what you are suggesting and let's just accept and deal
> with the reality that is: "we cannot guarantee a min freq selection if user
> doesn't disable the efficient freq selection".
>
> >
> > * Finally, we know that enabling RPe broke the kernel freq API because RPe
> >   could go over max_freq. So it is actually the max freq which is not
> >   obeyed after RPe is enabled.
>
> Oh! so it was my bad memory indeed and everything is the other way around?
> But I just looked to Xe code, my most recent memory, and I just needed
> to toggle the efficient freq off on the case that I mentioned, when min
> selection is below the efficient one. With that all the API expectation
> that I coded in IGT works neatly.

From what I saw the following bugs:

https://gitlab.freedesktop.org/drm/intel/-/issues/6806
https://gitlab.freedesktop.org/drm/intel/-/issues/6786

and the following patches in response to these bugs (as well as the
discussion on these patches):

https://patchwork.freedesktop.org/series/111282/
https://patchwork.freedesktop.org/series/110574/

were all due to the fact that the max freq is not obeyed after RPe is
enabled.

These patches were never merged but I will now try to submit them again
after this ignore efficient freq patch gets reviewed and merged.

Thanks.
--
Ashutosh

> >
> > So we ignore RPe in some select cases (which also I don't understand as
> > mentioned above but maybe I am missing something) to claim that we are
> > obeying the freq API, but let the freq API stay broken in other cases?
>
> what cases it stays broken? This is why we need the IGT tests for all the
> API behavior in place.
>
> > > So, that was introduced to avoid API breakage. Removing it now would mean
> > > breaking API. (Not sure if the IGT tests for the API got merged already,
> > > but think that as the API contract).
> >
> > I think we should take this patch as an opportunity to fix this and give
> > the user a clean interface to ignore RPe and remove this other implicit way
> > to ignore RPe. All IGT changes are unmerged at present.
>
> Yeap, the IGT needs to come with whatever we concluded here and we need to
> stick with that afterwards, so let's think with care.
>
> Vinay, Ashutosh's strongest argument is the variable RPe. Do you have thoughts
> on that?
>
> >
> > Thanks.
> > --
> > Ashutosh
> >
> >
> >
> > >
> > > But I do agree with you that having something selected from multiple places
> > > also has the potential to cause some miss-expectations. So I was thinking
> > > about multiple even orders where the user select the RP0 as minimal, then
> > > enable the efficient or vice versa, but I couldn't think of a bad case.
> > > Or at least not as bad as the user asking to get RP0 as minimal and only
> > > getting RPe back.
>
> in case I let you confused here, what I meant was RPn, not RP0.
>
> > >
> > > With this in mind, and having checked the code:
> > >
> > > Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
> > >
> > > But I won't push this immediately because I'm still open to hear another
> > > side/angle.
> > >
> > > >
> > > > Thanks.
> > > > --
> > > > Ashutosh
> > > >
> > > >
> > > > >	/* Need a lock now since waitboost can be modifying min as well */
> > > > >	mutex_lock(&slpc->lock);
> > > > >	wakeref = intel_runtime_pm_get(&i915->runtime_pm);
> > > > >
> > > > > -	/* Ignore efficient freq if lower min freq is requested */
> > > > > -	ret = slpc_set_param(slpc,
> > > > > -			     SLPC_PARAM_IGNORE_EFFICIENT_FREQUENCY,
> > > > > -			     val < slpc->rp1_freq);
> > > > > -	if (ret) {
> > > > > -		guc_probe_error(slpc_to_guc(slpc), "Failed to toggle efficient freq: %pe\n",
> > > > > -				ERR_PTR(ret));
> > > > > -		goto out;
> > > > > -	}
> > > > > -
> > > > >	ret = slpc_set_param(slpc,
> > > > >			     SLPC_PARAM_GLOBAL_MIN_GT_UNSLICE_FREQ_MHZ,
> > > > >			     val);
diff mbox series

Patch

diff --git a/drivers/gpu/drm/i915/gt/intel_gt_sysfs_pm.c b/drivers/gpu/drm/i915/gt/intel_gt_sysfs_pm.c
index 28f27091cd3b..7496de5be580 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_sysfs_pm.c
+++ b/drivers/gpu/drm/i915/gt/intel_gt_sysfs_pm.c
@@ -451,6 +451,33 @@  static ssize_t punit_req_freq_mhz_show(struct kobject *kobj,
 	return sysfs_emit(buff, "%u\n", preq);
 }
 
+static ssize_t slpc_ignore_eff_freq_show(struct kobject *kobj,
+				     struct kobj_attribute *attr,
+				     char *buff)
+{
+	struct intel_gt *gt = intel_gt_sysfs_get_drvdata(kobj, attr->attr.name);
+	struct intel_guc_slpc *slpc = &gt->uc.guc.slpc;
+
+	return sysfs_emit(buff, "%u\n", slpc->ignore_eff_freq);
+}
+
+static ssize_t slpc_ignore_eff_freq_store(struct kobject *kobj,
+					  struct kobj_attribute *attr,
+					  const char *buff, size_t count)
+{
+	struct intel_gt *gt = intel_gt_sysfs_get_drvdata(kobj, attr->attr.name);
+	struct intel_guc_slpc *slpc = &gt->uc.guc.slpc;
+	int err;
+	uint32_t val;
+
+	err = kstrtou32(buff, 0, &val);
+	if (err)
+		return err;
+
+	err = intel_guc_slpc_set_ignore_eff_freq(slpc, val);
+	return err ?: count;
+}
+
 struct intel_gt_bool_throttle_attr {
 	struct attribute attr;
 	ssize_t (*show)(struct kobject *kobj, struct kobj_attribute *attr,
@@ -663,6 +690,8 @@  static struct kobj_attribute attr_media_freq_factor_scale =
 INTEL_GT_ATTR_RO(media_RP0_freq_mhz);
 INTEL_GT_ATTR_RO(media_RPn_freq_mhz);
 
+INTEL_GT_ATTR_RW(slpc_ignore_eff_freq);
+
 static const struct attribute *media_perf_power_attrs[] = {
 	&attr_media_freq_factor.attr,
 	&attr_media_freq_factor_scale.attr,
@@ -744,6 +773,12 @@  void intel_gt_sysfs_pm_init(struct intel_gt *gt, struct kobject *kobj)
 	if (ret)
 		gt_warn(gt, "failed to create punit_req_freq_mhz sysfs (%pe)", ERR_PTR(ret));
 
+	if (intel_uc_uses_guc_slpc(&gt->uc)) {
+		ret = sysfs_create_file(kobj, &attr_slpc_ignore_eff_freq.attr);
+		if (ret)
+			gt_warn(gt, "failed to create ignore_eff_freq sysfs (%pe)", ERR_PTR(ret));
+	}
+
 	if (i915_mmio_reg_valid(intel_gt_perf_limit_reasons_reg(gt))) {
 		ret = sysfs_create_files(kobj, throttle_reason_attrs);
 		if (ret)
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c
index 026d73855f36..eaa73c1fba6d 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c
@@ -277,6 +277,7 @@  int intel_guc_slpc_init(struct intel_guc_slpc *slpc)
 
 	slpc->max_freq_softlimit = 0;
 	slpc->min_freq_softlimit = 0;
+	slpc->ignore_eff_freq = false;
 	slpc->min_is_rpmax = false;
 
 	slpc->boost_freq = 0;
@@ -457,6 +458,34 @@  int intel_guc_slpc_get_max_freq(struct intel_guc_slpc *slpc, u32 *val)
 	return ret;
 }
 
+int intel_guc_slpc_set_ignore_eff_freq(struct intel_guc_slpc *slpc, bool val)
+{
+	struct drm_i915_private *i915 = slpc_to_i915(slpc);
+	intel_wakeref_t wakeref;
+	int ret = 0;
+
+	/* Need a lock now since waitboost can be modifying min as well */
+	mutex_lock(&slpc->lock);
+	wakeref = intel_runtime_pm_get(&i915->runtime_pm);
+
+	/* Ignore efficient freq if lower min freq is requested */
+	ret = slpc_set_param(slpc,
+			     SLPC_PARAM_IGNORE_EFFICIENT_FREQUENCY,
+			     val);
+	if (ret) {
+		guc_probe_error(slpc_to_guc(slpc), "Failed to set efficient freq(%d): %pe\n",
+				val, ERR_PTR(ret));
+		goto out;
+	}
+
+	slpc->ignore_eff_freq = val;
+
+out:
+	intel_runtime_pm_put(&i915->runtime_pm, wakeref);
+	mutex_unlock(&slpc->lock);
+	return ret;
+}
+
 /**
  * intel_guc_slpc_set_min_freq() - Set min frequency limit for SLPC.
  * @slpc: pointer to intel_guc_slpc.
@@ -478,20 +507,15 @@  int intel_guc_slpc_set_min_freq(struct intel_guc_slpc *slpc, u32 val)
 	    val > slpc->max_freq_softlimit)
 		return -EINVAL;
 
+	/* Ignore efficient freq if lower min freq is requested */
+	ret = intel_guc_slpc_set_ignore_eff_freq(slpc, val < slpc->rp1_freq);
+	if (ret)
+		goto out;
+
 	/* Need a lock now since waitboost can be modifying min as well */
 	mutex_lock(&slpc->lock);
 	wakeref = intel_runtime_pm_get(&i915->runtime_pm);
 
-	/* Ignore efficient freq if lower min freq is requested */
-	ret = slpc_set_param(slpc,
-			     SLPC_PARAM_IGNORE_EFFICIENT_FREQUENCY,
-			     val < slpc->rp1_freq);
-	if (ret) {
-		guc_probe_error(slpc_to_guc(slpc), "Failed to toggle efficient freq: %pe\n",
-				ERR_PTR(ret));
-		goto out;
-	}
-
 	ret = slpc_set_param(slpc,
 			     SLPC_PARAM_GLOBAL_MIN_GT_UNSLICE_FREQ_MHZ,
 			     val);
@@ -499,10 +523,10 @@  int intel_guc_slpc_set_min_freq(struct intel_guc_slpc *slpc, u32 val)
 	if (!ret)
 		slpc->min_freq_softlimit = val;
 
-out:
 	intel_runtime_pm_put(&i915->runtime_pm, wakeref);
 	mutex_unlock(&slpc->lock);
 
+out:
 	/* Return standardized err code for sysfs calls */
 	if (ret)
 		ret = -EIO;
@@ -752,6 +776,9 @@  int intel_guc_slpc_enable(struct intel_guc_slpc *slpc)
 	/* Set cached media freq ratio mode */
 	intel_guc_slpc_set_media_ratio_mode(slpc, slpc->media_ratio_mode);
 
+	/* Set cached value of ignore efficient freq */
+	intel_guc_slpc_set_ignore_eff_freq(slpc, slpc->ignore_eff_freq);
+
 	return 0;
 }
 
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.h b/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.h
index 17ed515f6a85..597eb5413ddf 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.h
@@ -46,5 +46,6 @@  void intel_guc_slpc_boost(struct intel_guc_slpc *slpc);
 void intel_guc_slpc_dec_waiters(struct intel_guc_slpc *slpc);
 int intel_guc_slpc_unset_gucrc_mode(struct intel_guc_slpc *slpc);
 int intel_guc_slpc_override_gucrc_mode(struct intel_guc_slpc *slpc, u32 mode);
+int intel_guc_slpc_set_ignore_eff_freq(struct intel_guc_slpc *slpc, bool val);
 
 #endif
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc_types.h b/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc_types.h
index a6ef53b04e04..a88651331497 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc_types.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc_types.h
@@ -31,6 +31,7 @@  struct intel_guc_slpc {
 	/* frequency softlimits */
 	u32 min_freq_softlimit;
 	u32 max_freq_softlimit;
+	bool ignore_eff_freq;
 
 	/* cached media ratio mode */
 	u32 media_ratio_mode;