Skip to contentSkip to conversation

CPUFreq: Implement per policy instances of governors

PATCH Superseded Viresh Kumar 2 participants 20 messages Feb 11, 2013 – Feb 22, 2013

Subsystems (2)

v2 of 4 Superseded Latest is v4 →

lore
Share & tools
lore

Viresh Kumar

author maintainer
#0 lore raw

v2 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
author maintainer
#1 lore raw

PATCH 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
index 04aab05..40f7083 100644
@@ -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
index a22944c..3b822ce 100644
@@ -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	4
 
 struct cpufreq_governor {
 	char	name[CPUFREQ_NAME_LEN];
Signature · 1 line
1.7.12.rc2.18.g61b472e
#2 lore raw

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 a governor_type in 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
---
 drivers/cpufreq/cpufreq.c | 21 ++++++++++++++++++---
 include/linux/cpufreq.h   |  9 ++++++---
 2 files changed, 24 insertions(+), 6 deletions(-)
drivers/cpufreq/cpufreq.c +18 -3
index 04aab05..40f7083 100644
@@ -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
index a22944c..3b822ce 100644
@@ -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.
author maintainer
#3 lore raw

Re: [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      4

Why 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.

#4 lore raw

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      4

Why 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.
author maintainer
#5 lore raw

Re: [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 :)

author maintainer
#6 lore raw

Re: [PATCH V2 1/4] cpufreq: Add per policy governor-init/exit infrastructure

In reply to Rafael J. Wysocki
Quoted 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
index 3b822ce..b7393b5 100644
@@ -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];
author maintainer
#7 lore raw

PATCH v2 2/4 cpufreq: governor: Implement per policy instances of governors

In reply to 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 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
index 40f7083..a9e5840 100644
@@ -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
index 3b822ce..c5ac9a5 100644
@@ -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	5
 
 struct 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
author maintainer
#8 lore raw

Re: [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. :)

author maintainer
#9 lore raw

PATCH v2 3/4 cpufreq: Add Kconfig option to enable/disable have_multiple_policies

In reply to Viresh Kumar

have_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
index cbcb21e..e6e6939 100644
@@ -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
index c5ac9a5..0d84bfa 100644
@@ -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
#10 lore raw

Re: [PATCH V2 3/4] cpufreq: Add Kconfig option to enable/disable have_multiple_policies

Quoted 16 lines · Viresh Kumar

have_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 +0 -0
index cbcb21e..e6e6939 100644

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 -0
 config CPU_FREQ_STAT
 	tristate "CPU frequency translation statistics"
 	select CPU_FREQ_TABLE
include/linux/cpufreq.h +0 -0
index c5ac9a5..0d84bfa 100644

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 -0
 	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;

-> 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.
author maintainer
#11 lore raw

Re: [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->kobj is always returned, but it points to cpufreq_global_kobject in case there's only one (i.e. make policy->kobj a 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.

#12 lore raw

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_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->kobj is always returned, but it points to cpufreq_global_kobject in case there's only one (i.e. make policy->kobj a pointer)?

Quoted 2 lines

policy->kobj is a struct instance rather than a pointer and it is widely used within cpufreq.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.
author maintainer
#13 lore raw

Re: [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

author maintainer
#14 lore raw

PATCH v2 4/4 cpufreq: Get rid of "struct global_attr"

In reply to Viresh Kumar

We 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
index 937bc28..14219c3 100644
@@ -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
index 86ad482..0f2d6a0 100644
@@ -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
index 0d84bfa..a092fcb 100644
@@ -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
#15 lore raw

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_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
index 937bc28..14219c3 100644
@@ -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
index 86ad482..0f2d6a0 100644
@@ -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
index 0d84bfa..a092fcb 100644
@@ -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.
author maintainer
#16 lore raw

Re: [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.

#17 lore raw

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.
author maintainer
#18 lore raw

Re: [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
index e795134..49846b9 100644
@@ -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);             \
+       }
author maintainer
#19 lore raw
In reply to Viresh Kumar
Quoted 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