Re: [PATCH v4 5/7] cpufreq: Calculate number of busy CPUs

Dirk Brandewie
2013-06-19T18:01:14Z

On 06/19/2013 10:12 AM, Lukasz Majewski wrote:
> In the core governor code, per cpu load value is calculated. This patch
> uses it to mark processor as a "busy" one, when load value is higher than
> 90%.
>
> New cpufreq sysfs attribute is created (busy_cpus). It is read only
> and provides information about number of actually busy CPU.
>

What is the intended use of this interface?

For drivers that have internal governors it will be misleading/wrong

--Dirk
> Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
> Signed-off-by: Myungjoo Ham <myungjoo.ham@samsung.com>
>
> Changes for v4:
> - New patch
> ---
> drivers/cpufreq/cpufreq.c | 31 ++++++++++++++++++++++++++++++-
> drivers/cpufreq/cpufreq_governor.c | 1 +
> include/linux/cpufreq.h | 3 +++
> 3 files changed, 34 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
> index 9141d33..f785273 100644
> --- a/drivers/cpufreq/cpufreq.c
> +++ b/drivers/cpufreq/cpufreq.c
> @@ -48,6 +48,7 @@ static DEFINE_PER_CPU(char[CPUFREQ_NAME_LEN], cpufreq_cpu_governor);
> #endif
> static DEFINE_RWLOCK(cpufreq_driver_lock);
> static LIST_HEAD(cpufreq_policy_list);
> +static cpumask_t cpufreq_busy_cpus;
>
> /*
> * cpu_policy_rwsem is a per CPU reader-writer semaphore designed to cure
> @@ -317,6 +318,13 @@ EXPORT_SYMBOL_GPL(cpufreq_notify_transition);
> /*********************************************************************
> * SYSFS INTERFACE *
> *********************************************************************/
> +ssize_t show_busy_cpus(struct kobject *kobj,
> + struct attribute *attr, char *buf)
> +{
> + return sprintf(buf, "%d\n", cpufreq_num_busy_cpu());
> +}
> +define_one_global_ro(busy_cpus);
> +
> ssize_t show_boost(struct kobject *kobj,
> struct attribute *attr, char *buf)
> {
> @@ -1980,6 +1988,17 @@ int cpufreq_boost_enabled(void)
> return boost_enabled;
> }
>
> +int cpufreq_num_busy_cpu(void)
> +{
> + return cpumask_weight(&cpufreq_busy_cpus);
> +}
> +
> +void cpufreq_set_busy_cpu(int cpu, int val)
> +{
> + val ? cpumask_set_cpu(cpu, &cpufreq_busy_cpus) :
> + cpumask_clear_cpu(cpu, &cpufreq_busy_cpus);
> +}
> +
> /*********************************************************************
> * REGISTER / UNREGISTER CPUFREQ DRIVER *
> *********************************************************************/
> @@ -2019,6 +2038,13 @@ int cpufreq_register_driver(struct cpufreq_driver *driver_data)
> cpufreq_driver = driver_data;
> write_unlock_irqrestore(&cpufreq_driver_lock, flags);
>
> + ret = cpufreq_sysfs_create_file(&(busy_cpus.attr));
> + if (ret) {
> + pr_err("%s: cannot register global busy_cpus sysfs file\n",
> + __func__);
> + goto err_null_driver;
> + }
> +
> if (!cpufreq_driver->boost_supported)
> boost.attr.mode = 0444;
>
> @@ -2026,7 +2052,7 @@ int cpufreq_register_driver(struct cpufreq_driver *driver_data)
> if (ret) {
> pr_err("%s: cannot register global boost sysfs file\n",
> __func__);
> - goto err_null_driver;
> + goto err_busy_idle_unreg;
> }
>
> ret = subsys_interface_register(&cpufreq_interface);
> @@ -2058,6 +2084,8 @@ int cpufreq_register_driver(struct cpufreq_driver *driver_data)
> return 0;
> err_if_unreg:
> subsys_interface_unregister(&cpufreq_interface);
> +err_busy_idle_unreg:
> + cpufreq_sysfs_remove_file(&(busy_cpus.attr));
> err_null_driver:
> write_lock_irqsave(&cpufreq_driver_lock, flags);
> cpufreq_driver = NULL;
> @@ -2086,6 +2114,7 @@ int cpufreq_unregister_driver(struct cpufreq_driver *driver)
>
> subsys_interface_unregister(&cpufreq_interface);
>
> + cpufreq_sysfs_remove_file(&(busy_cpus.attr));
> cpufreq_sysfs_remove_file(&(boost.attr));
> unregister_hotcpu_notifier(&cpufreq_cpu_notifier);
>
> diff --git a/drivers/cpufreq/cpufreq_governor.c b/drivers/cpufreq/cpufreq_governor.c
> index 077cea7..3402533 100644
> --- a/drivers/cpufreq/cpufreq_governor.c
> +++ b/drivers/cpufreq/cpufreq_governor.c
> @@ -148,6 +148,7 @@ void dbs_check_cpu(struct dbs_data *dbs_data, int cpu)
> continue;
>
> load = 100 * (wall_time - idle_time) / wall_time;
> + cpufreq_set_busy_cpu(j, load > 90 ? 1 : 0);
>
> if (dbs_data->cdata->governor == GOV_ONDEMAND) {
> int freq_avg = __cpufreq_driver_getavg(policy, j);
> diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
> index 4783c4c..536abfc 100644
> --- a/include/linux/cpufreq.h
> +++ b/include/linux/cpufreq.h
> @@ -436,6 +436,9 @@ int cpufreq_frequency_table_target(struct cpufreq_policy *policy,
> int cpufreq_boost_trigger_state(int state);
> int cpufreq_boost_supported(void);
> int cpufreq_boost_enabled(void);
> +
> +void cpufreq_set_busy_cpu(int cpu, int val);
> +int cpufreq_num_busy_cpu(void);
> /* the following 3 funtions are for cpufreq core use only */
> struct cpufreq_frequency_table *cpufreq_frequency_get_table(unsigned int cpu);
>
>