CPUFreq: Implement per policy instances of governors
Subsystems (2)
Viresh Kumar
maintainerv2 cover CPUFreq: Implement per policy instances of governors
This is targetted for 3.10-rc1 or linux-next just after the merge window.
All patches are pushed here for others to apply:
http://git.linaro.org/gitweb?p=people/vireshk/linux.git;a=shortlog;h=refs/heads/cpufreq-updates-3.10
Currently, there can't be multiple instances of single governor_type. If we have a multi-package system, where we have multiple instances of struct policy (per package), we can't have multiple instances of same governor. i.e. We can't have multiple instances of ondemand governor for multiple packages.
Governors directory in sysfs is created at /sys/devices/system/cpu/cpufreq/ governor-name/. Which again reflects that there can be only one instance of a governor_type in the system.
This is a bottleneck for multicluster system, where we want different packages to use same governor type, but with different tunables.
This patchset is inclined towards fixing this issue. Now we will create governors directory in cpu/cpu*/cpufreq/<gov> for platforms which have multiple struct policy alive at any moment. For others the interface is kept same:
cpu/cpufreq/<gov>.
V1->V2:
- Few patches from V1 are already picked up by Rafael for 3.9-rc1
- Last two patches are new
- Added dbs_data->exit() routines to free up memory used for struct tuners.
@Rafael: I don't really want to have following patch: "cpufreq: Add Kconfig option to enable/disable have_multiple_policies" and added it because of comment from Borislov against which nobody else replied :)
I still want to have your opinion on the same.
Viresh Kumar (4):
cpufreq: Add per policy governor-init/exit infrastructure
cpufreq: governor: Implement per policy instances of governors
cpufreq: Add Kconfig option to enable/disable have_multiple_policies
cpufreq: Get rid of "struct global_attr"
drivers/cpufreq/Kconfig | 3 + drivers/cpufreq/acpi-cpufreq.c | 9 +- drivers/cpufreq/cpufreq.c | 27 +++-- drivers/cpufreq/cpufreq_conservative.c | 148 +++++++++++++--------- drivers/cpufreq/cpufreq_governor.c | 159 ++++++++++++++---------- drivers/cpufreq/cpufreq_governor.h | 43 +++++-- drivers/cpufreq/cpufreq_ondemand.c | 216 +++++++++++++++++++-------------- drivers/cpufreq/intel_pstate.c | 30 ++--- include/linux/cpufreq.h | 44 ++++--- 9 files changed, 402 insertions(+), 277 deletions(-)
Signature · 1 line
1.7.12.rc2.18.g61b472e
Viresh Kumar
maintainerPATCH v2 1/4 cpufreq: Add per policy governor-init/exit infrastructure
Currently, there can't be multiple instances of single governor_type. If we have a multi-package system, where we have multiple instances of struct policy (per package), we can't have multiple instances of same governor. i.e. We can't have multiple instances of ondemand governor for multiple packages.
Governors directory in sysfs is created at /sys/devices/system/cpu/cpufreq/ governor-name/. Which again reflects that there can be only one instance of a governor_type in the system.
This is a bottleneck for multicluster system, where we want different packages to use same governor type, but with different tunables.
This patch is inclined towards providing this infrastructure. Because we are required to allocate governor's resources dynamically now, we must do it at policy creation and end. And so got CPUFREQ_GOV_POLICY_INIT/EXIT.
--- drivers/cpufreq/cpufreq.c | 21 ++++++++++++++++++--- include/linux/cpufreq.h | 9 ++++++--- 2 files changed, 24 insertions(+), 6 deletions(-)
drivers/cpufreq/cpufreq.c +18 -3
@@ -1081,6 +1081,8 @@ static int __cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif/* If cpu is last user of policy, free policy */ if (cpus ==1 ) { +__cpufreq_governor (data,CPUFREQ_GOV_POLICY_EXIT ); +lock_policy_rwsem_read (cpu); kobj = &data->kobj; cmp = &data->kobj_unregister;
@@ -1669,7 +1671,7 @@ EXPORT_SYMBOL(cpufreq_get_policy);static int __cpufreq_set_policy (struct cpufreq_policy *data,struct cpufreq_policy *policy) { -int ret =0 ; +int ret =0 , failed =1 ;struct cpufreq_driver *driver =rcu_dereference (cpufreq_driver); pr_debug("setting new policy for CPU %u: %u - %u kHz\n", policy->cpu,
@@ -1724,18 +1726,31 @@ static int __cpufreq_set_policy(struct cpufreq_policy *data,pr_debug ("governor switch\n" );/* end old governor */ -if (data->governor) +if (data->governor) {__cpufreq_governor (data,CPUFREQ_GOV_STOP ); +__cpufreq_governor (data, +CPUFREQ_GOV_POLICY_EXIT ); + }/* start new governor */ data->governor = policy->governor; -if (__cpufreq_governor (data,CPUFREQ_GOV_START )) { +if (!__cpufreq_governor (data,CPUFREQ_GOV_POLICY_INIT )) { +if (!__cpufreq_governor (data,CPUFREQ_GOV_START )) + failed =0 ; +else +__cpufreq_governor (data, +CPUFREQ_GOV_POLICY_EXIT ); + } + +if (failed) {/* new governor failed, so re-start old one */ pr_debug ("starting governor %s failed\n" , data->governor->name);if (old_gov) { data->governor = old_gov;__cpufreq_governor (data, +CPUFREQ_GOV_POLICY_INIT ); +__cpufreq_governor (data,CPUFREQ_GOV_START ); } ret = -EINVAL ;
include/linux/cpufreq.h +6 -3
@@ -106,6 +106,7 @@ struct cpufreq_policy {* governors are used */ unsigned int policy;/* see above */ struct cpufreq_governor *governor;/* see below */ +void *governor_data;struct work_struct update;/* if update_policy() needs to be * called, but you're in IRQ context */
@@ -178,9 +179,11 @@ static inline unsigned long cpufreq_scale(unsigned long old, u_int div, u_int mu* CPUFREQ GOVERNORS * *********************************************************************/ -#define CPUFREQ_GOV_START 1 -#define CPUFREQ_GOV_STOP 2 -#define CPUFREQ_GOV_LIMITS 3 +#define CPUFREQ_GOV_START 1 +#define CPUFREQ_GOV_STOP 2 +#define CPUFREQ_GOV_LIMITS 3 +#define CPUFREQ_GOV_POLICY_INIT 4 +#define CPUFREQ_GOV_POLICY_EXIT 4struct cpufreq_governor {char name[CPUFREQ_NAME_LEN ];
Signature · 1 line
1.7.12.rc2.18.g61b472e
Re: [PATCH V2 1/4] cpufreq: Add per policy governor-init/exit infrastructure
Quoted 9 lines · Viresh Kumar
Currently, there can't be multiple instances of single
governor_type. If we have a multi-package system, where we have multiple instances of struct policy (per package), we can't have multiple instances of same governor. i.e. We can't have multiple instances of ondemand governor for multiple packages.Governors directory in sysfs is created at
/sys/devices/system/cpu/cpufreq/governor-name/. Which again reflects that there can be only one instance of agovernor_typein the system.
Quoted 6 lines
This is a bottleneck for multicluster system, where we want different packages to use same governor type, but with different tunables.
This patch is inclined towards providing this infrastructure. Because we are required to allocate governor's resources dynamically now, we must do it at policy creation and end. And so got CPUFREQ_GOV_POLICY_INIT/EXIT.
Are those new events NOPs now?
Quoted 76 lines
Signed-off-by Viresh Kumar <[email protected]>--- drivers/cpufreq/cpufreq.c | 21 ++++++++++++++++++--- include/linux/cpufreq.h | 9 ++++++--- 2 files changed, 24 insertions(+), 6 deletions(-)drivers/cpufreq/cpufreq.c +18
-3@@ -1081,6 +1081,8 @@ static int __cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif/* If cpu is last user of policy, free policy */ if (cpus ==1 ) { +__cpufreq_governor (data,CPUFREQ_GOV_POLICY_EXIT ); +lock_policy_rwsem_read (cpu); kobj = &data->kobj; cmp = &data->kobj_unregister;@@ -1669,7 +1671,7 @@ EXPORT_SYMBOL(cpufreq_get_policy);static int __cpufreq_set_policy (struct cpufreq_policy *data,struct cpufreq_policy *policy) { -int ret =0 ; +int ret =0 , failed =1 ;struct cpufreq_driver *driver =rcu_dereference (cpufreq_driver); pr_debug("setting new policy for CPU %u: %u - %u kHz\n", policy->cpu,@@ -1724,18 +1726,31 @@ static int __cpufreq_set_policy(struct cpufreq_policy *data,pr_debug ("governor switch\n" );/* end old governor */ -if (data->governor) +if (data->governor) {__cpufreq_governor (data,CPUFREQ_GOV_STOP ); +__cpufreq_governor (data, +CPUFREQ_GOV_POLICY_EXIT ); + }/* start new governor */ data->governor = policy->governor; -if (__cpufreq_governor (data,CPUFREQ_GOV_START )) { +if (!__cpufreq_governor (data,CPUFREQ_GOV_POLICY_INIT )) { +if (!__cpufreq_governor (data,CPUFREQ_GOV_START )) + failed =0 ; +else +__cpufreq_governor (data, +CPUFREQ_GOV_POLICY_EXIT ); + } + +if (failed) {/* new governor failed, so re-start old one */ pr_debug ("starting governor %s failed\n" , data->governor->name);if (old_gov) { data->governor = old_gov;__cpufreq_governor (data, +CPUFREQ_GOV_POLICY_INIT ); +__cpufreq_governor (data,CPUFREQ_GOV_START ); } ret = -EINVAL ;include/linux/cpufreq.h +1
-0@@ -106,6 +106,7 @@ struct cpufreq_policy {* governors are used */ unsigned int policy;/* see above */ struct cpufreq_governor *governor;/* see below */ +void *governor_data;struct work_struct update;/* if update_policy() needs to be * called, but you're in IRQ context */ @@ -178,9 +179,11 @@ static inline unsigned long cpufreq_scale(unsigned long old, u_int div, u_int mu* CPUFREQ GOVERNORS *
include/linux/cpufreq.h static inline unsigned long cpufreq_scale(unsigned long old, u_int div, u_int mu · line 186
Quoted 10 lines
include/linux/cpufreq.h +5
-3*********************************************************************/ -#define CPUFREQ_GOV_START 1 -#define CPUFREQ_GOV_STOP 2 -#define CPUFREQ_GOV_LIMITS 3 +#define CPUFREQ_GOV_START 1 +#define CPUFREQ_GOV_STOP 2 +#define CPUFREQ_GOV_LIMITS 3 +#define CPUFREQ_GOV_POLICY_INIT 4 +#define CPUFREQ_GOV_POLICY_EXIT 4
Why don't you use different values here?
If you need only one value, one #define should be sufficient.
Thanks,
Rafael
Signature · 2 lines
I speak only for myself. Rafael J. Wysocki, Intel Open Source Technology Center.
Viresh Kumar
maintainerRe: [PATCH V2 1/4] cpufreq: Add per policy governor-init/exit infrastructure
Quoted 7 lines · Rafael J. Wysocki
Quoted 3 lines · Viresh Kumar
This patch is inclined towards providing this infrastructure. Because we are required to allocate governor's resources dynamically now, we must do it at policy creation and end. And so got CPUFREQ_GOV_POLICY_INIT/EXIT.
Are those new events NOPs now?
No. These are used atleast for ondemand & conservative.
Quoted 6 lines
include/linux/cpufreq.h static inline unsigned long cpufreq_scale(unsigned long old, u_int div, u_int mu · line 186
Quoted 2 lines
include/linux/cpufreq.h +2
-0+#define CPUFREQ_GOV_POLICY_INIT 4 +#define CPUFREQ_GOV_POLICY_EXIT 4Why don't you use different values here?
If you need only one value, one #define should be sufficient.
Naah, something happened... I got fixed this locally but couldn't get that into the commit somehow. EXIT should have 5 here.
Re: [PATCH V2 1/4] cpufreq: Add per policy governor-init/exit infrastructure
Quoted 10 lines · Viresh Kumar
Quoted 7 lines · Rafael J. Wysocki
Quoted 3 lines · Viresh Kumar
This patch is inclined towards providing this infrastructure. Because we are required to allocate governor's resources dynamically now, we must do it at policy creation and end. And so got CPUFREQ_GOV_POLICY_INIT/EXIT.
Are those new events NOPs now?
No. These are used atleast for ondemand & conservative.
They will be after the next patch, you mean? :-)
Quoted 9 lines
Quoted 6 lines
include/linux/cpufreq.h static inline unsigned long cpufreq_scale(unsigned long old, u_int div, u_int mu · line 186
Quoted 2 lines
include/linux/cpufreq.h +2
-0+#define CPUFREQ_GOV_POLICY_INIT 4 +#define CPUFREQ_GOV_POLICY_EXIT 4Why don't you use different values here?
If you need only one value, one #define should be sufficient.
Naah, something happened... I got fixed this locally but couldn't get that into the commit somehow. EXIT should have 5 here.
Well, it appeared so from the next patch ...
Thanks,
Rafael
Signature · 2 lines
I speak only for myself. Rafael J. Wysocki, Intel Open Source Technology Center.
Viresh Kumar
maintainerRe: [PATCH V2 1/4] cpufreq: Add per policy governor-init/exit infrastructure
Quoted 6 lines · Rafael J. Wysocki
Quoted 1 line · Viresh Kumar
No. These are used atleast for ondemand & conservative.
They will be after the next patch, you mean? :-)
Well, it appeared so from the next patch ...
Yes :)
Viresh Kumar
maintainerRe: [PATCH V2 1/4] cpufreq: Add per policy governor-init/exit infrastructure
In reply to Rafael J. WysockiQuoted 3 lines · Rafael J. Wysocki
Why don't you use different values here?
If you need only one value, one #define should be sufficient.
This is the fixup i have for this, I will push all patches again to cpufreq-for-3.10 branch:
----------------------------------------------
commit 4d7296fb64f2353aafad5104f0a046466d0f4ea9
Author: Viresh Kumar <[email protected]> Date: Fri Feb 22 07:56:31 2013 +0530
fixup! cpufreq: Add per policy governor-init/exit infrastructure
--- include/linux/cpufreq.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
include/linux/cpufreq.h +0 -0
@@ -183,7 +183,7 @@ static inline unsigned long cpufreq_scale(unsigned
long old, u_int div, u_int mu
#define CPUFREQ_GOV_STOP 2
#define CPUFREQ_GOV_LIMITS 3
#define CPUFREQ_GOV_POLICY_INIT 4 -#define CPUFREQ_GOV_POLICY_EXIT 4 +#define CPUFREQ_GOV_POLICY_EXIT 5
struct cpufreq_governor {
char name[CPUFREQ_NAME_LEN];Viresh Kumar
maintainerPATCH v2 2/4 cpufreq: governor: Implement per policy instances of governors
In reply to Viresh KumarCurrently, there can't be multiple instances of single governor_type. If we have a multi-package system, where we have multiple instances of struct policy (per package), we can't have multiple instances of same governor. i.e. We can't have multiple instances of ondemand governor for multiple packages.
Governors directory in sysfs is created at /sys/devices/system/cpu/cpufreq/ governor-name/. Which again reflects that there can be only one instance of a governor_type in the system.
This is a bottleneck for multicluster system, where we want different packages to use same governor type, but with different tunables.
This patch uses the infrastructure provided by earlier patch and implements init/exit routines for ondemand and conservative governors.
--- drivers/cpufreq/cpufreq.c | 6 - drivers/cpufreq/cpufreq_conservative.c | 148 +++++++++++++--------- drivers/cpufreq/cpufreq_governor.c | 159 ++++++++++++++---------- drivers/cpufreq/cpufreq_governor.h | 43 +++++-- drivers/cpufreq/cpufreq_ondemand.c | 216 +++++++++++++++++++-------------- include/linux/cpufreq.h | 17 ++- 6 files changed, 353 insertions(+), 236 deletions(-)
drivers/cpufreq/cpufreq.c +0 -6
@@ -1564,11 +1564,6 @@ static int __cpufreq_governor(struct cpufreq_policy *policy, policy->cpu, event); ret = policy->governor->governor (policy, event); -if (event ==CPUFREQ_GOV_START ) - policy->governor->initialized++; -else if (event ==CPUFREQ_GOV_STOP ) - policy->governor->initialized--; -/* we keep one module reference alive for each CPU governed by this CPU */ if ((event !=CPUFREQ_GOV_START ) || ret)
@@ -1592,7 +1587,6 @@ int cpufreq_register_governor(struct cpufreq_governor *governor)mutex_lock (&cpufreq_governor_mutex); - governor->initialized =0 ; err = -EBUSY ;if (__find_governor (governor->name) ==NULL ) { err =0 ;
drivers/cpufreq/cpufreq_conservative.c +89 -59
317 lines not on this page · raw message
drivers/cpufreq/cpufreq_governor.c +93 -66
277 lines not on this page · raw message
drivers/cpufreq/cpufreq_governor.h +30 -13
87 lines not on this page · raw message
drivers/cpufreq/cpufreq_ondemand.c +126 -90
448 lines not on this page · raw message
include/linux/cpufreq.h +15 -2
@@ -107,6 +107,11 @@ struct cpufreq_policy {unsigned int policy;/* see above */ struct cpufreq_governor *governor;/* see below */ void *governor_data; +/* This should be set by init() of platforms having multiple +* clock-domains, i.e. supporting multiple policies. With this sysfs +* directories of governor would be created in cpu/cpu<num>/cpufreq/ +* directory */ +bool have_multiple_policies;struct work_struct update;/* if update_policy() needs to be * called, but you're in IRQ context */
@@ -134,6 +139,15 @@ static inline bool policy_is_shared(struct cpufreq_policy *policy)return cpumask_weight (policy->cpus) >1 ; } +static inline struct kobject * +get_governor_parent_kobj (struct cpufreq_policy *policy) +{ +if (policy->have_multiple_policies) +return &policy->kobj; +else +return cpufreq_global_kobject; +} +/******************** cpufreq transition notifiers *******************/ #define CPUFREQ_PRECHANGE (0)
@@ -183,11 +197,10 @@ static inline unsigned long cpufreq_scale(unsigned long old, u_int div, u_int mu#define CPUFREQ_GOV_STOP 2#define CPUFREQ_GOV_LIMITS 3#define CPUFREQ_GOV_POLICY_INIT 4 -#define CPUFREQ_GOV_POLICY_EXIT 4 +#define CPUFREQ_GOV_POLICY_EXIT 5struct cpufreq_governor {char name[CPUFREQ_NAME_LEN ]; -int initialized;int (*governor) (struct cpufreq_policy *policy,unsigned int event); ssize_t (*show_setspeed) (struct cpufreq_policy *policy,
Signature · 1 line
1.7.12.rc2.18.g61b472e
Viresh Kumar
maintainerRe: [PATCH V2 2/4] cpufreq: governor: Implement per policy instances of governors
include/linux/cpufreq.h static inline unsigned long cpufreq_scale(unsigned long old, u_int div, u_int mu · line 200
Quoted 9 lines · Viresh Kumar
include/linux/cpufreq.h +1
-1#define CPUFREQ_PRECHANGE (0)@@ -183,11 +197,10 @@ static inline unsigned long cpufreq_scale(unsigned long old, u_int div, u_int mu#define CPUFREQ_GOV_STOP 2#define CPUFREQ_GOV_LIMITS 3#define CPUFREQ_GOV_POLICY_INIT 4 -#define CPUFREQ_GOV_POLICY_EXIT 4 +#define CPUFREQ_GOV_POLICY_EXIT 5
See, i told you i had this change, but got merged to the wrong commit. :)
Viresh Kumar
maintainerPATCH v2 3/4 cpufreq: Add Kconfig option to enable/disable have_multiple_policies
In reply to Viresh Kumarhave_multiple_policies is required by platforms having multiple clock-domains for cpus, i.e. supporting multiple policies for cpus. This patch adds in a Kconfig option for enabling execution of this code.
--- drivers/cpufreq/Kconfig | 3 +++ include/linux/cpufreq.h | 4 ++++ 2 files changed, 7 insertions(+)
drivers/cpufreq/Kconfig +3 -0
@@ -23,6 +23,9 @@ config CPU_FREQ_TABLE config CPU_FREQ_GOV_COMMON bool +config CPU_FREQ_HAVE_MULTIPLE_POLICIES + bool + config CPU_FREQ_STAT tristate "CPU frequency translation statistics" select CPU_FREQ_TABLE
include/linux/cpufreq.h +4 -0
@@ -107,11 +107,13 @@ struct cpufreq_policy {unsigned int policy;/* see above */ struct cpufreq_governor *governor;/* see below */ void *governor_data; +#ifdef CONFIG_CPU_FREQ_HAVE_MULTIPLE_POLICIES /* This should be set by init() of platforms having multiple * clock-domains, i.e. supporting multiple policies. With this sysfs * directories of governor would be created in cpu/cpu<num>/cpufreq/ * directory */ bool have_multiple_policies; +#endif struct work_struct update;/* if update_policy() needs to be * called, but you're in IRQ context */
@@ -142,9 +144,11 @@ static inline bool policy_is_shared(struct cpufreq_policy *policy)static inline struct kobject *get_governor_parent_kobj (struct cpufreq_policy *policy) { +#ifdef CONFIG_CPU_FREQ_HAVE_MULTIPLE_POLICIES if (policy->have_multiple_policies)return &policy->kobj; else +#endif return cpufreq_global_kobject; }
Signature · 1 line
1.7.12.rc2.18.g61b472e
Re: [PATCH V2 3/4] cpufreq: Add Kconfig option to enable/disable have_multiple_policies
Quoted 16 lines · Viresh Kumar
have_multiple_policiesis required by platforms having multiple clock-domains for cpus, i.e. supporting multiple policies for cpus. This patch adds in aKconfigoption for enabling execution of this code.Reported-by Borislav Petkov <[email protected]>Signed-off-by Viresh Kumar <[email protected]>--- drivers/cpufreq/Kconfig | 3 +++ include/linux/cpufreq.h | 4 ++++ 2 files changed, 7 insertions(+)drivers/cpufreq/Kconfig +0
-0
drivers/cpufreq/Kconfig config CPU_FREQ_TABLE · line 28
Quoted 6 lines
drivers/cpufreq/Kconfig +3
-0@@ -23,6 +23,9 @@ config CPU_FREQ_TABLE config CPU_FREQ_GOV_COMMON bool +config CPU_FREQ_HAVE_MULTIPLE_POLICIES + bool +
So I suppose some architectures will select this, right?
What architecture they are?
Quoted 8 lines
drivers/cpufreq/Kconfig +0
-0config CPU_FREQ_STAT tristate "CPU frequency translation statistics" select CPU_FREQ_TABLEinclude/linux/cpufreq.h +0
-0
include/linux/cpufreq.h struct cpufreq_policy { · line 116
Quoted 10 lines
include/linux/cpufreq.h +2
-0@@ -107,11 +107,13 @@ struct cpufreq_policy {unsigned int policy;/* see above */ struct cpufreq_governor *governor;/* see below */ void *governor_data; +#ifdef CONFIG_CPU_FREQ_HAVE_MULTIPLE_POLICIES /* This should be set by init() of platforms having multiple * clock-domains, i.e. supporting multiple policies. With this sysfs * directories of governor would be created in cpu/cpu<num>/cpufreq/ * directory */ bool have_multiple_policies; +#endif
I'm not really sure I like this. ->
include/linux/cpufreq.h static inline bool policy_is_shared(struct cpufreq_policy *policy) · line 152
Quoted 12 lines
include/linux/cpufreq.h +2
-0struct work_struct update;/* if update_policy() needs to be * called, but you're in IRQ context */ @@ -142,9 +144,11 @@ static inline bool policy_is_shared(struct cpufreq_policy *policy)static inline struct kobject *get_governor_parent_kobj (struct cpufreq_policy *policy) { +#ifdef CONFIG_CPU_FREQ_HAVE_MULTIPLE_POLICIES if (policy->have_multiple_policies)return &policy->kobj; else +#endif return cpufreq_global_kobject;
-> I wonder why don't you arrange things so that policy->kobj is always returned, but it points to cpufreq_global_kobject in case there's only one (i.e. make policy->kobj a pointer)?
include/linux/cpufreq.h static inline bool policy_is_shared(struct cpufreq_policy *policy) · line 153
Quoted 1 line
include/linux/cpufreq.h +0
-0}
Thanks,
Rafael
Signature · 2 lines
I speak only for myself. Rafael J. Wysocki, Intel Open Source Technology Center.
Viresh Kumar
maintainerRe: [PATCH V2 3/4] cpufreq: Add Kconfig option to enable/disable have_multiple_policies
Quoted 7 lines · Rafael J. Wysocki
drivers/cpufreq/Kconfig config CPU_FREQ_TABLE · line 28
Quoted 3 lines · Viresh Kumar
drivers/cpufreq/Kconfig +3
-0+config CPU_FREQ_HAVE_MULTIPLE_POLICIES + bool +So I suppose some architectures will select this, right?
Yes. And they have to enable have_multiple_policies too from their drivers init code.
Quoted 1 line
What architecture they are?
Atleast all big.LITTLE SoCs. Or any other SoC that has multiple policy structs alive at any time.
Quoted 15 lines
I'm not really sure I like this. ->
include/linux/cpufreq.h static inline bool policy_is_shared(struct cpufreq_policy *policy) · line 152
Quoted 9 lines
static inline struct kobject *
get_governor_parent_kobj(struct cpufreq_policy *policy){include/linux/cpufreq.h +2
-0+#ifdef CONFIG_CPU_FREQ_HAVE_MULTIPLE_POLICIES if (policy->have_multiple_policies)return &policy->kobj; else +#endif return cpufreq_global_kobject;-> I wonder why don't you arrange things so that
policy->kobjis always returned, but it points tocpufreq_global_kobjectin case there's only one (i.e. makepolicy->kobja pointer)?
policy->kobj is a struct instance rather than a pointer and it is widely used within cpufreq.c. If you don't like this one then we can add another entry into struct policy like: gov_sysfs_parent.
Re: [PATCH V2 3/4] cpufreq: Add Kconfig option to enable/disable have_multiple_policies
Quoted 34 lines · Viresh Kumar
Quoted 7 lines · Rafael J. Wysocki
drivers/cpufreq/Kconfig config CPU_FREQ_TABLE · line 28
Quoted 3 lines · Viresh Kumar
drivers/cpufreq/Kconfig +3
-0+config CPU_FREQ_HAVE_MULTIPLE_POLICIES + bool +So I suppose some architectures will select this, right?
Yes. And they have to enable
have_multiple_policiestoo from their drivers init code.Quoted 1 line
What architecture they are?
Atleast all big.LITTLE SoCs. Or any other SoC that has multiple policy structs alive at any time.
Quoted 15 lines
I'm not really sure I like this. ->
include/linux/cpufreq.h static inline bool policy_is_shared(struct cpufreq_policy *policy) · line 152
Quoted 9 lines
static inline struct kobject *
get_governor_parent_kobj(struct cpufreq_policy *policy){include/linux/cpufreq.h +2
-0+#ifdef CONFIG_CPU_FREQ_HAVE_MULTIPLE_POLICIES if (policy->have_multiple_policies)return &policy->kobj; else +#endif return cpufreq_global_kobject;-> I wonder why don't you arrange things so that
policy->kobjis always returned, but it points tocpufreq_global_kobjectin case there's only one (i.e. makepolicy->kobja pointer)?
Quoted 2 lines
policy->kobjis a struct instance rather than a pointer and it is widely used withincpufreq.c.
Yeah, policy attributes. Never mind.
Quoted 2 lines
If you don't like this one then we can add another entry into struct policy like:
gov_sysfs_parent.
I don't know. This is going to look kind of ugly this way or another I think.
Maybe I'll figure out something ...
Thanks,
Rafael
Signature · 2 lines
I speak only for myself. Rafael J. Wysocki, Intel Open Source Technology Center.
Viresh Kumar
maintainerRe: [PATCH V2 3/4] cpufreq: Add Kconfig option to enable/disable have_multiple_policies
Quoted 8 lines · Rafael J. Wysocki
Quoted 2 lines · Viresh Kumar
If you don't like this one then we can add another entry into struct policy like:
gov_sysfs_parent.I don't know. This is going to look kind of ugly this way or another I think.
Maybe I'll figure out something ...
Another simple way of doing this is, leave this patch and here is why i say so.
struct policy is allocated dynamically with kzalloc and so every field is zero including have_multiple_policies. And only the platforms needing this feature would make it 1 and all remaining ones would stay unchanged.
This variable would waste just "4" bytes for platforms that don't need this feature.
About performance: This if/else is called only on policy creation or destruction.
For platforms that doesn't have multiple policies and thus all cpus share the same policy struct, the destruction might never happen unless we rmmod/insmod cpufreq driver, because policy destruction would only happen when all the cpus are removed :)
So it will execute only once at boot time when we initialize policy struct.
Is this patch worth keeping then?
--
viresh
Viresh Kumar
maintainerPATCH v2 4/4 cpufreq: Get rid of "struct global_attr"
In reply to Viresh KumarWe don't need to keep two structures for file attributes, global_attr and freq_attr. Lets use freq_attr only for cpufreq core and drivers.
--- drivers/cpufreq/acpi-cpufreq.c | 9 ++++----- drivers/cpufreq/intel_pstate.c | 30 +++++++++++++++--------------- include/linux/cpufreq.h | 16 ---------------- 3 files changed, 19 insertions(+), 36 deletions(-)
drivers/cpufreq/acpi-cpufreq.c +4 -5
@@ -160,19 +160,18 @@ static ssize_t _store_boost(const char *buf, size_t count)return count; } -static ssize_t store_global_boost (struct kobject *kobj,struct attribute *attr, -const char *buf,size_t count) +static ssize_t store_global_boost (struct cpufreq_policy *policy, +const char *buf,size_t count) {return _store_boost (buf, count); } -static ssize_t show_global_boost (struct kobject *kobj, -struct attribute *attr,char *buf) +static ssize_t show_global_boost (struct cpufreq_policy *policy,char *buf) {return sprintf (buf,"%u\n" , boost_enabled); } -static struct global_attr global_boost =__ATTR (boost,0644 , +static struct freq_attr global_boost =__ATTR (boost,0644 , show_global_boost, store_global_boost);
drivers/cpufreq/intel_pstate.c +15 -15
@@ -273,15 +273,15 @@ static void intel_pstate_debug_expose_params(void)/************************** debugfs end ************************/ /************************** sysfs begin ************************/ -#define show_one (file_name, object) \ - static ssize_t show_##file_name \ - (struct kobject *kobj, struct attribute *attr, char *buf) \ - { \ - return sprintf(buf, "%u\n", limits.object); \ - } +#define show_one (file_name, object) \ +static ssize_t show_##file_name \ +(struct cpufreq_policy *policy, char *buf) \ +{ \ + return sprintf(buf, "%u\n", limits.object); \ +} -static ssize_t store_no_turbo (struct kobject *a,struct attribute *b, -const char *buf,size_t count) +static ssize_t store_no_turbo (struct cpufreq_policy *policy,const char *buf, +size_t count) {unsigned int input;int ret;
@@ -293,8 +293,8 @@ static ssize_t store_no_turbo(struct kobject *a, struct attribute *b,return count; } -static ssize_t store_max_perf_pct (struct kobject *a,struct attribute *b, -const char *buf,size_t count) +static ssize_t store_max_perf_pct (struct cpufreq_policy *policy, +const char *buf,size_t count) {unsigned int input;int ret;
@@ -307,8 +307,8 @@ static ssize_t store_max_perf_pct(struct kobject *a, struct attribute *b,return count; } -static ssize_t store_min_perf_pct (struct kobject *a,struct attribute *b, -const char *buf,size_t count) +static ssize_t store_min_perf_pct (struct cpufreq_policy *policy, +const char *buf,size_t count) {unsigned int input;int ret;
@@ -325,9 +325,9 @@ show_one(no_turbo, no_turbo);show_one (max_perf_pct, max_perf_pct);show_one (min_perf_pct, min_perf_pct); -define_one_global_rw (no_turbo); -define_one_global_rw (max_perf_pct); -define_one_global_rw (min_perf_pct); +cpufreq_freq_attr_rw (no_turbo); +cpufreq_freq_attr_rw (max_perf_pct); +cpufreq_freq_attr_rw (min_perf_pct);static struct attribute *intel_pstate_attributes[] = { &no_turbo.attr,
include/linux/cpufreq.h +0 -16
@@ -324,22 +324,6 @@ __ATTR(_name, _perm, show_##_name, NULL)static struct freq_attr _name = \ __ATTR(_name, 0644, show_##_name, store_##_name) -struct global_attr { -struct attribute attr; -ssize_t (*show)(struct kobject *kobj, -struct attribute *attr,char *buf); -ssize_t (*store)(struct kobject *a,struct attribute *b, -const char *c,size_t count); -}; - -#define define_one_global_ro (_name) \ -static struct global_attr _name = \ -__ATTR(_name, 0444, show_##_name, NULL) - -#define define_one_global_rw (_name) \ -static struct global_attr _name = \ -__ATTR(_name, 0644, show_##_name, store_##_name) -struct cpufreq_policy *cpufreq_cpu_get (unsigned int cpu);void cpufreq_cpu_put (struct cpufreq_policy *data);const char *cpufreq_get_current_driver (void );
Signature · 1 line
1.7.12.rc2.18.g61b472e
Re: [PATCH V2 4/4] cpufreq: Get rid of "struct global_attr"
Quoted 48 lines · Viresh Kumar
We don't need to keep two structures for file attributes,
global_attrandfreq_attr. Lets usefreq_attronly for cpufreq core and drivers.Signed-off-by Viresh Kumar <[email protected]>--- drivers/cpufreq/acpi-cpufreq.c | 9 ++++----- drivers/cpufreq/intel_pstate.c | 30 +++++++++++++++--------------- include/linux/cpufreq.h | 16 ---------------- 3 files changed, 19 insertions(+), 36 deletions(-)drivers/cpufreq/acpi-cpufreq.c +4
-5@@ -160,19 +160,18 @@ static ssize_t _store_boost(const char *buf, size_t count)return count; } -static ssize_t store_global_boost (struct kobject *kobj,struct attribute *attr, -const char *buf,size_t count) +static ssize_t store_global_boost (struct cpufreq_policy *policy, +const char *buf,size_t count) {return _store_boost (buf, count); } -static ssize_t show_global_boost (struct kobject *kobj, -struct attribute *attr,char *buf) +static ssize_t show_global_boost (struct cpufreq_policy *policy,char *buf) {return sprintf (buf,"%u\n" , boost_enabled); } -static struct global_attr global_boost =__ATTR (boost,0644 , +static struct freq_attr global_boost =__ATTR (boost,0644 , show_global_boost, store_global_boost);drivers/cpufreq/intel_pstate.c +0
-2@@ -273,15 +273,15 @@ static void intel_pstate_debug_expose_params(void)/************************** debugfs end ************************/ /************************** sysfs begin ************************/ -#define show_one (file_name, object) \ - static ssize_t show_##file_name \
drivers/cpufreq/intel_pstate.c static void intel_pstate_debug_expose_params(void) · line 281
Quoted 10 lines
drivers/cpufreq/intel_pstate.c +6
-4- (struct kobject *kobj, struct attribute *attr, char *buf) \ - { \ -return sprintf (buf,"%u\n" , limits.object); \ - } +#define show_one (file_name, object) \ +static ssize_t show_##file_name \ +(struct cpufreq_policy *policy, char *buf) \ +{ \ + return sprintf(buf, "%u\n", limits.object); \ +}
Why did you change all of the lines of this macro instead of changing just the one line you needed to change?
Please don't do that.
Quoted 59 lines
drivers/cpufreq/intel_pstate.c +9
-9-static ssize_t store_no_turbo (struct kobject *a,struct attribute *b, -const char *buf,size_t count) +static ssize_t store_no_turbo (struct cpufreq_policy *policy,const char *buf, +size_t count) {unsigned int input;int ret;@@ -293,8 +293,8 @@ static ssize_t store_no_turbo(struct kobject *a, struct attribute *b,return count; } -static ssize_t store_max_perf_pct (struct kobject *a,struct attribute *b, -const char *buf,size_t count) +static ssize_t store_max_perf_pct (struct cpufreq_policy *policy, +const char *buf,size_t count) {unsigned int input;int ret;@@ -307,8 +307,8 @@ static ssize_t store_max_perf_pct(struct kobject *a, struct attribute *b,return count; } -static ssize_t store_min_perf_pct (struct kobject *a,struct attribute *b, -const char *buf,size_t count) +static ssize_t store_min_perf_pct (struct cpufreq_policy *policy, +const char *buf,size_t count) {unsigned int input;int ret;@@ -325,9 +325,9 @@ show_one(no_turbo, no_turbo);show_one (max_perf_pct, max_perf_pct);show_one (min_perf_pct, min_perf_pct); -define_one_global_rw (no_turbo); -define_one_global_rw (max_perf_pct); -define_one_global_rw (min_perf_pct); +cpufreq_freq_attr_rw (no_turbo); +cpufreq_freq_attr_rw (max_perf_pct); +cpufreq_freq_attr_rw (min_perf_pct);static struct attribute *intel_pstate_attributes[] = { &no_turbo.attr,include/linux/cpufreq.h +0
-9@@ -324,22 +324,6 @@ __ATTR(_name, _perm, show_##_name, NULL)static struct freq_attr _name = \ __ATTR(_name, 0644, show_##_name, store_##_name) -struct global_attr { -struct attribute attr; -ssize_t (*show)(struct kobject *kobj, -struct attribute *attr,char *buf); -ssize_t (*store)(struct kobject *a,struct attribute *b, -const char *c,size_t count); -}; - -#define define_one_global_ro (_name) \
include/linux/cpufreq.h __ATTR(_name, _perm, show_##_name, NULL) · line 329
Quoted 10 lines
include/linux/cpufreq.h +0
-7-static struct global_attr _name = \ -__ATTR(_name, 0444, show_##_name, NULL) - -#define define_one_global_rw (_name) \ -static struct global_attr _name = \ -__ATTR(_name, 0644, show_##_name, store_##_name) -struct cpufreq_policy *cpufreq_cpu_get (unsigned int cpu);void cpufreq_cpu_put (struct cpufreq_policy *data);const char *cpufreq_get_current_driver (void );
Thanks,
Rafael
Signature · 2 lines
I speak only for myself. Rafael J. Wysocki, Intel Open Source Technology Center.
Viresh Kumar
maintainerRe: [PATCH V2 4/4] cpufreq: Get rid of "struct global_attr"
Quoted 2 lines · Rafael J. Wysocki
Why did you change all of the lines of this macro instead of changing just the one line you needed to change?
I didn't like the indentation used within the macro. So did it.
Quoted 1 line
Please don't do that.
Okay.
Re: [PATCH V2 4/4] cpufreq: Get rid of "struct global_attr"
Quoted 5 lines · Viresh Kumar
Quoted 2 lines · Rafael J. Wysocki
Why did you change all of the lines of this macro instead of changing just the one line you needed to change?
I didn't like the indentation used within the macro. So did it.
In general, things like that are for separate cleanup patches. If you mix functional changes with cleanups, poeple get confused and it's difficult to see what's needed and what's "optional".
I know it's tempting to fix stuff like that along with doing functional changes and I do that sometimes. Not very often, though, and with care.
Thanks,
Rafael
Signature · 2 lines
I speak only for myself. Rafael J. Wysocki, Intel Open Source Technology Center.
Viresh Kumar
maintainerRe: [PATCH V2 4/4] cpufreq: Get rid of "struct global_attr"
Quoted 5 lines · Rafael J. Wysocki
Quoted 4 lines · Viresh Kumar
Quoted 2 lines · Rafael J. Wysocki
Why did you change all of the lines of this macro instead of changing just the one line you needed to change?
Quoted 8 lines
Quoted 1 line
I didn't like the indentation used within the macro. So did it.
In general, things like that are for separate cleanup patches. If you mix functional changes with cleanups, poeple get confused and it's difficult to see what's needed and what's "optional".
I know it's tempting to fix stuff like that along with doing functional changes and I do that sometimes. Not very often, though, and with care.
Even i give similar comments sometimes but forget these while writing my patches :)
Anyway, fixup:
commit b1bbb99467d56140cf3a8a2b70e61b456aa46e48
Author: Viresh Kumar <[email protected]> Date: Fri Feb 22 07:59:20 2013 +0530
fixup! cpufreq: Get rid of "struct global_attr"
--- drivers/cpufreq/intel_pstate.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
drivers/cpufreq/intel_pstate.c +6 -6
@@ -273,12 +273,12 @@ static void intel_pstate_debug_expose_params(void)/************************** debugfs end ************************/ /************************** sysfs begin ************************/ -#define show_one (file_name, object) \ -static ssize_t show_##file_name \ -(struct cpufreq_policy *policy, char *buf) \ -{ \ - return sprintf(buf, "%u\n", limits.object); \ -} +#define show_one (file_name, object) \ + static ssize_t show_##file_name \ + (struct cpufreq_policy *policy, char *buf) \ + { \ + return sprintf(buf, "%u\n", limits.object); \ + }
Viresh Kumar
maintainerQuoted 1 line · Viresh Kumar
This is targetted for 3.10-rc1 or linux-next just after the merge window.
Hi Rafael,
I have pushed this patch again with the modifications/fixups i posted:
cpufreq-for-3.10
Also i have swapped patch 3 & 4, in case you decide to drop that Kconfig patch which is no. 4 now :)
--
viresh