linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/6] Add P state driver for Intel Core Processors
@ 2013-02-01 18:45 dirk.brandewie
  2013-02-01 18:45 ` [PATCH 1/6] cpufreq: Retrieve current frequency from scaling drivers with internal governors dirk.brandewie
                   ` (8 more replies)
  0 siblings, 9 replies; 17+ messages in thread
From: dirk.brandewie @ 2013-02-01 18:45 UTC (permalink / raw)
  To: linux-kernel, cpufreq; +Cc: Dirk Brandewie

From: Dirk Brandewie <dirk.brandewie@gmail.com>

This driver implements a scaling driver with an internal governor for
Intel Core processors.  The driver follows the same model as the
Transmeta scaling driver (longrun.c) and implements the setpolicy()
instead of target().  Scaling drivers that implement setpolicy() are
assmuned to implement internal governors by the cpufreq core. All the
logic for selecting the current P state is contained within the driver
no external governor is used by the cpufreq core.

At the moment only Intel SandyBridge processors are supported. As
testing on SandyBridge+ processors is completed support will be added
to the driver.

New sysfs files for controlling P state selection have been added to
/sys/devices/system/cpu/intel_pstate/
      max_perf_pct: limits the maximum P state that will be requested by
      the driver stated as a percentage of the avail performance.
    
      min_perf_pct: limits the minimum P state that will be  requested by
      the driver stated as a percentage of the avail performance.
    
      no_turbo: limits the driver to selecting P states below the turbo
      frequency range.

The units for these for these files are purposely abstract and stated
in terms of available performance and not frequency.  In idea that
frequency can be set to a single frequency is a fiction for Intel Core
processors. Even if the scaling driver selects a single P state the
actual frequency the processor will run at is selected by the
processor itself.

Based on v3.8-rc5.
Patches 1-5:
     Fix issues related to scaling drivers that implement the
     setpolicy() interface instead of target() when CONFIG_SMP and
     CONFIG_HOTPLUG_CPU are set.

Patch 6:
     The driver and associated config glue.

Dirk Brandewie (6):
  cpufreq: Retrieve current frequency from scaling drivers with
    internal governors
  cpufreq: Only query drivers that implement cpufreq_driver.target()
  cpufreq: Do not track governor name for scaling drivers with internal
    governors.
  cpufreq_stats: Do not track policies without associated governors.
  cpufreq: balance out cpufreq_cpu_{get,put} for scaling drivers using
    setpolicy
  cpufreq/x86: Add P-state driver for sandy bridge.

 drivers/cpufreq/Kconfig.x86     |   18 +
 drivers/cpufreq/Makefile        |    1 +
 drivers/cpufreq/cpufreq.c       |   43 ++-
 drivers/cpufreq/cpufreq_stats.c |    4 +-
 drivers/cpufreq/intel_pstate.c  |  830 +++++++++++++++++++++++++++++++++++++++
 5 files changed, 880 insertions(+), 16 deletions(-)
 create mode 100644 drivers/cpufreq/intel_pstate.c

-- 
1.7.7.6


^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH 1/6] cpufreq: Retrieve current frequency from scaling drivers with internal governors
  2013-02-01 18:45 [PATCH 0/6] Add P state driver for Intel Core Processors dirk.brandewie
@ 2013-02-01 18:45 ` dirk.brandewie
  2013-02-01 18:45 ` [PATCH 2/6] cpufreq: Only query drivers that implement cpufreq_driver.target() dirk.brandewie
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 17+ messages in thread
From: dirk.brandewie @ 2013-02-01 18:45 UTC (permalink / raw)
  To: linux-kernel, cpufreq; +Cc: Dirk Brandewie

From: Dirk Brandewie <dirk.j.brandewie@intel.com>

Scaling drivers that implement the cpufreq_driver.setpolicy() versus
the cpufreq_driver.target() interface do not set policy->cur.

Normally policy->cur is set during the call to cpufreq_driver.target()
when the frequnecy request is made by the governor.

If the scaling driver implements cpufreq_driver.setpolicy() and
cpufreq_driver.get() interfaces use cpufreq_driver.get() to retrieve
the current frequency.

Signed-off-by: Dirk Brandewie <dirk.j.brandewie@intel.com>
---
 drivers/cpufreq/cpufreq.c |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 1f93dbd..1c037f0 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -1219,6 +1219,9 @@ unsigned int cpufreq_quick_get(unsigned int cpu)
 	struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
 	unsigned int ret_freq = 0;
 
+	if (cpufreq_driver && cpufreq_driver->setpolicy && cpufreq_driver->get)
+		return cpufreq_driver->get(cpu);
+
 	if (policy) {
 		ret_freq = policy->cur;
 		cpufreq_cpu_put(policy);
-- 
1.7.7.6


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 2/6] cpufreq: Only query drivers that implement cpufreq_driver.target()
  2013-02-01 18:45 [PATCH 0/6] Add P state driver for Intel Core Processors dirk.brandewie
  2013-02-01 18:45 ` [PATCH 1/6] cpufreq: Retrieve current frequency from scaling drivers with internal governors dirk.brandewie
@ 2013-02-01 18:45 ` dirk.brandewie
  2013-02-02  3:22   ` Viresh Kumar
  2013-02-01 18:45 ` dirk.brandewie
                   ` (6 subsequent siblings)
  8 siblings, 1 reply; 17+ messages in thread
From: dirk.brandewie @ 2013-02-01 18:45 UTC (permalink / raw)
  To: linux-kernel, cpufreq; +Cc: Dirk Brandewie, Dirk Brandewie

From: Dirk Brandewie <dirk.brandewie@gmail.com>

Scaling drivers that implement cpufreq_driver.setpolicy() have
internal governors and may/will change the current operating frequency
very frequently this will cause cpufreq_out_of_sync() to be called
every time. Only call cpufreq_driver.get() for drivers that implement
cpufreq_driver.target()

Signed-off-by: Dirk Brandewie <dirk.j.brandewie@intel.com>
---
 drivers/cpufreq/cpufreq.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 1c037f0..493cd50 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -1794,7 +1794,7 @@ int cpufreq_update_policy(unsigned int cpu)
 
 	/* BIOS might change freq behind our back
 	  -> ask driver for current freq and notify governors about a change */
-	if (cpufreq_driver->get) {
+	if (cpufreq_driver->get && cpufreq_driver->target) {
 		policy.cur = cpufreq_driver->get(cpu);
 		if (!data->cur) {
 			pr_debug("Driver did not initialize current freq");
-- 
1.7.7.6


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 2/6] cpufreq: Only query drivers that implement cpufreq_driver.target()
  2013-02-01 18:45 [PATCH 0/6] Add P state driver for Intel Core Processors dirk.brandewie
  2013-02-01 18:45 ` [PATCH 1/6] cpufreq: Retrieve current frequency from scaling drivers with internal governors dirk.brandewie
  2013-02-01 18:45 ` [PATCH 2/6] cpufreq: Only query drivers that implement cpufreq_driver.target() dirk.brandewie
@ 2013-02-01 18:45 ` dirk.brandewie
  2013-02-01 18:45 ` [PATCH 3/6] cpufreq: Do not track governor name for scaling drivers with internal governors dirk.brandewie
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 17+ messages in thread
From: dirk.brandewie @ 2013-02-01 18:45 UTC (permalink / raw)
  To: linux-kernel, cpufreq; +Cc: Dirk Brandewie

From: Dirk Brandewie <dirk.j.brandewie@intel.com>

Scaling drivers that implement cpufreq_driver.setpolicy() have
internal governors and may/will change the current operating frequency
very frequently this will cause cpufreq_out_of_sync() to be called
every time. Only call cpufreq_driver.get() for drivers that implement
cpufreq_driver.target()

Signed-off-by: Dirk Brandewie <dirk.j.brandewie@intel.com>
---
 drivers/cpufreq/cpufreq.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 1c037f0..493cd50 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -1794,7 +1794,7 @@ int cpufreq_update_policy(unsigned int cpu)
 
 	/* BIOS might change freq behind our back
 	  -> ask driver for current freq and notify governors about a change */
-	if (cpufreq_driver->get) {
+	if (cpufreq_driver->get && cpufreq_driver->target) {
 		policy.cur = cpufreq_driver->get(cpu);
 		if (!data->cur) {
 			pr_debug("Driver did not initialize current freq");
-- 
1.7.7.6


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 3/6] cpufreq: Do not track governor name for scaling drivers with internal governors.
  2013-02-01 18:45 [PATCH 0/6] Add P state driver for Intel Core Processors dirk.brandewie
                   ` (2 preceding siblings ...)
  2013-02-01 18:45 ` dirk.brandewie
@ 2013-02-01 18:45 ` dirk.brandewie
  2013-02-02  3:25   ` Viresh Kumar
  2013-02-01 18:45 ` dirk.brandewie
                   ` (4 subsequent siblings)
  8 siblings, 1 reply; 17+ messages in thread
From: dirk.brandewie @ 2013-02-01 18:45 UTC (permalink / raw)
  To: linux-kernel, cpufreq; +Cc: Dirk Brandewie, Dirk Brandewie

From: Dirk Brandewie <dirk.brandewie@gmail.com>

Scaling drivers that implement internal governors do not have governor
structures assocaited with them.  Only track the name of the governor
associated with the CPU if the driver does not implement
cpufreq_driver.setpolicy()

Signed-off-by: Dirk Brandewie <dirk.j.brandewie@intel.com>
---
 drivers/cpufreq/cpufreq.c |   35 +++++++++++++++++++++--------------
 1 files changed, 21 insertions(+), 14 deletions(-)

diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 493cd50..a4fd51e 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -717,11 +717,13 @@ static int cpufreq_add_dev_policy(unsigned int cpu,
 #ifdef CONFIG_HOTPLUG_CPU
 	struct cpufreq_governor *gov;
 
-	gov = __find_governor(per_cpu(cpufreq_cpu_governor, cpu));
-	if (gov) {
-		policy->governor = gov;
-		pr_debug("Restoring governor %s for cpu %d\n",
-		       policy->governor->name, cpu);
+	if (!cpufreq_driver->setpolicy) {
+		gov = __find_governor(per_cpu(cpufreq_cpu_governor, cpu));
+		if (gov) {
+			policy->governor = gov;
+			pr_debug("Restoring governor %s for cpu %d\n",
+				policy->governor->name, cpu);
+		}
 	}
 #endif
 
@@ -1072,8 +1074,9 @@ static int __cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif
 #ifdef CONFIG_SMP
 
 #ifdef CONFIG_HOTPLUG_CPU
-	strncpy(per_cpu(cpufreq_cpu_governor, cpu), data->governor->name,
-			CPUFREQ_NAME_LEN);
+	if (!cpufreq_driver->setpolicy)
+		strncpy(per_cpu(cpufreq_cpu_governor, cpu),
+			data->governor->name, CPUFREQ_NAME_LEN);
 #endif
 
 	/* if we have other CPUs still registered, we need to unlink them,
@@ -1097,8 +1100,9 @@ static int __cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif
 				continue;
 			pr_debug("removing link for cpu %u\n", j);
 #ifdef CONFIG_HOTPLUG_CPU
-			strncpy(per_cpu(cpufreq_cpu_governor, j),
-				data->governor->name, CPUFREQ_NAME_LEN);
+			if (!cpufreq_driver->setpolicy)
+				strncpy(per_cpu(cpufreq_cpu_governor, j),
+					data->governor->name, CPUFREQ_NAME_LEN);
 #endif
 			cpu_dev = get_cpu_device(j);
 			kobj = &cpu_dev->kobj;
@@ -1628,11 +1632,14 @@ void cpufreq_unregister_governor(struct cpufreq_governor *governor)
 		return;
 
 #ifdef CONFIG_HOTPLUG_CPU
-	for_each_present_cpu(cpu) {
-		if (cpu_online(cpu))
-			continue;
-		if (!strcmp(per_cpu(cpufreq_cpu_governor, cpu), governor->name))
-			strcpy(per_cpu(cpufreq_cpu_governor, cpu), "\0");
+	if (!cpufreq_driver->setpolicy)
+		for_each_present_cpu(cpu) {
+			if (cpu_online(cpu))
+				continue;
+			if (!strcmp(per_cpu(cpufreq_cpu_governor, cpu),
+					governor->name))
+				strcpy(per_cpu(cpufreq_cpu_governor, cpu),
+					"\0");
 	}
 #endif
 
-- 
1.7.7.6


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 3/6] cpufreq: Do not track governor name for scaling drivers with internal governors.
  2013-02-01 18:45 [PATCH 0/6] Add P state driver for Intel Core Processors dirk.brandewie
                   ` (3 preceding siblings ...)
  2013-02-01 18:45 ` [PATCH 3/6] cpufreq: Do not track governor name for scaling drivers with internal governors dirk.brandewie
@ 2013-02-01 18:45 ` dirk.brandewie
  2013-02-01 18:45 ` [PATCH 4/6] cpufreq_stats: Do not track policies without associated governors dirk.brandewie
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 17+ messages in thread
From: dirk.brandewie @ 2013-02-01 18:45 UTC (permalink / raw)
  To: linux-kernel, cpufreq; +Cc: Dirk Brandewie

From: Dirk Brandewie <dirk.j.brandewie@intel.com>

Scaling drivers that implement internal governors do not have governor
structures assocaited with them.  Only track the name of the governor
associated with the CPU if the driver does not implement
cpufreq_driver.setpolicy()

Signed-off-by: Dirk Brandewie <dirk.j.brandewie@intel.com>
---
 drivers/cpufreq/cpufreq.c |   35 +++++++++++++++++++++--------------
 1 files changed, 21 insertions(+), 14 deletions(-)

diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 493cd50..a4fd51e 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -717,11 +717,13 @@ static int cpufreq_add_dev_policy(unsigned int cpu,
 #ifdef CONFIG_HOTPLUG_CPU
 	struct cpufreq_governor *gov;
 
-	gov = __find_governor(per_cpu(cpufreq_cpu_governor, cpu));
-	if (gov) {
-		policy->governor = gov;
-		pr_debug("Restoring governor %s for cpu %d\n",
-		       policy->governor->name, cpu);
+	if (!cpufreq_driver->setpolicy) {
+		gov = __find_governor(per_cpu(cpufreq_cpu_governor, cpu));
+		if (gov) {
+			policy->governor = gov;
+			pr_debug("Restoring governor %s for cpu %d\n",
+				policy->governor->name, cpu);
+		}
 	}
 #endif
 
@@ -1072,8 +1074,9 @@ static int __cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif
 #ifdef CONFIG_SMP
 
 #ifdef CONFIG_HOTPLUG_CPU
-	strncpy(per_cpu(cpufreq_cpu_governor, cpu), data->governor->name,
-			CPUFREQ_NAME_LEN);
+	if (!cpufreq_driver->setpolicy)
+		strncpy(per_cpu(cpufreq_cpu_governor, cpu),
+			data->governor->name, CPUFREQ_NAME_LEN);
 #endif
 
 	/* if we have other CPUs still registered, we need to unlink them,
@@ -1097,8 +1100,9 @@ static int __cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif
 				continue;
 			pr_debug("removing link for cpu %u\n", j);
 #ifdef CONFIG_HOTPLUG_CPU
-			strncpy(per_cpu(cpufreq_cpu_governor, j),
-				data->governor->name, CPUFREQ_NAME_LEN);
+			if (!cpufreq_driver->setpolicy)
+				strncpy(per_cpu(cpufreq_cpu_governor, j),
+					data->governor->name, CPUFREQ_NAME_LEN);
 #endif
 			cpu_dev = get_cpu_device(j);
 			kobj = &cpu_dev->kobj;
@@ -1628,11 +1632,14 @@ void cpufreq_unregister_governor(struct cpufreq_governor *governor)
 		return;
 
 #ifdef CONFIG_HOTPLUG_CPU
-	for_each_present_cpu(cpu) {
-		if (cpu_online(cpu))
-			continue;
-		if (!strcmp(per_cpu(cpufreq_cpu_governor, cpu), governor->name))
-			strcpy(per_cpu(cpufreq_cpu_governor, cpu), "\0");
+	if (!cpufreq_driver->setpolicy)
+		for_each_present_cpu(cpu) {
+			if (cpu_online(cpu))
+				continue;
+			if (!strcmp(per_cpu(cpufreq_cpu_governor, cpu),
+					governor->name))
+				strcpy(per_cpu(cpufreq_cpu_governor, cpu),
+					"\0");
 	}
 #endif
 
-- 
1.7.7.6


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 4/6] cpufreq_stats: Do not track policies without associated governors.
  2013-02-01 18:45 [PATCH 0/6] Add P state driver for Intel Core Processors dirk.brandewie
                   ` (4 preceding siblings ...)
  2013-02-01 18:45 ` dirk.brandewie
@ 2013-02-01 18:45 ` dirk.brandewie
  2013-02-02  5:38   ` Viresh Kumar
  2013-02-01 18:45 ` dirk.brandewie
                   ` (2 subsequent siblings)
  8 siblings, 1 reply; 17+ messages in thread
From: dirk.brandewie @ 2013-02-01 18:45 UTC (permalink / raw)
  To: linux-kernel, cpufreq; +Cc: Dirk Brandewie, Dirk Brandewie

From: Dirk Brandewie <dirk.brandewie@gmail.com>

Scaling drivers that implement internal governors do not have governor
sturctures associated with them.  Do not create/remove statisitcs
entries for polices that do not have governors associated with them.

Signed-off-by: Dirk Brandewie <dirk.j.brandewie@intel.com>
---
 drivers/cpufreq/cpufreq_stats.c |    4 +++-
 1 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/drivers/cpufreq/cpufreq_stats.c b/drivers/cpufreq/cpufreq_stats.c
index 9d7732b..8a1daf4 100644
--- a/drivers/cpufreq/cpufreq_stats.c
+++ b/drivers/cpufreq/cpufreq_stats.c
@@ -183,7 +183,7 @@ static void cpufreq_stats_free_table(unsigned int cpu)
 static void cpufreq_stats_free_sysfs(unsigned int cpu)
 {
 	struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
-	if (policy && policy->cpu == cpu)
+	if (policy && policy->cpu == cpu && policy->governor)
 		sysfs_remove_group(&policy->kobj, &stats_attr_group);
 	if (policy)
 		cpufreq_cpu_put(policy);
@@ -271,6 +271,8 @@ static int cpufreq_stat_notifier_policy(struct notifier_block *nb,
 	unsigned int cpu = policy->cpu;
 	if (val != CPUFREQ_NOTIFY)
 		return 0;
+	if (!policy->governor)
+		return 0;
 	table = cpufreq_frequency_get_table(cpu);
 	if (!table)
 		return 0;
-- 
1.7.7.6


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 4/6] cpufreq_stats: Do not track policies without associated governors.
  2013-02-01 18:45 [PATCH 0/6] Add P state driver for Intel Core Processors dirk.brandewie
                   ` (5 preceding siblings ...)
  2013-02-01 18:45 ` [PATCH 4/6] cpufreq_stats: Do not track policies without associated governors dirk.brandewie
@ 2013-02-01 18:45 ` dirk.brandewie
  2013-02-01 18:45 ` [PATCH 5/6] cpufreq: balance out cpufreq_cpu_{get,put} for scaling drivers using setpolicy dirk.brandewie
  2013-02-01 18:45 ` [PATCH 6/6] cpufreq/x86: Add P-state driver for sandy bridge dirk.brandewie
  8 siblings, 0 replies; 17+ messages in thread
From: dirk.brandewie @ 2013-02-01 18:45 UTC (permalink / raw)
  To: linux-kernel, cpufreq; +Cc: Dirk Brandewie

From: Dirk Brandewie <dirk.j.brandewie@intel.com>

Scaling drivers that implement internal governors do not have governor
sturctures associated with them.  Do not create/remove statisitcs
entries for polices that do not have governors associated with them.

Signed-off-by: Dirk Brandewie <dirk.j.brandewie@intel.com>
---
 drivers/cpufreq/cpufreq_stats.c |    4 +++-
 1 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/drivers/cpufreq/cpufreq_stats.c b/drivers/cpufreq/cpufreq_stats.c
index 9d7732b..8a1daf4 100644
--- a/drivers/cpufreq/cpufreq_stats.c
+++ b/drivers/cpufreq/cpufreq_stats.c
@@ -183,7 +183,7 @@ static void cpufreq_stats_free_table(unsigned int cpu)
 static void cpufreq_stats_free_sysfs(unsigned int cpu)
 {
 	struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
-	if (policy && policy->cpu == cpu)
+	if (policy && policy->cpu == cpu && policy->governor)
 		sysfs_remove_group(&policy->kobj, &stats_attr_group);
 	if (policy)
 		cpufreq_cpu_put(policy);
@@ -271,6 +271,8 @@ static int cpufreq_stat_notifier_policy(struct notifier_block *nb,
 	unsigned int cpu = policy->cpu;
 	if (val != CPUFREQ_NOTIFY)
 		return 0;
+	if (!policy->governor)
+		return 0;
 	table = cpufreq_frequency_get_table(cpu);
 	if (!table)
 		return 0;
-- 
1.7.7.6


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 5/6] cpufreq: balance out cpufreq_cpu_{get,put} for scaling drivers using setpolicy
  2013-02-01 18:45 [PATCH 0/6] Add P state driver for Intel Core Processors dirk.brandewie
                   ` (6 preceding siblings ...)
  2013-02-01 18:45 ` dirk.brandewie
@ 2013-02-01 18:45 ` dirk.brandewie
  2013-02-02  5:41   ` Viresh Kumar
  2013-02-01 18:45 ` [PATCH 6/6] cpufreq/x86: Add P-state driver for sandy bridge dirk.brandewie
  8 siblings, 1 reply; 17+ messages in thread
From: dirk.brandewie @ 2013-02-01 18:45 UTC (permalink / raw)
  To: linux-kernel, cpufreq; +Cc: Dirk Brandewie

From: Dirk Brandewie <dirk.brandewie@gmail.com>

There is an additional reference added to the driver in
cpufreq_add_dev_policy() that is removed in__cpufreq_governor() if the
driver implements target().  Remove the last reference when the driver
implements setpolicy()

Signed-off-by: Dirk Brandewie <dirk.brandewie@gmail.com>
---
 drivers/cpufreq/cpufreq.c |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index a4fd51e..ec103bf 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -1119,6 +1119,9 @@ static int __cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif
 	if (cpufreq_driver->target)
 		__cpufreq_governor(data, CPUFREQ_GOV_STOP);
 
+	if (cpufreq_driver->setpolicy)
+		cpufreq_cpu_put(data);
+
 	kobj = &data->kobj;
 	cmp = &data->kobj_unregister;
 	unlock_policy_rwsem_write(cpu);
-- 
1.7.7.6


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 6/6] cpufreq/x86: Add P-state driver for sandy bridge.
  2013-02-01 18:45 [PATCH 0/6] Add P state driver for Intel Core Processors dirk.brandewie
                   ` (7 preceding siblings ...)
  2013-02-01 18:45 ` [PATCH 5/6] cpufreq: balance out cpufreq_cpu_{get,put} for scaling drivers using setpolicy dirk.brandewie
@ 2013-02-01 18:45 ` dirk.brandewie
  8 siblings, 0 replies; 17+ messages in thread
From: dirk.brandewie @ 2013-02-01 18:45 UTC (permalink / raw)
  To: linux-kernel, cpufreq; +Cc: Dirk Brandewie, Dirk Brandewie

From: Dirk Brandewie <dirk.brandewie@gmail.com>

Add a P-state driver for the Intel Sandy bridge processor. In cpufreq
terminology this driver implements a  scaling driver with an internal
governor.

When built into the the kernel this driver will be the preferred
scaling driver for Sandy bridge processors.

In addition to the interfaces provided by the cpufreq subsystem for
controlling scaling drivers. The user may control the behavior of the
driver via three sysfs files located in
"/sys/devices/system/cpu/intel_pstate".

  max_perf_pct: limits the maximum P state that will be requested by
  the driver stated as a percentage of the avail performance.

  min_perf_pct: limits the minimum P state that will be  requested by
  the driver stated as a percentage of the avail performance.

  no_turbo: limits the driver to selecting P states below the turbo
  frequency range.

Signed-off-by: Dirk Brandewie <dirk.j.brandewie@intel.com>
---
 drivers/cpufreq/Kconfig.x86    |   18 +
 drivers/cpufreq/Makefile       |    1 +
 drivers/cpufreq/intel_pstate.c |  829 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 848 insertions(+), 0 deletions(-)
 create mode 100644 drivers/cpufreq/intel_pstate.c

diff --git a/drivers/cpufreq/Kconfig.x86 b/drivers/cpufreq/Kconfig.x86
index 7227cd7..6aa7053 100644
--- a/drivers/cpufreq/Kconfig.x86
+++ b/drivers/cpufreq/Kconfig.x86
@@ -2,6 +2,24 @@
 # x86 CPU Frequency scaling drivers
 #
 
+config X86_INTEL_PSTATE
+       tristate "Intel P state control"
+       depends on X86
+       help
+          This driver provides a P state for Intel core processors.
+	  The driver implements an internal governor and will become
+          the scaling driver and governor for Sandy bridge processors.
+
+	  When this driver is enabled it will become the perferred
+          scaling driver for Sandy bridge processors.
+
+	  Note: This driver should be built with the same settings as
+	  the other scaling drivers configured into the system
+	  (module/built-in) in order for the driver to register itself
+	  as the scaling driver on the system.
+
+	  If in doubt, say N.
+
 config X86_PCC_CPUFREQ
 	tristate "Processor Clocking Control interface driver"
 	depends on ACPI && ACPI_PROCESSOR
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
index fadc4d4..f806347 100644
--- a/drivers/cpufreq/Makefile
+++ b/drivers/cpufreq/Makefile
@@ -39,6 +39,7 @@ obj-$(CONFIG_X86_SPEEDSTEP_SMI)		+= speedstep-smi.o
 obj-$(CONFIG_X86_SPEEDSTEP_CENTRINO)	+= speedstep-centrino.o
 obj-$(CONFIG_X86_P4_CLOCKMOD)		+= p4-clockmod.o
 obj-$(CONFIG_X86_CPUFREQ_NFORCE2)	+= cpufreq-nforce2.o
+obj-$(CONFIG_X86_INTEL_PSTATE)		+= intel_pstate.o
 
 ##################################################################################
 # ARM SoC drivers
diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c
new file mode 100644
index 0000000..f72e2a6
--- /dev/null
+++ b/drivers/cpufreq/intel_pstate.c
@@ -0,0 +1,829 @@
+/*
+ * cpufreq_snb.c: Native P state management for Intel processors
+ *
+ * (C) Copyright 2012 Intel Corporation
+ * Author: Dirk Brandewie <dirk.j.brandewie@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; version 2
+ * of the License.
+ */
+
+#include <linux/kernel.h>
+#include <linux/kernel_stat.h>
+#include <linux/module.h>
+#include <linux/ktime.h>
+#include <linux/hrtimer.h>
+#include <linux/tick.h>
+#include <linux/slab.h>
+#include <linux/sched.h>
+#include <linux/list.h>
+#include <linux/cpu.h>
+#include <linux/cpufreq.h>
+#include <linux/sysfs.h>
+#include <linux/types.h>
+#include <linux/fs.h>
+#include <linux/debugfs.h>
+#include <trace/events/power.h>
+
+#include <asm/div64.h>
+#include <asm/msr.h>
+#include <asm/cpu_device_id.h>
+
+#define SAMPLE_COUNT		3
+
+#define FRAC_BITS 8
+#define int_tofp(X) ((int64_t)(X) << FRAC_BITS)
+#define fp_toint(X) ((X) >> FRAC_BITS)
+
+static inline int32_t mul_fp(int32_t x, int32_t y)
+{
+	return ((int64_t)x * (int64_t)y) >> FRAC_BITS;
+}
+
+static inline int32_t div_fp(int32_t x, int32_t y)
+{
+	return div_s64((int64_t)x << FRAC_BITS, (int64_t)y);
+}
+
+struct sample {
+	ktime_t start_time;
+	ktime_t end_time;
+	int core_pct_busy;
+	int pstate_pct_busy;
+	u64 duration_us;
+	u64 idletime_us;
+	u64 aperf;
+	u64 mperf;
+	int freq;
+};
+
+struct pstate_data {
+	int	current_pstate;
+	int	min_pstate;
+	int	max_pstate;
+	int	turbo_pstate;
+};
+
+struct _pid {
+	int setpoint;
+	int32_t integral;
+	int32_t p_gain;
+	int32_t i_gain;
+	int32_t d_gain;
+	int deadband;
+	int last_err;
+};
+
+struct cpudata {
+	int cpu;
+
+	char name[64];
+
+	struct timer_list timer;
+
+	struct pstate_adjust_policy *pstate_policy;
+	struct pstate_data pstate;
+	struct _pid pid;
+	struct _pid idle_pid;
+
+	int min_pstate_count;
+	int idle_mode;
+
+	ktime_t prev_sample;
+	u64	prev_idle_time_us;
+	u64	prev_aperf;
+	u64	prev_mperf;
+	int	sample_ptr;
+	struct sample samples[SAMPLE_COUNT];
+};
+
+struct cpudata **all_cpu_data;
+struct pstate_adjust_policy {
+	int sample_rate_ms;
+	int deadband;
+	int setpoint;
+	int p_gain_pct;
+	int d_gain_pct;
+	int i_gain_pct;
+};
+
+static struct pstate_adjust_policy default_policy = {
+	.sample_rate_ms = 10,
+	.deadband = 0,
+	.setpoint = 109,
+	.p_gain_pct = 17,
+	.d_gain_pct = 0,
+	.i_gain_pct = 4,
+};
+
+struct perf_limits {
+	int no_turbo;
+	int max_perf_pct;
+	int min_perf_pct;
+	int32_t max_perf;
+	int32_t min_perf;
+};
+
+static struct perf_limits limits = {
+	.no_turbo = 0,
+	.max_perf_pct = 100,
+	.max_perf = int_tofp(1),
+	.min_perf_pct = 0,
+	.min_perf = 0,
+};
+
+static inline void pid_reset(struct _pid *pid, int setpoint, int busy,
+			int deadband, int integral) {
+	pid->setpoint = setpoint;
+	pid->deadband  = deadband;
+	pid->integral  = int_tofp(integral);
+	pid->last_err  = setpoint - busy;
+}
+
+static inline void pid_p_gain_set(struct _pid *pid, int percent)
+{
+	pid->p_gain = div_fp(int_tofp(percent), int_tofp(100));
+}
+
+static inline void pid_i_gain_set(struct _pid *pid, int percent)
+{
+	pid->i_gain = div_fp(int_tofp(percent), int_tofp(100));
+}
+
+static inline void pid_d_gain_set(struct _pid *pid, int percent)
+{
+
+	pid->d_gain = div_fp(int_tofp(percent), int_tofp(100));
+}
+
+static  signed int pid_calc(struct _pid *pid, int busy)
+{
+	signed int err, result;
+	int32_t pterm, dterm, fp_error;
+	int32_t integral_limit;
+
+
+	err = pid->setpoint - busy;
+	fp_error = int_tofp(err);
+
+	if (abs(err) <= pid->deadband)
+		return 0;
+
+	pterm = mul_fp(pid->p_gain, fp_error);
+
+	pid->integral += fp_error;
+
+	/* limit the integral term */
+	integral_limit = int_tofp(30);
+	if (pid->integral > integral_limit)
+		pid->integral = integral_limit;
+	if (pid->integral < -integral_limit)
+		pid->integral = -integral_limit;
+
+	dterm = mul_fp(pid->d_gain, (err - pid->last_err));
+	pid->last_err = err;
+
+	result = pterm + mul_fp(pid->integral, pid->i_gain) + dterm;
+
+	return (signed int)fp_toint(result);
+}
+
+
+static inline void intel_pstate_busy_pid_reset(struct cpudata *cpu)
+{
+	pid_p_gain_set(&cpu->pid, cpu->pstate_policy->p_gain_pct);
+	pid_d_gain_set(&cpu->pid, cpu->pstate_policy->d_gain_pct);
+	pid_i_gain_set(&cpu->pid, cpu->pstate_policy->i_gain_pct);
+
+	pid_reset(&cpu->pid,
+		cpu->pstate_policy->setpoint,
+		100,
+		cpu->pstate_policy->deadband,
+		0);
+
+}
+
+static inline void intel_pstate_idle_pid_reset(struct cpudata *cpu)
+{
+	pid_p_gain_set(&cpu->idle_pid, cpu->pstate_policy->p_gain_pct);
+	pid_d_gain_set(&cpu->idle_pid, cpu->pstate_policy->d_gain_pct);
+	pid_i_gain_set(&cpu->idle_pid, cpu->pstate_policy->i_gain_pct);
+
+	pid_reset(&cpu->idle_pid,
+		75,
+		50,
+		cpu->pstate_policy->deadband,
+		0);
+}
+
+static inline void intel_pstate_reset_all_pid(void)
+{
+	unsigned int cpu;
+	for_each_online_cpu(cpu) {
+		if (all_cpu_data[cpu])
+			intel_pstate_busy_pid_reset(all_cpu_data[cpu]);
+	}
+}
+
+/************************** debugfs begin ************************/
+static int pid_param_set(void *data, u64 val)
+{
+	*(u32 *)data = val;
+	intel_pstate_reset_all_pid();
+	return 0;
+}
+static int pid_param_get(void *data, u64 *val)
+{
+	*val = *(u32 *)data;
+	return 0;
+}
+DEFINE_SIMPLE_ATTRIBUTE(fops_pid_param, pid_param_get,
+			pid_param_set, "%llu\n");
+
+struct pid_param {
+	char *name;
+	void *value;
+};
+
+static struct pid_param pid_files[] = {
+	{"sample_rate_ms", &default_policy.sample_rate_ms},
+	{"d_gain_pct", &default_policy.d_gain_pct},
+	{"i_gain_pct", &default_policy.i_gain_pct},
+	{"deadband", &default_policy.deadband},
+	{"setpoint", &default_policy.setpoint},
+	{"p_gain_pct", &default_policy.p_gain_pct},
+	{NULL, NULL}
+};
+
+struct dentry *debugfs_parent;
+void intel_pstate_debug_expose_params(void)
+{
+	int i = 0;
+
+	debugfs_parent = debugfs_create_dir("pstate_snb", NULL);
+	if (IS_ERR_OR_NULL(debugfs_parent))
+		return;
+	while (pid_files[i].name) {
+		debugfs_create_file(pid_files[i].name, 0660,
+				debugfs_parent, pid_files[i].value,
+				&fops_pid_param);
+		i++;
+	}
+
+}
+
+/************************** 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);	\
+	}
+
+static ssize_t store_no_turbo(struct kobject *a, struct attribute *b,
+				const char *buf, size_t count)
+{
+	unsigned int input;
+	int ret;
+	ret = sscanf(buf, "%u", &input);
+	if (ret != 1)
+		return -EINVAL;
+	limits.no_turbo =  clamp_t(int, input, 0 , 1);
+
+	return count;
+}
+
+static ssize_t store_max_perf_pct(struct kobject *a, struct attribute *b,
+				const char *buf, size_t count)
+{
+	unsigned int input;
+	int ret;
+	ret = sscanf(buf, "%u", &input);
+	if (ret != 1)
+		return -EINVAL;
+
+	limits.max_perf_pct = clamp_t(int, input, 0 , 100);
+	limits.max_perf = div_fp(int_tofp(limits.max_perf_pct), int_tofp(100));
+	return count;
+}
+
+static ssize_t store_min_perf_pct(struct kobject *a, struct attribute *b,
+				const char *buf, size_t count)
+{
+	unsigned int input;
+	int ret;
+	ret = sscanf(buf, "%u", &input);
+	if (ret != 1)
+		return -EINVAL;
+	limits.min_perf_pct = clamp_t(int, input, 0 , 100);
+	limits.min_perf = div_fp(int_tofp(limits.min_perf_pct), int_tofp(100));
+
+	return count;
+}
+
+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);
+
+
+static struct attribute *intel_pstate_attributes[] = {
+	&no_turbo.attr,
+	&max_perf_pct.attr,
+	&min_perf_pct.attr,
+	NULL
+};
+
+static struct attribute_group intel_pstate_attr_group = {
+	.attrs = intel_pstate_attributes,
+};
+static struct kobject *intel_pstate_kobject;
+
+void intel_pstate_sysfs_expose_params(void)
+{
+	int rc;
+
+	intel_pstate_kobject = kobject_create_and_add("intel_pstate",
+						&cpu_subsys.dev_root->kobj);
+	BUG_ON(!intel_pstate_kobject);
+	rc = sysfs_create_group(intel_pstate_kobject,
+				&intel_pstate_attr_group);
+	BUG_ON(rc);
+}
+
+
+/************************** sysfs end ************************/
+
+static int intel_pstate_min_pstate(void)
+{
+	u64 value;
+	rdmsrl(0xCE, value);
+	return (value >> 40) & 0xFF;
+}
+
+static int intel_pstate_max_pstate(void)
+{
+	u64 value;
+	rdmsrl(0xCE, value);
+	return (value >> 8) & 0xFF;
+}
+
+static int intel_pstate_turbo_pstate(void)
+{
+	u64 value;
+	int nont, ret;
+	rdmsrl(0x1AD, value);
+	nont = intel_pstate_max_pstate();
+	ret = ((value) & 255);
+	if (ret <= nont)
+		ret = nont;
+	return ret;
+}
+
+static void intel_pstate_get_min_max(struct cpudata *cpu, int *min, int *max)
+{
+	int max_perf = cpu->pstate.turbo_pstate;
+	int min_perf;
+	if (limits.no_turbo)
+		max_perf = cpu->pstate.max_pstate;
+
+	max_perf = fp_toint(mul_fp(int_tofp(max_perf), limits.max_perf));
+	*max = clamp_t(int, max_perf,
+			cpu->pstate.min_pstate, cpu->pstate.turbo_pstate);
+
+	min_perf = fp_toint(mul_fp(int_tofp(max_perf), limits.min_perf));
+	*min = clamp_t(int, min_perf,
+			cpu->pstate.min_pstate, max_perf);
+}
+
+
+static void intel_pstate_set_pstate(struct cpudata *cpu, int pstate)
+{
+	int max_perf, min_perf;
+
+	intel_pstate_get_min_max(cpu, &min_perf, &max_perf);
+
+	pstate = clamp_t(int, pstate, min_perf, max_perf);
+
+	if (pstate == cpu->pstate.current_pstate)
+		return;
+
+
+#ifndef MODULE
+	trace_cpu_frequency(pstate * 100000, cpu->cpu);
+	trace_power_frequency(POWER_PSTATE, pstate * 100000, cpu->cpu);
+#endif
+	cpu->pstate.current_pstate = pstate;
+	wrmsrl(MSR_IA32_PERF_CTL, pstate << 8);
+
+}
+
+static inline void intel_pstate_pstate_increase(struct cpudata *cpu, int steps)
+{
+	int target;
+	target = cpu->pstate.current_pstate + steps;
+
+	intel_pstate_set_pstate(cpu, target);
+}
+
+static inline void intel_pstate_pstate_decrease(struct cpudata *cpu, int steps)
+{
+	int target;
+	target = cpu->pstate.current_pstate - steps;
+	intel_pstate_set_pstate(cpu, target);
+}
+
+static void intel_pstate_get_cpu_pstates(struct cpudata *cpu)
+{
+	sprintf(cpu->name, "Intel 2nd generation core");
+
+	cpu->pstate.min_pstate = intel_pstate_min_pstate();
+	cpu->pstate.max_pstate = intel_pstate_max_pstate();
+	cpu->pstate.turbo_pstate = intel_pstate_turbo_pstate();
+
+	/* goto max pstate so we don't slow up boot if we are built-in
+	   if we are a module we will take care of it during normal
+	   operation
+	*/
+	intel_pstate_set_pstate(cpu, cpu->pstate.max_pstate);
+}
+
+
+static inline void intel_pstate_calc_busy(struct cpudata *cpu,
+					struct sample *sample)
+{
+	u64 core_pct;
+	sample->pstate_pct_busy = 100 - div64_u64(
+					sample->idletime_us * 100,
+					sample->duration_us);
+	core_pct = div64_u64(sample->aperf * 100, sample->mperf);
+	sample->freq = cpu->pstate.turbo_pstate * core_pct * 1000;
+
+	sample->core_pct_busy = sample->pstate_pct_busy * core_pct / 100;
+}
+
+static inline int intel_pstate_sample(struct cpudata *cpu)
+{
+	ktime_t now;
+	u64 idle_time_us;
+	u64 aperf, mperf;
+
+	now = ktime_get();
+	idle_time_us = get_cpu_idle_time_us(cpu->cpu, NULL);
+
+	rdmsrl(MSR_IA32_APERF, aperf);
+	rdmsrl(MSR_IA32_MPERF, mperf);
+	/* for the first sample, don't actually record a sample, just
+	 * set the baseline */
+	if (cpu->prev_idle_time_us > 0) {
+		cpu->sample_ptr = (cpu->sample_ptr + 1) % SAMPLE_COUNT;
+		cpu->samples[cpu->sample_ptr].start_time = cpu->prev_sample;
+		cpu->samples[cpu->sample_ptr].end_time = now;
+		cpu->samples[cpu->sample_ptr].duration_us =
+			ktime_us_delta(now, cpu->prev_sample);
+		cpu->samples[cpu->sample_ptr].idletime_us =
+			idle_time_us - cpu->prev_idle_time_us;
+
+		cpu->samples[cpu->sample_ptr].aperf = aperf;
+		cpu->samples[cpu->sample_ptr].mperf = mperf;
+		cpu->samples[cpu->sample_ptr].aperf -= cpu->prev_aperf;
+		cpu->samples[cpu->sample_ptr].mperf -= cpu->prev_mperf;
+
+		intel_pstate_calc_busy(cpu, &cpu->samples[cpu->sample_ptr]);
+	}
+
+	cpu->prev_sample = now;
+	cpu->prev_idle_time_us = idle_time_us;
+	cpu->prev_aperf = aperf;
+	cpu->prev_mperf = mperf;
+	return cpu->sample_ptr;
+}
+
+static inline void intel_pstate_set_sample_time(struct cpudata *cpu)
+{
+	int sample_time;
+	int delay;
+
+	sample_time = cpu->pstate_policy->sample_rate_ms;
+	delay = msecs_to_jiffies(sample_time);
+	delay -= jiffies % delay;
+	mod_timer_pinned(&cpu->timer, jiffies + delay);
+}
+
+static inline void intel_pstate_idle_mode(struct cpudata *cpu)
+{
+	cpu->idle_mode = 1;
+}
+
+static inline void intel_pstate_normal_mode(struct cpudata *cpu)
+{
+	cpu->idle_mode = 0;
+}
+
+static inline int intel_pstate_get_scaled_busy(struct cpudata *cpu)
+{
+	int32_t busy_scaled;
+	int32_t core_busy, turbo_pstate, current_pstate;
+
+	core_busy    = int_tofp(cpu->samples[cpu->sample_ptr].core_pct_busy);
+	turbo_pstate   = int_tofp(cpu->pstate.turbo_pstate);
+	current_pstate = int_tofp(cpu->pstate.current_pstate);
+	busy_scaled = mul_fp(core_busy, div_fp(turbo_pstate, current_pstate));
+
+
+	return fp_toint(busy_scaled);
+}
+
+static inline void intel_pstate_adjust_busy_pstate(struct cpudata *cpu)
+{
+	int busy_scaled;
+	struct _pid *pid;
+	signed int ctl = 0;
+	int steps;
+
+	pid = &cpu->pid;
+	busy_scaled =  intel_pstate_get_scaled_busy(cpu);
+
+	ctl = pid_calc(pid, busy_scaled);
+
+	steps = abs(ctl);
+	if (ctl < 0)
+		intel_pstate_pstate_increase(cpu, steps);
+	else
+		intel_pstate_pstate_decrease(cpu, steps);
+}
+
+static inline void intel_pstate_adjust_idle_pstate(struct cpudata *cpu)
+{
+	int busy_scaled;
+	struct _pid *pid;
+	int ctl = 0;
+	int steps;
+
+	pid = &cpu->idle_pid;
+
+	busy_scaled =  intel_pstate_get_scaled_busy(cpu);
+
+	ctl = pid_calc(pid, 100 - busy_scaled);
+
+	steps = abs(ctl);
+	if (ctl < 0)
+		intel_pstate_pstate_decrease(cpu, steps);
+	else
+		intel_pstate_pstate_increase(cpu, steps);
+
+	if (cpu->pstate.current_pstate == cpu->pstate.min_pstate)
+		intel_pstate_normal_mode(cpu);
+}
+
+static void intel_pstate_timer_func(unsigned long __data)
+{
+	struct cpudata *cpu = (struct cpudata *) __data;
+	int idx;
+
+
+	idx = intel_pstate_sample(cpu);
+
+
+	if (!cpu->idle_mode)
+		intel_pstate_adjust_busy_pstate(cpu);
+	else
+		intel_pstate_adjust_idle_pstate(cpu);
+
+#if defined(XPERF_FIX)
+	if (cpu->pstate.current_pstate == cpu->pstate.min_pstate) {
+		cpu->min_pstate_count++;
+		if (!(cpu->min_pstate_count % 5)) {
+			intel_pstate_set_pstate(cpu, cpu->pstate.max_pstate);
+			intel_pstate_idle_mode(cpu);
+		}
+	} else
+		cpu->min_pstate_count = 0;
+#endif
+	intel_pstate_set_sample_time(cpu);
+}
+
+#define ICPU(model, policy) \
+	{ X86_VENDOR_INTEL, 6, model, X86_FEATURE_ANY, (unsigned long)&policy }
+
+static const struct x86_cpu_id intel_pstate_cpu_ids[] = {
+	ICPU(0x2a, default_policy),
+	ICPU(0x2d, default_policy),
+	{}
+};
+MODULE_DEVICE_TABLE(x86cpu, intel_pstate_cpu_ids);
+
+static int intel_pstate_init_cpu(unsigned int cpunum)
+{
+
+	const struct x86_cpu_id *id;
+	struct cpudata *cpu;
+
+	id = x86_match_cpu(intel_pstate_cpu_ids);
+	if (!id)
+		return -ENODEV;
+
+	all_cpu_data[cpunum] = kzalloc(sizeof(struct cpudata), GFP_KERNEL);
+	if (!all_cpu_data[cpunum])
+		return -ENOMEM;
+
+	cpu = all_cpu_data[cpunum];
+
+	intel_pstate_get_cpu_pstates(cpu);
+
+	cpu->cpu = cpunum;
+	cpu->pstate_policy =
+		(struct pstate_adjust_policy *)id->driver_data;
+	init_timer_deferrable(&cpu->timer);
+	cpu->timer.function = intel_pstate_timer_func;
+	cpu->timer.data =
+		(unsigned long)cpu;
+	cpu->timer.expires = jiffies + HZ/100;
+	intel_pstate_busy_pid_reset(cpu);
+	intel_pstate_idle_pid_reset(cpu);
+	intel_pstate_sample(cpu);
+	intel_pstate_set_pstate(cpu, cpu->pstate.max_pstate);
+
+	add_timer_on(&cpu->timer, cpunum);
+
+	pr_info("Intel pstate controlling:  cpu %d\n", cpunum);
+
+	return 0;
+}
+
+unsigned int intel_pstate_get(unsigned int cpu_num)
+{
+	struct sample *sample;
+	struct cpudata *cpu;
+
+	cpu = all_cpu_data[cpu_num];
+	if (!cpu)
+		return 0;
+	sample = &cpu->samples[cpu->sample_ptr];
+	return sample->freq;
+}
+
+static int intel_pstate_set_policy(struct cpufreq_policy *policy)
+{
+	struct cpudata *cpu;
+	int min, max;
+
+	cpu = all_cpu_data[policy->cpu];
+
+	intel_pstate_get_min_max(cpu, &min, &max);
+
+	limits.min_perf_pct = (policy->min * 100) / policy->cpuinfo.max_freq;
+	limits.min_perf_pct = clamp_t(int, limits.min_perf_pct, 0 , 100);
+	limits.min_perf = div_fp(int_tofp(limits.min_perf_pct), int_tofp(100));
+
+
+	limits.max_perf_pct = policy->max * 100 / policy->cpuinfo.max_freq;
+	limits.max_perf_pct = clamp_t(int, limits.max_perf_pct, 0 , 100);
+	limits.max_perf = div_fp(int_tofp(limits.max_perf_pct), int_tofp(100));
+
+
+
+	if (policy->policy == CPUFREQ_POLICY_PERFORMANCE) {
+		limits.min_perf_pct = 100;
+		limits.min_perf = int_tofp(1);
+		limits.max_perf_pct = 100;
+		limits.max_perf = int_tofp(1);
+		limits.no_turbo = 0;
+	}
+
+	return 0;
+}
+
+static int intel_pstate_verify_policy(struct cpufreq_policy *policy)
+{
+	cpufreq_verify_within_limits(policy,
+				policy->cpuinfo.min_freq,
+				policy->cpuinfo.max_freq);
+
+	if ((policy->policy != CPUFREQ_POLICY_POWERSAVE) &&
+		(policy->policy != CPUFREQ_POLICY_PERFORMANCE))
+		return -EINVAL;
+
+	return 0;
+}
+
+static int __cpuinit intel_pstate_cpu_exit(struct cpufreq_policy *policy)
+{
+	int cpu = policy->cpu;
+
+	del_timer(&all_cpu_data[cpu]->timer);
+	kfree(all_cpu_data[cpu]);
+	all_cpu_data[cpu] = NULL;
+	return 0;
+}
+
+static int __cpuinit intel_pstate_cpu_init(struct cpufreq_policy *policy)
+{
+	int rc, min_pstate, max_pstate;
+	struct cpudata *cpu;
+
+	rc = intel_pstate_init_cpu(policy->cpu);
+	if (rc)
+		return rc;
+
+	cpu = all_cpu_data[policy->cpu];
+
+	if (!limits.no_turbo &&
+		limits.min_perf_pct == 100 && limits.max_perf_pct == 100)
+		policy->policy = CPUFREQ_POLICY_PERFORMANCE;
+	else
+		policy->policy = CPUFREQ_POLICY_POWERSAVE;
+
+	intel_pstate_get_min_max(cpu, &min_pstate, &max_pstate);
+	policy->min = min_pstate * 100000;
+	policy->max = max_pstate * 100000;
+
+	/* cpuinfo and default policy values */
+	policy->cpuinfo.min_freq = cpu->pstate.min_pstate * 100000;
+	policy->cpuinfo.max_freq = cpu->pstate.turbo_pstate * 100000;
+	policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
+
+	return 0;
+}
+
+static struct cpufreq_driver intel_pstate_driver = {
+	.flags		= CPUFREQ_CONST_LOOPS,
+	.verify		= intel_pstate_verify_policy,
+	.setpolicy	= intel_pstate_set_policy,
+	.get		= intel_pstate_get,
+	.init		= intel_pstate_cpu_init,
+	.exit		= intel_pstate_cpu_exit,
+	.name		= "intel_pstate",
+	.owner		= THIS_MODULE,
+};
+
+
+static void intel_pstate_exit(void)
+{
+	int cpu;
+
+
+	sysfs_remove_group(intel_pstate_kobject,
+				&intel_pstate_attr_group);
+	debugfs_remove_recursive(debugfs_parent);
+
+	cpufreq_unregister_driver(&intel_pstate_driver);
+
+	if (!all_cpu_data)
+		return;
+
+	get_online_cpus();
+	for_each_online_cpu(cpu) {
+		if (all_cpu_data[cpu]) {
+			del_timer_sync(&all_cpu_data[cpu]->timer);
+			kfree(all_cpu_data[cpu]);
+		}
+	}
+
+	put_online_cpus();
+	vfree(all_cpu_data);
+}
+
+static int __init intel_pstate_init(void)
+{
+	int rc = 0;
+
+	const struct x86_cpu_id *id;
+
+	id = x86_match_cpu(intel_pstate_cpu_ids);
+	if (!id)
+		return -ENODEV;
+
+	pr_info("Intel P-state driver initializing.\n");
+
+	all_cpu_data = vmalloc(sizeof(void *) * num_possible_cpus());
+	if (!all_cpu_data)
+		return -ENOMEM;
+	memset(all_cpu_data, 0, sizeof(void *) * num_possible_cpus());
+
+	rc = cpufreq_register_driver(&intel_pstate_driver);
+	if (rc)
+		goto out;
+
+	intel_pstate_debug_expose_params();
+	intel_pstate_sysfs_expose_params();
+	return rc;
+out:
+	intel_pstate_exit();
+	return -ENODEV;
+}
+
+MODULE_AUTHOR("Dirk Brandewie <dirk.j.brandewie@intel.com>");
+MODULE_DESCRIPTION("'intel_pstate' - P state driver Intel Core processors");
+MODULE_LICENSE("GPL");
+
+device_initcall(intel_pstate_init);
+module_exit(intel_pstate_exit);
-- 
1.7.7.6


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* Re: [PATCH 2/6] cpufreq: Only query drivers that implement cpufreq_driver.target()
  2013-02-01 18:45 ` [PATCH 2/6] cpufreq: Only query drivers that implement cpufreq_driver.target() dirk.brandewie
@ 2013-02-02  3:22   ` Viresh Kumar
  0 siblings, 0 replies; 17+ messages in thread
From: Viresh Kumar @ 2013-02-02  3:22 UTC (permalink / raw)
  To: dirk.brandewie; +Cc: linux-kernel, cpufreq, Dirk Brandewie

On Sat, Feb 2, 2013 at 12:15 AM,  <dirk.brandewie@gmail.com> wrote:
> From: Dirk Brandewie <dirk.brandewie@gmail.com>
>
> Scaling drivers that implement cpufreq_driver.setpolicy() have
> internal governors and may/will change the current operating frequency
> very frequently this will cause cpufreq_out_of_sync() to be called
> every time. Only call cpufreq_driver.get() for drivers that implement
> cpufreq_driver.target()
>
> Signed-off-by: Dirk Brandewie <dirk.j.brandewie@intel.com>
> ---
>  drivers/cpufreq/cpufreq.c |    2 +-
>  1 files changed, 1 insertions(+), 1 deletions(-)
>
> diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
> index 1c037f0..493cd50 100644
> --- a/drivers/cpufreq/cpufreq.c
> +++ b/drivers/cpufreq/cpufreq.c
> @@ -1794,7 +1794,7 @@ int cpufreq_update_policy(unsigned int cpu)
>
>         /* BIOS might change freq behind our back
>           -> ask driver for current freq and notify governors about a change */
> -       if (cpufreq_driver->get) {
> +       if (cpufreq_driver->get && cpufreq_driver->target) {

This would mean policy->cur has a garbage value. I don't really know
how would other routine behave on this. Would it make sense to make
policy->cur zero atleast?

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 3/6] cpufreq: Do not track governor name for scaling drivers with internal governors.
  2013-02-01 18:45 ` [PATCH 3/6] cpufreq: Do not track governor name for scaling drivers with internal governors dirk.brandewie
@ 2013-02-02  3:25   ` Viresh Kumar
       [not found]     ` <CANOOhLSSXPuLG5X=TCfThjwcR3GuR=Z-O5qmY4StJZzg+Er5tA@mail.gmail.com>
  0 siblings, 1 reply; 17+ messages in thread
From: Viresh Kumar @ 2013-02-02  3:25 UTC (permalink / raw)
  To: dirk.brandewie; +Cc: linux-kernel, cpufreq, Dirk Brandewie

On Sat, Feb 2, 2013 at 12:15 AM,  <dirk.brandewie@gmail.com> wrote:
> From: Dirk Brandewie <dirk.brandewie@gmail.com>
>
> Scaling drivers that implement internal governors do not have governor
> structures assocaited with them.  Only track the name of the governor
> associated with the CPU if the driver does not implement
> cpufreq_driver.setpolicy()
>
> Signed-off-by: Dirk Brandewie <dirk.j.brandewie@intel.com>

Is this rebased on latest stuff? i.e. rafael/bleeding_edge ?

--
viresh

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 4/6] cpufreq_stats: Do not track policies without associated governors.
  2013-02-01 18:45 ` [PATCH 4/6] cpufreq_stats: Do not track policies without associated governors dirk.brandewie
@ 2013-02-02  5:38   ` Viresh Kumar
  0 siblings, 0 replies; 17+ messages in thread
From: Viresh Kumar @ 2013-02-02  5:38 UTC (permalink / raw)
  To: dirk.brandewie; +Cc: linux-kernel, cpufreq, Dirk Brandewie

On Sat, Feb 2, 2013 at 12:15 AM,  <dirk.brandewie@gmail.com> wrote:
> From: Dirk Brandewie <dirk.brandewie@gmail.com>
>
> Scaling drivers that implement internal governors do not have governor
> sturctures associated with them.  Do not create/remove statisitcs
> entries for polices that do not have governors associated with them.
>
> Signed-off-by: Dirk Brandewie <dirk.j.brandewie@intel.com>

It is not based of latest work.

Why don't we want stats to be updated for these? What does stats have
to do with governor?

> ---
>  drivers/cpufreq/cpufreq_stats.c |    4 +++-
>  1 files changed, 3 insertions(+), 1 deletions(-)
>
> diff --git a/drivers/cpufreq/cpufreq_stats.c b/drivers/cpufreq/cpufreq_stats.c
> index 9d7732b..8a1daf4 100644
> --- a/drivers/cpufreq/cpufreq_stats.c
> +++ b/drivers/cpufreq/cpufreq_stats.c
> @@ -183,7 +183,7 @@ static void cpufreq_stats_free_table(unsigned int cpu)
>  static void cpufreq_stats_free_sysfs(unsigned int cpu)
>  {
>         struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
> -       if (policy && policy->cpu == cpu)
> +       if (policy && policy->cpu == cpu && policy->governor)
>                 sysfs_remove_group(&policy->kobj, &stats_attr_group);
>         if (policy)
>                 cpufreq_cpu_put(policy);
> @@ -271,6 +271,8 @@ static int cpufreq_stat_notifier_policy(struct notifier_block *nb,
>         unsigned int cpu = policy->cpu;
>         if (val != CPUFREQ_NOTIFY)
>                 return 0;
> +       if (!policy->governor)
> +               return 0;
>         table = cpufreq_frequency_get_table(cpu);
>         if (!table)
>                 return 0;
> --
> 1.7.7.6
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 5/6] cpufreq: balance out cpufreq_cpu_{get,put} for scaling drivers using setpolicy
  2013-02-01 18:45 ` [PATCH 5/6] cpufreq: balance out cpufreq_cpu_{get,put} for scaling drivers using setpolicy dirk.brandewie
@ 2013-02-02  5:41   ` Viresh Kumar
  2013-02-04 18:25     ` Dirk Brandewie
  0 siblings, 1 reply; 17+ messages in thread
From: Viresh Kumar @ 2013-02-02  5:41 UTC (permalink / raw)
  To: dirk.brandewie; +Cc: linux-kernel, cpufreq

On Sat, Feb 2, 2013 at 12:15 AM,  <dirk.brandewie@gmail.com> wrote:
> From: Dirk Brandewie <dirk.brandewie@gmail.com>
>
> There is an additional reference added to the driver in
> cpufreq_add_dev_policy() that is removed in__cpufreq_governor() if the
> driver implements target().  Remove the last reference when the driver
> implements setpolicy()
>
> Signed-off-by: Dirk Brandewie <dirk.brandewie@gmail.com>

Rebase it on latest work as cpufreq_add_dev_policy() doesn't exist anymore.

> ---
>  drivers/cpufreq/cpufreq.c |    3 +++
>  1 files changed, 3 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
> index a4fd51e..ec103bf 100644
> --- a/drivers/cpufreq/cpufreq.c
> +++ b/drivers/cpufreq/cpufreq.c
> @@ -1119,6 +1119,9 @@ static int __cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif
>         if (cpufreq_driver->target)
>                 __cpufreq_governor(data, CPUFREQ_GOV_STOP);
>
> +       if (cpufreq_driver->setpolicy)
> +               cpufreq_cpu_put(data);
> +
>         kobj = &data->kobj;
>         cmp = &data->kobj_unregister;
>         unlock_policy_rwsem_write(cpu);
> --
> 1.7.7.6
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 3/6] cpufreq: Do not track governor name for scaling drivers with internal governors.
       [not found]     ` <CANOOhLSSXPuLG5X=TCfThjwcR3GuR=Z-O5qmY4StJZzg+Er5tA@mail.gmail.com>
@ 2013-02-02  5:54       ` Viresh Kumar
  0 siblings, 0 replies; 17+ messages in thread
From: Viresh Kumar @ 2013-02-02  5:54 UTC (permalink / raw)
  To: Dirk Brandewie; +Cc: linux-kernel, cpufreq, Dirk Brandewie

On 2 February 2013 11:14, Dirk Brandewie <dirk.brandewie@gmail.com> wrote:
> Hi viresh,
>
> This is based on 3.8-rc5.  I think this should work against bleeding_edge
> but I have not tested against bleeding_edge

Rafael wouldn't be able to apply these patches. There are a lot of core patches
present in bleeding_edge.

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 5/6] cpufreq: balance out cpufreq_cpu_{get,put} for scaling drivers using setpolicy
  2013-02-02  5:41   ` Viresh Kumar
@ 2013-02-04 18:25     ` Dirk Brandewie
  2013-02-05  7:03       ` Viresh Kumar
  0 siblings, 1 reply; 17+ messages in thread
From: Dirk Brandewie @ 2013-02-04 18:25 UTC (permalink / raw)
  To: Viresh Kumar; +Cc: dirk.brandewie, linux-kernel, cpufreq

Hi Viresh,

I have rebased onto bleeding-edge when I reboot the system I get a kernel panic.
Any idea what I could have done that would have broken the restructured
cpufreq_{add/remove}_dev.

--Dirk

[  134.714071] kvm: exiting hardware virtualization
[  134.920302] sd 0:0:0:0: [sda] Synchronizing SCSI cache
[  135.132967] Disabling non-boot CPUs ...
[  135.137189] __cpufreq_remove_dev: cpufreq: __cpufreq_remove_dev: 
unregistering CPU 1
[  135.145577] __cpufreq_remove_dev: cpufreq: __cpufreq_remove_dev: removing 
link, cpu: 1
[  135.154152] ------------[ cut here ]------------
[  135.159212] kernel BUG at fs/sysfs/dir.c:562!
[  135.163900] invalid opcode: 0000 [#1] SMP
[  135.168367] Modules linked in:
[  135.171720] CPU 0
[  135.173730] Pid: 1, comm: systemd-shutdow Not tainted 3.8.0-rc5+ #33 Acer 
Veriton X4618G/Veriton X4618G
[  135.184133] RIP: 0010:[<ffffffff81252723>]  [<ffffffff81252723>] 
sysfs_remove_one+0x73/0x80
[  135.193155] RSP: 0018:ffff880427c95b88  EFLAGS: 00010202
[  135.198925] RAX: ffff880427d10000 RBX: ffff880425efe460 RCX: 0000000180240017
[  135.206641] RDX: 0000000000000000 RSI: ffff880425efe460 RDI: ffff880427c95bb8
[  135.214314] RBP: ffff880427c95ba8 R08: 0000000000000000 R09: 0000000000000001
[  135.222060] R10: 000000000000000e R11: ffffffff81251f38 R12: 0000000000000000
[  135.229854] R13: ffff880425efe460 R14: 0000000000000246 R15: 0000000000000001
[  135.237537] FS:  00007fd987f6a800(0000) GS:ffff88043e200000(0000) 
knlGS:0000000000000000
[  135.246343] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[  135.252525] CR2: 00000032e70104f0 CR3: 0000000416bf8000 CR4: 00000000000407f0
[  135.260203] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
[  135.267959] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
[  135.275668] Process systemd-shutdow (pid: 1, threadinfo ffff880427c94000, 
task ffff880427d10000)
[  135.285104] Stack:
[  135.287299]  ffff880425efe460 ffff880425efe460 0000000000000000 ffff880425efe460
[  135.295355]  ffff880427c95bd8 ffffffff8125281a ffff88042789fd20 0000000000000000
[  135.303461]  0000000000000246 0000000000000000 ffff880427c95c18 ffffffff81252cf7
[  135.311571] Call Trace:
[  135.314213]  [<ffffffff8125281a>] remove_dir+0x2a/0x40
[  135.319786]  [<ffffffff81252cf7>] sysfs_remove_dir+0x97/0xc0
[  135.325886]  [<ffffffff8137ebc6>] kobject_del+0x16/0x40
[  135.331529]  [<ffffffff8137ec52>] kobject_cleanup+0x62/0x1b0
[  135.337598]  [<ffffffff8137eafb>] kobject_put+0x2b/0x60
[  135.343253]  [<ffffffff816311a3>] __cpufreq_remove_dev.isra.13+0x183/0x450
[  135.350682]  [<ffffffff81829a76>] ? down_write+0x16/0x40
[  135.356422]  [<ffffffff8181e030>] cpufreq_cpu_callback+0x5d/0x77
[  135.362966]  [<ffffffff8182fa1d>] notifier_call_chain+0x4d/0x70
[  135.369346]  [<ffffffff810cf2ce>] __raw_notifier_call_chain+0xe/0x10
[  135.376256]  [<ffffffff810a8f70>] __cpu_notify+0x20/0x40
[  135.382026]  [<ffffffff8180f5af>] _cpu_down+0x7f/0x270
[  135.387602]  [<ffffffff810a926e>] disable_nonboot_cpus+0x8e/0x120
[  135.394170]  [<ffffffff810bcd7b>] kernel_restart+0x1b/0x60
[  135.400075]  [<ffffffff810bcfa1>] sys_reboot+0x1c1/0x280
[  135.405832]  [<ffffffff811827ae>] ? do_writepages+0x1e/0x40
[  135.411879]  [<ffffffff81177d41>] ? __filemap_fdatawrite_range+0x51/0x60
[  135.419129]  [<ffffffff811f6f78>] ? iput+0x48/0x190
[  135.424457]  [<ffffffff8120b600>] ? sync_inodes_one_sb+0x20/0x20
[  135.430969]  [<ffffffff81215d3f>] ? iterate_bdevs+0xef/0x100
[  135.437057]  [<ffffffff81833fd9>] system_call_fastpath+0x16/0x1b
[  135.443563] Code: 30 49 89 44 24 38 49 89 54 24 40 66 81 4b 60 00 20 49 8b 45 
08 48 89 43 30 49 89 5d 08 48 8b 5d e8 4c 8b 65 f0 4c
[  135.465457] RIP  [<ffffffff81252723>] sysfs_remove_one+0x73/0x80
[  135.471964]  RSP <ffff880427c95b88>
[  135.475777] ---[ end trace 88437c0ab4adf760 ]---
[  135.488452] Kernel panic - not syncing: Attempted to kill init! 
exitcode=0x0000000b
[  135.488452]
[  135.504187] drm_kms_helper: panic occurred, switching back to text console
[  135.511074] ------------[ cut here ]------------
[  135.515711] WARNING: at arch/x86/kernel/smp.c:123 
native_smp_send_reschedule+0x5b/0x60()
[  135.523805] Hardware name: Veriton X4618G
[  135.527819] Modules linked in:
[  135.530921] Pid: 1, comm: systemd-shutdow Tainted: G      D      3.8.0-rc5+ #33
[  135.538233] Call Trace:
[  135.540694]  <IRQ>  [<ffffffff810a552f>] warn_slowpath_common+0x7f/0xc0
[  135.547363]  [<ffffffff810a558a>] warn_slowpath_null+0x1a/0x20
[  135.553202]  [<ffffffff8107baeb>] native_smp_send_reschedule+0x5b/0x60
[  135.559733]  [<ffffffff810e5774>] trigger_load_balance+0x184/0x220
[  135.565920]  [<ffffffff810d9989>] scheduler_tick+0x109/0x140
[  135.571593]  [<ffffffff810b67bc>] update_process_times+0x6c/0x90
[  135.577615]  [<ffffffff810fef6e>] tick_sched_handle.isra.8+0x2e/0x70
[  135.583975]  [<ffffffff810ff0fc>] tick_sched_timer+0x4c/0x80
[  135.589639]  [<ffffffff810cd243>] __run_hrtimer+0x73/0x1d0
[  135.595135]  [<ffffffff810ff0b0>] ? tick_sched_do_timer+0x40/0x40
[  135.601242]  [<ffffffff810adc16>] ? __do_softirq+0x136/0x210
[  135.606912]  [<ffffffff810cdb67>] hrtimer_interrupt+0xf7/0x230
[  135.612755]  [<ffffffff81835c39>] smp_apic_timer_interrupt+0x69/0x99
[  135.619118]  [<ffffffff81834b9d>] apic_timer_interrupt+0x6d/0x80
[  135.625125]  <EOI>  [<ffffffff8182110e>] ? panic+0x18c/0x1d0
[  135.630843]  [<ffffffff81821078>] ? panic+0xf6/0x1d0
[  135.635814]  [<ffffffff810ab688>] do_exit+0x918/0x9e0
[  135.640872]  [<ffffffff8182cbdd>] oops_end+0x9d/0xe0
[  135.645849]  [<ffffffff8105b848>] die+0x58/0x90
[  135.650395]  [<ffffffff8182c47b>] do_trap+0x6b/0x170
[  135.655367]  [<ffffffff8182fa52>] ? __atomic_notifier_call_chain+0x12/0x20
[  135.662242]  [<ffffffff81058eec>] do_invalid_op+0x9c/0xb0
[  135.667650]  [<ffffffff81252723>] ? sysfs_remove_one+0x73/0x80
[  135.673482]  [<ffffffff818350de>] invalid_op+0x1e/0x30
[  135.678631]  [<ffffffff81251f38>] ? release_sysfs_dirent+0xa8/0xf0
[  135.684816]  [<ffffffff81252723>] ? sysfs_remove_one+0x73/0x80
[  135.690656]  [<ffffffff818291fd>] ? mutex_lock+0x1d/0x50
[  135.695982]  [<ffffffff8125281a>] remove_dir+0x2a/0x40
[  135.701136]  [<ffffffff81252cf7>] sysfs_remove_dir+0x97/0xc0
[  135.706798]  [<ffffffff8137ebc6>] kobject_del+0x16/0x40
[  135.712027]  [<ffffffff8137ec52>] kobject_cleanup+0x62/0x1b0
[  135.717693]  [<ffffffff8137eafb>] kobject_put+0x2b/0x60
[  135.722928]  [<ffffffff816311a3>] __cpufreq_remove_dev.isra.13+0x183/0x450
[  135.729812]  [<ffffffff81829a76>] ? down_write+0x16/0x40
[  135.735128]  [<ffffffff8181e030>] cpufreq_cpu_callback+0x5d/0x77
[  135.741140]  [<ffffffff8182fa1d>] notifier_call_chain+0x4d/0x70
[  135.747066]  [<ffffffff810cf2ce>] __raw_notifier_call_chain+0xe/0x10
[  135.753422]  [<ffffffff810a8f70>] __cpu_notify+0x20/0x40
[  135.758739]  [<ffffffff8180f5af>] _cpu_down+0x7f/0x270
[  135.763885]  [<ffffffff810a926e>] disable_nonboot_cpus+0x8e/0x120
[  135.769983]  [<ffffffff810bcd7b>] kernel_restart+0x1b/0x60
[  135.775479]  [<ffffffff810bcfa1>] sys_reboot+0x1c1/0x280
[  135.780803]  [<ffffffff811827ae>] ? do_writepages+0x1e/0x40
[  135.786381]  [<ffffffff81177d41>] ? __filemap_fdatawrite_range+0x51/0x60
[  135.793088]  [<ffffffff811f6f78>] ? iput+0x48/0x190
[  135.797982]  [<ffffffff8120b600>] ? sync_inodes_one_sb+0x20/0x20
[  135.803997]  [<ffffffff81215d3f>] ? iterate_bdevs+0xef/0x100
[  135.809665]  [<ffffffff81833fd9>] system_call_fastpath+0x16/0x1b
[  135.815676] ---[ end trace 88437c0ab4adf761 ]---


On 02/01/2013 09:41 PM, Viresh Kumar wrote:
> On Sat, Feb 2, 2013 at 12:15 AM,  <dirk.brandewie@gmail.com> wrote:
>> From: Dirk Brandewie <dirk.brandewie@gmail.com>
>>
>> There is an additional reference added to the driver in
>> cpufreq_add_dev_policy() that is removed in__cpufreq_governor() if the
>> driver implements target().  Remove the last reference when the driver
>> implements setpolicy()
>>
>> Signed-off-by: Dirk Brandewie <dirk.brandewie@gmail.com>
>
> Rebase it on latest work as cpufreq_add_dev_policy() doesn't exist anymore.
>
>> ---
>>   drivers/cpufreq/cpufreq.c |    3 +++
>>   1 files changed, 3 insertions(+), 0 deletions(-)
>>
>> diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
>> index a4fd51e..ec103bf 100644
>> --- a/drivers/cpufreq/cpufreq.c
>> +++ b/drivers/cpufreq/cpufreq.c
>> @@ -1119,6 +1119,9 @@ static int __cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif
>>          if (cpufreq_driver->target)
>>                  __cpufreq_governor(data, CPUFREQ_GOV_STOP);
>>
>> +       if (cpufreq_driver->setpolicy)
>> +               cpufreq_cpu_put(data);
>> +
>>          kobj = &data->kobj;
>>          cmp = &data->kobj_unregister;
>>          unlock_policy_rwsem_write(cpu);
>> --
>> 1.7.7.6
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>> Please read the FAQ at  http://www.tux.org/lkml/


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 5/6] cpufreq: balance out cpufreq_cpu_{get,put} for scaling drivers using setpolicy
  2013-02-04 18:25     ` Dirk Brandewie
@ 2013-02-05  7:03       ` Viresh Kumar
  0 siblings, 0 replies; 17+ messages in thread
From: Viresh Kumar @ 2013-02-05  7:03 UTC (permalink / raw)
  To: Dirk Brandewie; +Cc: linux-kernel, cpufreq

On 4 February 2013 23:55, Dirk Brandewie <dirk.brandewie@gmail.com> wrote:
> Hi Viresh,
>
> I have rebased onto bleeding-edge when I reboot the system I get a kernel
> panic.
> Any idea what I could have done that would have broken the restructured
> cpufreq_{add/remove}_dev.

Dirk, there are two mail chains for similar issue. Lets discuss these
issues in the
other thread: "BUG in bleeding edge c560f3d".

^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2013-02-05  7:04 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-02-01 18:45 [PATCH 0/6] Add P state driver for Intel Core Processors dirk.brandewie
2013-02-01 18:45 ` [PATCH 1/6] cpufreq: Retrieve current frequency from scaling drivers with internal governors dirk.brandewie
2013-02-01 18:45 ` [PATCH 2/6] cpufreq: Only query drivers that implement cpufreq_driver.target() dirk.brandewie
2013-02-02  3:22   ` Viresh Kumar
2013-02-01 18:45 ` dirk.brandewie
2013-02-01 18:45 ` [PATCH 3/6] cpufreq: Do not track governor name for scaling drivers with internal governors dirk.brandewie
2013-02-02  3:25   ` Viresh Kumar
     [not found]     ` <CANOOhLSSXPuLG5X=TCfThjwcR3GuR=Z-O5qmY4StJZzg+Er5tA@mail.gmail.com>
2013-02-02  5:54       ` Viresh Kumar
2013-02-01 18:45 ` dirk.brandewie
2013-02-01 18:45 ` [PATCH 4/6] cpufreq_stats: Do not track policies without associated governors dirk.brandewie
2013-02-02  5:38   ` Viresh Kumar
2013-02-01 18:45 ` dirk.brandewie
2013-02-01 18:45 ` [PATCH 5/6] cpufreq: balance out cpufreq_cpu_{get,put} for scaling drivers using setpolicy dirk.brandewie
2013-02-02  5:41   ` Viresh Kumar
2013-02-04 18:25     ` Dirk Brandewie
2013-02-05  7:03       ` Viresh Kumar
2013-02-01 18:45 ` [PATCH 6/6] cpufreq/x86: Add P-state driver for sandy bridge dirk.brandewie

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).