On 30 May 11:16, Wyes Karny wrote: > From: "Gautham R. Shenoy" <gautham.shenoy@xxxxxxx> > > [ Upstream commit 3bf8c6307bad5c0cc09cde982e146d847859b651 ] > > Schedutil normally calls the adjust_perf callback for drivers with > adjust_perf callback available and fast_switch_possible flag set. > However, when frequency invariance is disabled and schedutil tries to > invoke fast_switch. So, there is a chance of kernel crash if this > function pointer is not set. To protect against this scenario add > fast_switch callback to amd_pstate driver. > > Fixes: 1d215f0319c2 ("cpufreq: amd-pstate: Add fast switch function for AMD P-State") > Signed-off-by: Gautham R. Shenoy <gautham.shenoy@xxxxxxx> > Signed-off-by: Wyes Karny <wyes.karny@xxxxxxx> > Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@xxxxxxxxx> > (cherry picked from commit 4badf2eb1e986bdbf34dd2f5d4c979553a86fe54) > --- > drivers/cpufreq/amd-pstate.c | 37 +++++++++++++++++++++++++++++------- > 1 file changed, 30 insertions(+), 7 deletions(-) > > diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c > index 8dd46fad151e..7cce90d16b8d 100644 > --- a/drivers/cpufreq/amd-pstate.c > +++ b/drivers/cpufreq/amd-pstate.c > @@ -422,9 +422,8 @@ static int amd_pstate_verify(struct cpufreq_policy_data *policy) > return 0; > } > > -static int amd_pstate_target(struct cpufreq_policy *policy, > - unsigned int target_freq, > - unsigned int relation) > +static int amd_pstate_update_freq(struct cpufreq_policy *policy, > + unsigned int target_freq, bool fast_switch) > { > struct cpufreq_freqs freqs; > struct amd_cpudata *cpudata = policy->driver_data; > @@ -443,14 +442,36 @@ static int amd_pstate_target(struct cpufreq_policy *policy, > des_perf = DIV_ROUND_CLOSEST(target_freq * cap_perf, > cpudata->max_freq); > > - cpufreq_freq_transition_begin(policy, &freqs); > - amd_pstate_update(cpudata, min_perf, des_perf, > - max_perf, false); > - cpufreq_freq_transition_end(policy, &freqs, false); > + WARN_ON(fast_switch && !policy->fast_switch_enabled); > + /* > + * If fast_switch is desired, then there aren't any registered > + * transition notifiers. See comment for > + * cpufreq_enable_fast_switch(). > + */ > + if (!fast_switch) > + cpufreq_freq_transition_begin(policy, &freqs); > + > + amd_pstate_update(cpudata, min_perf, des_perf, max_perf, fast_switch); > + > + if (!fast_switch) > + cpufreq_freq_transition_end(policy, &freqs, false); > > return 0; > } > > +static int amd_pstate_target(struct cpufreq_policy *policy, > + unsigned int target_freq, > + unsigned int relation) > +{ > + return amd_pstate_update_freq(policy, target_freq, false); > +} > + > +static unsigned int amd_pstate_fast_switch(struct cpufreq_policy *policy, > + unsigned int target_freq) > +{ > + return amd_pstate_update_freq(policy, target_freq, true); > +} > + > static void amd_pstate_adjust_perf(unsigned int cpu, > unsigned long _min_perf, > unsigned long target_perf, > @@ -692,6 +713,7 @@ static int amd_pstate_cpu_exit(struct cpufreq_policy *policy) > > freq_qos_remove_request(&cpudata->req[1]); > freq_qos_remove_request(&cpudata->req[0]); > + policy->fast_switch_possible = false; > kfree(cpudata); > > return 0; > @@ -1226,6 +1248,7 @@ static struct cpufreq_driver amd_pstate_driver = { > .flags = CPUFREQ_CONST_LOOPS | CPUFREQ_NEED_UPDATE_LIMITS, > .verify = amd_pstate_verify, > .target = amd_pstate_target, > + .fast_switch = amd_pstate_fast_switch, > .init = amd_pstate_cpu_init, > .exit = amd_pstate_cpu_exit, > .suspend = amd_pstate_cpu_suspend, Please ignore this. Wrong patch. Sorry for inconvenience. Thanks, Wyes > -- > 2.34.1 >