Dear Meng Li and team, thank you so much for working on finally bringing AMD preferred core scheduling to mainline Linux! > The initial core rankings are set up by AMD Pstate when the > system boots. I tested this patch on our Ryzen 7950x and 5950x systems and could unfortunatlely not find any performance differences. I therefore took a closer look and as far as I can tell the conditional for the initial preferred performance priorities appears to be reversed. I marked them down below. I also attached a patch for the fix. With that fixed I can measure a 0.7% improvement compiling Firefox on 7950x. I wonder slightly how this ever past testing before, ... I think it would be a good idea to always expose the hw perf values in sysfs to help users debugging hardware issues or BIOS settings even with percore not enabled and therefore not using the unused 166 or 255 values anyway. With that fixed, however, Linux is still not always scheduling to preferred cores, but that appears to be an independant limitation of the current linux scheduler not strictly using the priority for scheduling, yet. With manual taskset guidance I could further improve the Firefox build time by some more seconds to over 1% overall performance improvement, if the linux scheudler would more reliably schedule minute long running rust lto link tasks to the preferred cores and not some mediocre ones. > - highest_perf = amd_get_highest_perf(); > - if (highest_perf > AMD_CPPC_HIGHEST_PERF(cap1)) > - highest_perf = AMD_CPPC_HIGHEST_PERF(cap1); > - > - WRITE_ONCE(cpudata->highest_perf, highest_perf); > + if (prefcore) > + WRITE_ONCE(cpudata->highest_perf, AMD_PSTATE_PREFCORE_THRESHOLD); > + else > + WRITE_ONCE(cpudata->highest_perf, AMD_CPPC_HIGHEST_PERF(cap1)); Conditional reversed, assigns THRESHOLD if enabled! > WRITE_ONCE(cpudata->nominal_perf, AMD_CPPC_NOMINAL_PERF(cap1)); > WRITE_ONCE(cpudata->lowest_nonlinear_perf, AMD_CPPC_LOWNONLIN_PERF(cap1)); > @@ -318,17 +322,15 @@ static int pstate_init_perf(struct amd_cpudata *cpudata) > static int cppc_init_perf(struct amd_cpudata *cpudata) > { > struct cppc_perf_caps cppc_perf; > - u32 highest_perf; > > int ret = cppc_get_perf_caps(cpudata->cpu, &cppc_perf); > if (ret) > return ret; > > - highest_perf = amd_get_highest_perf(); > - if (highest_perf > cppc_perf.highest_perf) > - highest_perf = cppc_perf.highest_perf; > - > - WRITE_ONCE(cpudata->highest_perf, highest_perf); > + if (prefcore) > + WRITE_ONCE(cpudata->highest_perf, AMD_PSTATE_PREFCORE_THRESHOLD); > + else > + WRITE_ONCE(cpudata->highest_perf, cppc_perf.highest_perf); Same here. Not using highest_perf if enabled, ... Signed-off-by: René Rebe <rene@xxxxxxxxxxxx> --- linux-6.4/drivers/cpufreq/amd-pstate.c.vanilla 2023-08-25 22:34:25.254995690 +0200 +++ linux-6.4/drivers/cpufreq/amd-pstate.c 2023-08-25 22:35:49.194991446 +0200 @@ -282,9 +282,9 @@ * the default max perf. */ if (prefcore) - WRITE_ONCE(cpudata->highest_perf, AMD_PSTATE_PREFCORE_THRESHOLD); - else WRITE_ONCE(cpudata->highest_perf, AMD_CPPC_HIGHEST_PERF(cap1)); + else + WRITE_ONCE(cpudata->highest_perf, AMD_PSTATE_PREFCORE_THRESHOLD); WRITE_ONCE(cpudata->nominal_perf, AMD_CPPC_NOMINAL_PERF(cap1)); WRITE_ONCE(cpudata->lowest_nonlinear_perf, AMD_CPPC_LOWNONLIN_PERF(cap1)); @@ -303,9 +303,9 @@ return ret; if (prefcore) - WRITE_ONCE(cpudata->highest_perf, AMD_PSTATE_PREFCORE_THRESHOLD); - else WRITE_ONCE(cpudata->highest_perf, cppc_perf.highest_perf); + else + WRITE_ONCE(cpudata->highest_perf, AMD_PSTATE_PREFCORE_THRESHOLD); WRITE_ONCE(cpudata->nominal_perf, cppc_perf.nominal_perf); WRITE_ONCE(cpudata->lowest_nonlinear_perf, -- René Rebe, ExactCODE GmbH, Lietzenburger Str. 42, DE-10789 Berlin https://exactcode.com | https://t2sde.org | https://rene.rebe.de