Message ID | 1629966944-439570-6-git-send-email-vincent.donnefort@arm.com |
---|---|
State | New |
Headers | show |
Series | inefficient OPPs | expand |
Hi Vincent, Thank you for the patch! Yet something to improve: [auto build test ERROR on next-20210825] [cannot apply to pm/linux-next linus/master v5.14-rc7 v5.14-rc6 v5.14-rc5 v5.14-rc7] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch] url: https://github.com/0day-ci/linux/commits/Vincent-Donnefort/inefficient-OPPs/20210826-163705 base: 7636510f976d75b860848884169ba985c8f844d8 config: i386-randconfig-r025-20210826 (attached as .config) compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project ea08c4cd1c0869ec5024a8bb3f5cdf06ab03ae83) reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # https://github.com/0day-ci/linux/commit/ed31a82b6d4abef95e8c50df33f826175cb6b6de git remote add linux-review https://github.com/0day-ci/linux git fetch --no-tags linux-review Vincent-Donnefort/inefficient-OPPs/20210826-163705 git checkout ed31a82b6d4abef95e8c50df33f826175cb6b6de # save the attached .config to linux build tree COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=i386 If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot <lkp@intel.com> All errors (new ones prefixed by >>): In file included from kernel/time/tick-common.c:19: In file included from include/trace/events/power.h:8: >> include/linux/cpufreq.h:1044:35: error: non-void function does not return a value [-Werror,-Wreturn-type] unsigned int frequency) {} ^ 1 error generated. -- In file included from drivers/acpi/processor_idle.c:23: In file included from include/acpi/processor.h:7: >> include/linux/cpufreq.h:1044:35: error: non-void function does not return a value [-Werror,-Wreturn-type] unsigned int frequency) {} ^ drivers/acpi/processor_idle.c:1137:12: warning: no previous prototype for function 'acpi_processor_ffh_lpi_probe' [-Wmissing-prototypes] int __weak acpi_processor_ffh_lpi_probe(unsigned int cpu) ^ drivers/acpi/processor_idle.c:1137:1: note: declare 'static' if the function is not intended to be used outside of this translation unit int __weak acpi_processor_ffh_lpi_probe(unsigned int cpu) ^ static drivers/acpi/processor_idle.c:1142:12: warning: no previous prototype for function 'acpi_processor_ffh_lpi_enter' [-Wmissing-prototypes] int __weak acpi_processor_ffh_lpi_enter(struct acpi_lpi_state *lpi) ^ drivers/acpi/processor_idle.c:1142:1: note: declare 'static' if the function is not intended to be used outside of this translation unit int __weak acpi_processor_ffh_lpi_enter(struct acpi_lpi_state *lpi) ^ static 2 warnings and 1 error generated. -- In file included from kernel/sched/topology.c:5: In file included from kernel/sched/sched.h:43: >> include/linux/cpufreq.h:1044:35: error: non-void function does not return a value [-Werror,-Wreturn-type] unsigned int frequency) {} ^ kernel/sched/topology.c:691:6: warning: variable 'numa_distance' set but not used [-Wunused-but-set-variable] int numa_distance = 0; ^ 1 warning and 1 error generated. -- In file included from kernel/sched/core.c:13: In file included from kernel/sched/sched.h:43: >> include/linux/cpufreq.h:1044:35: error: non-void function does not return a value [-Werror,-Wreturn-type] unsigned int frequency) {} ^ kernel/sched/core.c:3217:6: warning: no previous prototype for function 'sched_set_stop_task' [-Wmissing-prototypes] void sched_set_stop_task(int cpu, struct task_struct *stop) ^ kernel/sched/core.c:3217:1: note: declare 'static' if the function is not intended to be used outside of this translation unit void sched_set_stop_task(int cpu, struct task_struct *stop) ^ static 1 warning and 1 error generated. -- In file included from kernel/sched/fair.c:23: In file included from kernel/sched/sched.h:43: >> include/linux/cpufreq.h:1044:35: error: non-void function does not return a value [-Werror,-Wreturn-type] unsigned int frequency) {} ^ kernel/sched/fair.c:10924:6: warning: no previous prototype for function 'task_vruntime_update' [-Wmissing-prototypes] void task_vruntime_update(struct rq *rq, struct task_struct *p, bool in_fi) ^ kernel/sched/fair.c:10924:1: note: declare 'static' if the function is not intended to be used outside of this translation unit void task_vruntime_update(struct rq *rq, struct task_struct *p, bool in_fi) ^ static 1 warning and 1 error generated. -- In file included from kernel/sched/rt.c:6: In file included from kernel/sched/sched.h:43: >> include/linux/cpufreq.h:1044:35: error: non-void function does not return a value [-Werror,-Wreturn-type] unsigned int frequency) {} ^ kernel/sched/rt.c:669:6: warning: no previous prototype for function 'sched_rt_bandwidth_account' [-Wmissing-prototypes] bool sched_rt_bandwidth_account(struct rt_rq *rt_rq) ^ kernel/sched/rt.c:669:1: note: declare 'static' if the function is not intended to be used outside of this translation unit bool sched_rt_bandwidth_account(struct rt_rq *rt_rq) ^ static 1 warning and 1 error generated. vim +1044 include/linux/cpufreq.h 1041 1042 static inline int 1043 cpufreq_table_set_inefficient(const struct cpufreq_policy *policy, > 1044 unsigned int frequency) {} 1045 #endif 1046 --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 7d5f170ecad1..64ff3836955d 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -1504,6 +1504,8 @@ static int cpufreq_online(unsigned int cpu) */ if (cpufreq_driver->register_em) cpufreq_driver->register_em(policy); + + cpufreq_table_update_efficiencies(policy); } ret = cpufreq_init_policy(policy); diff --git a/drivers/cpufreq/freq_table.c b/drivers/cpufreq/freq_table.c index 67e56cf638ef..c43320c57067 100644 --- a/drivers/cpufreq/freq_table.c +++ b/drivers/cpufreq/freq_table.c @@ -365,6 +365,52 @@ int cpufreq_table_validate_and_sort(struct cpufreq_policy *policy) return set_freq_table_sorted(policy); } +void cpufreq_table_update_efficiencies(struct cpufreq_policy *policy) +{ + struct cpufreq_frequency_table *pos, *table = policy->freq_table; + enum cpufreq_table_sorting sort = policy->freq_table_sorted; + int efficient, idx; + + /* Not supported */ + if (sort == CPUFREQ_TABLE_UNSORTED) { + cpufreq_for_each_entry_idx(pos, table, idx) + pos->efficient = idx; + return; + } + + /* The highest frequency is always efficient */ + cpufreq_for_each_entry_idx(pos, table, idx) { + if (pos->frequency == CPUFREQ_ENTRY_INVALID) + continue; + + efficient = idx; + + if (sort == CPUFREQ_TABLE_SORTED_DESCENDING) + break; + } + + for (;;) { + pos = &table[idx]; + + if (pos->frequency != CPUFREQ_ENTRY_INVALID) { + if (pos->flags & CPUFREQ_INEFFICIENT_FREQ) { + pos->efficient = efficient; + } else { + pos->efficient = idx; + efficient = idx; + } + } + + if (sort == CPUFREQ_TABLE_SORTED_ASCENDING) { + if (--idx < 0) + break; + } else { + if (table[++idx].frequency == CPUFREQ_TABLE_END) + break; + } + } +} + MODULE_AUTHOR("Dominik Brodowski <linux@brodo.de>"); MODULE_DESCRIPTION("CPUfreq frequency table helpers"); MODULE_LICENSE("GPL"); diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index c65a1d7385f8..4659921173f7 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h @@ -664,13 +664,15 @@ struct governor_attr { #define CPUFREQ_ENTRY_INVALID ~0u #define CPUFREQ_TABLE_END ~1u /* Special Values of .flags field */ -#define CPUFREQ_BOOST_FREQ (1 << 0) +#define CPUFREQ_BOOST_FREQ (1 << 0) +#define CPUFREQ_INEFFICIENT_FREQ (1 << 1) struct cpufreq_frequency_table { unsigned int flags; unsigned int driver_data; /* driver specific data, not used by core */ unsigned int frequency; /* kHz - doesn't need to be in ascending * order */ + unsigned int efficient; /* idx of an efficient frequency */ }; #if defined(CONFIG_CPU_FREQ) && defined(CONFIG_PM_OPP) @@ -1003,6 +1005,20 @@ static inline int cpufreq_table_count_valid_entries(const struct cpufreq_policy return count; } + +static inline void +cpufreq_table_set_inefficient(const struct cpufreq_policy *policy, + unsigned int frequency) +{ + struct cpufreq_frequency_table *pos; + + cpufreq_for_each_valid_entry(pos, policy->freq_table) { + if (pos->frequency == frequency) { + pos->flags |= CPUFREQ_INEFFICIENT_FREQ; + break; + } + } +} #else static inline int cpufreq_boost_trigger_state(int state) { @@ -1022,6 +1038,10 @@ static inline bool policy_has_boost_freq(struct cpufreq_policy *policy) { return false; } + +static inline int +cpufreq_table_set_inefficient(const struct cpufreq_policy *policy, + unsigned int frequency) {} #endif #if defined(CONFIG_ENERGY_MODEL) && defined(CONFIG_CPU_FREQ_GOV_SCHEDUTIL) @@ -1049,6 +1069,7 @@ extern struct freq_attr cpufreq_freq_attr_scaling_available_freqs; extern struct freq_attr cpufreq_freq_attr_scaling_boost_freqs; extern struct freq_attr *cpufreq_generic_attr[]; int cpufreq_table_validate_and_sort(struct cpufreq_policy *policy); +void cpufreq_table_update_efficiencies(struct cpufreq_policy *policy); unsigned int cpufreq_generic_get(unsigned int cpu); void cpufreq_generic_init(struct cpufreq_policy *policy,
Some SoCs such as the sd855 have OPPs within the same policy whose cost is higher than others with a higher frequency. Those OPPs are inefficients and it might be interesting for a governor to not use them. Adding a flag, CPUFREQ_INEFFICIENT_FREQ, to mark such OPPs into the frequency table, as well as a new cpufreq_frequency_table member "efficient". This new member allows CPUFreq to resolve an inefficient frequency to an efficient one. Efficient frequencies point to themselves. The efficiency resolution must check it doesn't break the policy maximum. Signed-off-by: Vincent Donnefort <vincent.donnefort@arm.com>