rpms/kernel/devel git-cpufreq.patch, 1.2, 1.3 TODO, 1.5, 1.6 kernel.spec, 1.1019, 1.1020

Dave Jones davej at fedoraproject.org
Mon Oct 6 19:55:33 UTC 2008


Author: davej

Update of /cvs/pkgs/rpms/kernel/devel
In directory cvs1.fedora.phx.redhat.com:/tmp/cvs-serv18282

Modified Files:
	TODO kernel.spec 
Added Files:
	git-cpufreq.patch 
Log Message:
Add cpufreq.git bits queued for 2.6.28.

git-cpufreq.patch:

Index: git-cpufreq.patch
===================================================================
RCS file: git-cpufreq.patch
diff -N git-cpufreq.patch
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ git-cpufreq.patch	6 Oct 2008 19:55:32 -0000	1.3
@@ -0,0 +1,830 @@
+diff --git a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
+index dd097b8..c24c4a4 100644
+--- a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
++++ b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
+@@ -256,7 +256,8 @@ static u32 get_cur_val(const cpumask_t *mask)
+  * Only IA32_APERF/IA32_MPERF ratio is architecturally defined and
+  * no meaning should be associated with absolute values of these MSRs.
+  */
+-static unsigned int get_measured_perf(unsigned int cpu)
++static unsigned int get_measured_perf(struct cpufreq_policy *policy,
++				      unsigned int cpu)
+ {
+ 	union {
+ 		struct {
+@@ -326,7 +327,7 @@ static unsigned int get_measured_perf(unsigned int cpu)
+ 
+ #endif
+ 
+-	retval = per_cpu(drv_data, cpu)->max_freq * perf_percent / 100;
++	retval = per_cpu(drv_data, policy->cpu)->max_freq * perf_percent / 100;
+ 
+ 	put_cpu();
+ 	set_cpus_allowed_ptr(current, &saved_mask);
+@@ -785,7 +786,11 @@ static int __init acpi_cpufreq_init(void)
+ 	if (ret)
+ 		return ret;
+ 
+-	return cpufreq_register_driver(&acpi_cpufreq_driver);
++	ret = cpufreq_register_driver(&acpi_cpufreq_driver);
++	if (ret)
++		free_percpu(acpi_perf_data);
++
++	return ret;
+ }
+ 
+ static void __exit acpi_cpufreq_exit(void)
+@@ -795,8 +800,6 @@ static void __exit acpi_cpufreq_exit(void)
+ 	cpufreq_unregister_driver(&acpi_cpufreq_driver);
+ 
+ 	free_percpu(acpi_perf_data);
+-
+-	return;
+ }
+ 
+ module_param(acpi_pstate_strict, uint, 0644);
+diff --git a/arch/x86/kernel/cpu/cpufreq/elanfreq.c b/arch/x86/kernel/cpu/cpufreq/elanfreq.c
+index e4a4bf8..fe613c9 100644
+--- a/arch/x86/kernel/cpu/cpufreq/elanfreq.c
++++ b/arch/x86/kernel/cpu/cpufreq/elanfreq.c
+@@ -25,8 +25,8 @@
+ #include <linux/cpufreq.h>
+ 
+ #include <asm/msr.h>
+-#include <asm/timex.h>
+-#include <asm/io.h>
++#include <linux/timex.h>
++#include <linux/io.h>
+ 
+ #define REG_CSCIR 0x22		/* Chip Setup and Control Index Register    */
+ #define REG_CSCDR 0x23		/* Chip Setup and Control Data  Register    */
+@@ -82,7 +82,7 @@ static unsigned int elanfreq_get_cpu_frequency(unsigned int cpu)
+ 	u8 clockspeed_reg;    /* Clock Speed Register */
+ 
+ 	local_irq_disable();
+-	outb_p(0x80,REG_CSCIR);
++	outb_p(0x80, REG_CSCIR);
+ 	clockspeed_reg = inb_p(REG_CSCDR);
+ 	local_irq_enable();
+ 
+@@ -98,10 +98,10 @@ static unsigned int elanfreq_get_cpu_frequency(unsigned int cpu)
+ 	}
+ 
+ 	/* 33 MHz is not 32 MHz... */
+-	if ((clockspeed_reg & 0xE0)==0xA0)
++	if ((clockspeed_reg & 0xE0) == 0xA0)
+ 		return 33000;
+ 
+-	return ((1<<((clockspeed_reg & 0xE0) >> 5)) * 1000);
++	return (1<<((clockspeed_reg & 0xE0) >> 5)) * 1000;
+ }
+ 
+ 
+@@ -117,7 +117,7 @@ static unsigned int elanfreq_get_cpu_frequency(unsigned int cpu)
+  *	There is no return value.
+  */
+ 
+-static void elanfreq_set_cpu_state (unsigned int state)
++static void elanfreq_set_cpu_state(unsigned int state)
+ {
+ 	struct cpufreq_freqs    freqs;
+ 
+@@ -144,20 +144,20 @@ static void elanfreq_set_cpu_state (unsigned int state)
+ 	 */
+ 
+ 	local_irq_disable();
+-	outb_p(0x40,REG_CSCIR);		/* Disable hyperspeed mode */
+-	outb_p(0x00,REG_CSCDR);
++	outb_p(0x40, REG_CSCIR);		/* Disable hyperspeed mode */
++	outb_p(0x00, REG_CSCDR);
+ 	local_irq_enable();		/* wait till internal pipelines and */
+ 	udelay(1000);			/* buffers have cleaned up          */
+ 
+ 	local_irq_disable();
+ 
+ 	/* now, set the CPU clock speed register (0x80) */
+-	outb_p(0x80,REG_CSCIR);
+-	outb_p(elan_multiplier[state].val80h,REG_CSCDR);
++	outb_p(0x80, REG_CSCIR);
++	outb_p(elan_multiplier[state].val80h, REG_CSCDR);
+ 
+ 	/* now, the hyperspeed bit in PMU Force Mode Register (0x40) */
+-	outb_p(0x40,REG_CSCIR);
+-	outb_p(elan_multiplier[state].val40h,REG_CSCDR);
++	outb_p(0x40, REG_CSCIR);
++	outb_p(elan_multiplier[state].val40h, REG_CSCDR);
+ 	udelay(10000);
+ 	local_irq_enable();
+ 
+@@ -173,12 +173,12 @@ static void elanfreq_set_cpu_state (unsigned int state)
+  *	for the hardware supported by the driver.
+  */
+ 
+-static int elanfreq_verify (struct cpufreq_policy *policy)
++static int elanfreq_verify(struct cpufreq_policy *policy)
+ {
+ 	return cpufreq_frequency_table_verify(policy, &elanfreq_table[0]);
+ }
+ 
+-static int elanfreq_target (struct cpufreq_policy *policy,
++static int elanfreq_target(struct cpufreq_policy *policy,
+ 			    unsigned int target_freq,
+ 			    unsigned int relation)
+ {
+@@ -205,7 +205,7 @@ static int elanfreq_cpu_init(struct cpufreq_policy *policy)
+ 
+ 	/* capability check */
+ 	if ((c->x86_vendor != X86_VENDOR_AMD) ||
+-	    (c->x86 != 4) || (c->x86_model!=10))
++	    (c->x86 != 4) || (c->x86_model != 10))
+ 		return -ENODEV;
+ 
+ 	/* max freq */
+@@ -213,7 +213,7 @@ static int elanfreq_cpu_init(struct cpufreq_policy *policy)
+ 		max_freq = elanfreq_get_cpu_frequency(0);
+ 
+ 	/* table init */
+-	for (i=0; (elanfreq_table[i].frequency != CPUFREQ_TABLE_END); i++) {
++	for (i = 0; (elanfreq_table[i].frequency != CPUFREQ_TABLE_END); i++) {
+ 		if (elanfreq_table[i].frequency > max_freq)
+ 			elanfreq_table[i].frequency = CPUFREQ_ENTRY_INVALID;
+ 	}
+@@ -224,7 +224,7 @@ static int elanfreq_cpu_init(struct cpufreq_policy *policy)
+ 
+ 	result = cpufreq_frequency_table_cpuinfo(policy, elanfreq_table);
+ 	if (result)
+-		return (result);
++		return result;
+ 
+ 	cpufreq_frequency_table_get_attr(elanfreq_table, policy->cpu);
+ 	return 0;
+@@ -260,7 +260,7 @@ __setup("elanfreq=", elanfreq_setup);
+ #endif
+ 
+ 
+-static struct freq_attr* elanfreq_attr[] = {
++static struct freq_attr *elanfreq_attr[] = {
+ 	&cpufreq_freq_attr_scaling_available_freqs,
+ 	NULL,
+ };
+@@ -284,9 +284,9 @@ static int __init elanfreq_init(void)
+ 
+ 	/* Test if we have the right hardware */
+ 	if ((c->x86_vendor != X86_VENDOR_AMD) ||
+-		(c->x86 != 4) || (c->x86_model!=10)) {
++		(c->x86 != 4) || (c->x86_model != 10)) {
+ 		printk(KERN_INFO "elanfreq: error: no Elan processor found!\n");
+-                return -ENODEV;
++		return -ENODEV;
+ 	}
+ 	return cpufreq_register_driver(&elanfreq_driver);
+ }
+@@ -298,7 +298,7 @@ static void __exit elanfreq_exit(void)
+ }
+ 
+ 
+-module_param (max_freq, int, 0444);
++module_param(max_freq, int, 0444);
+ 
+ MODULE_LICENSE("GPL");
+ MODULE_AUTHOR("Robert Schwebel <r.schwebel at pengutronix.de>, Sven Geggus <sven at geggus.net>");
+diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k6.c b/arch/x86/kernel/cpu/cpufreq/powernow-k6.c
+index eb9b62b..b5ced80 100644
+--- a/arch/x86/kernel/cpu/cpufreq/powernow-k6.c
++++ b/arch/x86/kernel/cpu/cpufreq/powernow-k6.c
+@@ -15,12 +15,11 @@
+ #include <linux/slab.h>
+ 
+ #include <asm/msr.h>
+-#include <asm/timex.h>
+-#include <asm/io.h>
++#include <linux/timex.h>
++#include <linux/io.h>
+ 
+-
+-#define POWERNOW_IOPORT 0xfff0         /* it doesn't matter where, as long
+-					  as it is unused */
++#define POWERNOW_IOPORT 0xfff0          /* it doesn't matter where, as long
++					   as it is unused */
+ 
+ static unsigned int                     busfreq;   /* FSB, in 10 kHz */
+ static unsigned int                     max_multiplier;
+@@ -53,7 +52,7 @@ static int powernow_k6_get_cpu_multiplier(void)
+ 
+ 	msrval = POWERNOW_IOPORT + 0x1;
+ 	wrmsr(MSR_K6_EPMR, msrval, 0); /* enable the PowerNow port */
+-	invalue=inl(POWERNOW_IOPORT + 0x8);
++	invalue = inl(POWERNOW_IOPORT + 0x8);
+ 	msrval = POWERNOW_IOPORT + 0x0;
+ 	wrmsr(MSR_K6_EPMR, msrval, 0); /* disable it again */
+ 
+@@ -67,9 +66,9 @@ static int powernow_k6_get_cpu_multiplier(void)
+  *
+  *   Tries to change the PowerNow! multiplier
+  */
+-static void powernow_k6_set_state (unsigned int best_i)
++static void powernow_k6_set_state(unsigned int best_i)
+ {
+-	unsigned long           outvalue=0, invalue=0;
++	unsigned long           outvalue = 0, invalue = 0;
+ 	unsigned long           msrval;
+ 	struct cpufreq_freqs    freqs;
+ 
+@@ -90,10 +89,10 @@ static void powernow_k6_set_state (unsigned int best_i)
+ 
+ 	msrval = POWERNOW_IOPORT + 0x1;
+ 	wrmsr(MSR_K6_EPMR, msrval, 0); /* enable the PowerNow port */
+-	invalue=inl(POWERNOW_IOPORT + 0x8);
++	invalue = inl(POWERNOW_IOPORT + 0x8);
+ 	invalue = invalue & 0xf;
+ 	outvalue = outvalue | invalue;
+-	outl(outvalue ,(POWERNOW_IOPORT + 0x8));
++	outl(outvalue , (POWERNOW_IOPORT + 0x8));
+ 	msrval = POWERNOW_IOPORT + 0x0;
+ 	wrmsr(MSR_K6_EPMR, msrval, 0); /* disable it again */
+ 
+@@ -124,7 +123,7 @@ static int powernow_k6_verify(struct cpufreq_policy *policy)
+  *
+  * sets a new CPUFreq policy
+  */
+-static int powernow_k6_target (struct cpufreq_policy *policy,
++static int powernow_k6_target(struct cpufreq_policy *policy,
+ 			       unsigned int target_freq,
+ 			       unsigned int relation)
+ {
+@@ -152,7 +151,7 @@ static int powernow_k6_cpu_init(struct cpufreq_policy *policy)
+ 	busfreq = cpu_khz / max_multiplier;
+ 
+ 	/* table init */
+-	for (i=0; (clock_ratio[i].frequency != CPUFREQ_TABLE_END); i++) {
++	for (i = 0; (clock_ratio[i].frequency != CPUFREQ_TABLE_END); i++) {
+ 		if (clock_ratio[i].index > max_multiplier)
+ 			clock_ratio[i].frequency = CPUFREQ_ENTRY_INVALID;
+ 		else
+@@ -165,7 +164,7 @@ static int powernow_k6_cpu_init(struct cpufreq_policy *policy)
+ 
+ 	result = cpufreq_frequency_table_cpuinfo(policy, clock_ratio);
+ 	if (result)
+-		return (result);
++		return result;
+ 
+ 	cpufreq_frequency_table_get_attr(clock_ratio, policy->cpu);
+ 
+@@ -176,8 +175,8 @@ static int powernow_k6_cpu_init(struct cpufreq_policy *policy)
+ static int powernow_k6_cpu_exit(struct cpufreq_policy *policy)
+ {
+ 	unsigned int i;
+-	for (i=0; i<8; i++) {
+-		if (i==max_multiplier)
++	for (i = 0; i < 8; i++) {
++		if (i == max_multiplier)
+ 			powernow_k6_set_state(i);
+ 	}
+ 	cpufreq_frequency_table_put_attr(policy->cpu);
+@@ -189,7 +188,7 @@ static unsigned int powernow_k6_get(unsigned int cpu)
+ 	return busfreq * powernow_k6_get_cpu_multiplier();
+ }
+ 
+-static struct freq_attr* powernow_k6_attr[] = {
++static struct freq_attr *powernow_k6_attr[] = {
+ 	&cpufreq_freq_attr_scaling_available_freqs,
+ 	NULL,
+ };
+@@ -227,7 +226,7 @@ static int __init powernow_k6_init(void)
+ 	}
+ 
+ 	if (cpufreq_register_driver(&powernow_k6_driver)) {
+-		release_region (POWERNOW_IOPORT, 16);
++		release_region(POWERNOW_IOPORT, 16);
+ 		return -EINVAL;
+ 	}
+ 
+@@ -243,13 +242,13 @@ static int __init powernow_k6_init(void)
+ static void __exit powernow_k6_exit(void)
+ {
+ 	cpufreq_unregister_driver(&powernow_k6_driver);
+-	release_region (POWERNOW_IOPORT, 16);
++	release_region(POWERNOW_IOPORT, 16);
+ }
+ 
+ 
+-MODULE_AUTHOR ("Arjan van de Ven <arjanv at redhat.com>, Dave Jones <davej at codemonkey.org.uk>, Dominik Brodowski <linux at brodo.de>");
+-MODULE_DESCRIPTION ("PowerNow! driver for AMD K6-2+ / K6-3+ processors.");
+-MODULE_LICENSE ("GPL");
++MODULE_AUTHOR("Arjan van de Ven <arjanv at redhat.com>, Dave Jones <davej at codemonkey.org.uk>, Dominik Brodowski <linux at brodo.de>");
++MODULE_DESCRIPTION("PowerNow! driver for AMD K6-2+ / K6-3+ processors.");
++MODULE_LICENSE("GPL");
+ 
+ module_init(powernow_k6_init);
+ module_exit(powernow_k6_exit);
+diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
+index 8a67f16..31d6f53 100644
+--- a/drivers/cpufreq/cpufreq.c
++++ b/drivers/cpufreq/cpufreq.c
+@@ -1467,25 +1467,27 @@ int cpufreq_driver_target(struct cpufreq_policy *policy,
+ 			  unsigned int target_freq,
+ 			  unsigned int relation)
+ {
+-	int ret;
++	int ret = -EINVAL;
+ 
+ 	policy = cpufreq_cpu_get(policy->cpu);
+ 	if (!policy)
+-		return -EINVAL;
++		goto no_policy;
+ 
+ 	if (unlikely(lock_policy_rwsem_write(policy->cpu)))
+-		return -EINVAL;
++		goto fail;
+ 
+ 	ret = __cpufreq_driver_target(policy, target_freq, relation);
+ 
+ 	unlock_policy_rwsem_write(policy->cpu);
+ 
++fail:
+ 	cpufreq_cpu_put(policy);
++no_policy:
+ 	return ret;
+ }
+ EXPORT_SYMBOL_GPL(cpufreq_driver_target);
+ 
+-int __cpufreq_driver_getavg(struct cpufreq_policy *policy)
++int __cpufreq_driver_getavg(struct cpufreq_policy *policy, unsigned int cpu)
+ {
+ 	int ret = 0;
+ 
+@@ -1493,8 +1495,8 @@ int __cpufreq_driver_getavg(struct cpufreq_policy *policy)
+ 	if (!policy)
+ 		return -EINVAL;
+ 
+-	if (cpu_online(policy->cpu) && cpufreq_driver->getavg)
+-		ret = cpufreq_driver->getavg(policy->cpu);
++	if (cpu_online(cpu) && cpufreq_driver->getavg)
++		ret = cpufreq_driver->getavg(policy, cpu);
+ 
+ 	cpufreq_cpu_put(policy);
+ 	return ret;
+@@ -1717,13 +1719,17 @@ int cpufreq_update_policy(unsigned int cpu)
+ {
+ 	struct cpufreq_policy *data = cpufreq_cpu_get(cpu);
+ 	struct cpufreq_policy policy;
+-	int ret = 0;
++	int ret;
+ 
+-	if (!data)
+-		return -ENODEV;
++	if (!data) {
++		ret = -ENODEV;
++		goto no_policy;
++	}
+ 
+-	if (unlikely(lock_policy_rwsem_write(cpu)))
+-		return -EINVAL;
++	if (unlikely(lock_policy_rwsem_write(cpu))) {
++		ret = -EINVAL;
++		goto fail;
++	}
+ 
+ 	dprintk("updating policy for CPU %u\n", cpu);
+ 	memcpy(&policy, data, sizeof(struct cpufreq_policy));
+@@ -1750,7 +1756,9 @@ int cpufreq_update_policy(unsigned int cpu)
+ 
+ 	unlock_policy_rwsem_write(cpu);
+ 
++fail:
+ 	cpufreq_cpu_put(data);
++no_policy:
+ 	return ret;
+ }
+ EXPORT_SYMBOL(cpufreq_update_policy);
+diff --git a/drivers/cpufreq/cpufreq_conservative.c b/drivers/cpufreq/cpufreq_conservative.c
+index ac0bbf2..e265783 100644
+--- a/drivers/cpufreq/cpufreq_conservative.c
++++ b/drivers/cpufreq/cpufreq_conservative.c
+@@ -460,6 +460,7 @@ static void do_dbs_timer(struct work_struct *work)
+ 
+ static inline void dbs_timer_init(void)
+ {
++	init_timer_deferrable(&dbs_work.timer);
+ 	schedule_delayed_work(&dbs_work,
+ 			usecs_to_jiffies(dbs_tuners_ins.sampling_rate));
+ 	return;
+@@ -575,13 +576,15 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
+ 	return 0;
+ }
+ 
++#ifndef CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE
++static
++#endif
+ struct cpufreq_governor cpufreq_gov_conservative = {
+ 	.name			= "conservative",
+ 	.governor		= cpufreq_governor_dbs,
+ 	.max_transition_latency	= TRANSITION_LATENCY_LIMIT,
+ 	.owner			= THIS_MODULE,
+ };
+-EXPORT_SYMBOL(cpufreq_gov_conservative);
+ 
+ static int __init cpufreq_gov_dbs_init(void)
+ {
+diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c
+index 33855cb..2ab3c12 100644
+--- a/drivers/cpufreq/cpufreq_ondemand.c
++++ b/drivers/cpufreq/cpufreq_ondemand.c
+@@ -18,13 +18,19 @@
+ #include <linux/jiffies.h>
+ #include <linux/kernel_stat.h>
+ #include <linux/mutex.h>
++#include <linux/hrtimer.h>
++#include <linux/tick.h>
++#include <linux/ktime.h>
+ 
+ /*
+  * dbs is used in this file as a shortform for demandbased switching
+  * It helps to keep variable names smaller, simpler
+  */
+ 
++#define DEF_FREQUENCY_DOWN_DIFFERENTIAL		(10)
+ #define DEF_FREQUENCY_UP_THRESHOLD		(80)
++#define MICRO_FREQUENCY_DOWN_DIFFERENTIAL	(3)
++#define MICRO_FREQUENCY_UP_THRESHOLD		(95)
+ #define MIN_FREQUENCY_UP_THRESHOLD		(11)
+ #define MAX_FREQUENCY_UP_THRESHOLD		(100)
+ 
+@@ -57,6 +63,7 @@ enum {DBS_NORMAL_SAMPLE, DBS_SUB_SAMPLE};
+ struct cpu_dbs_info_s {
+ 	cputime64_t prev_cpu_idle;
+ 	cputime64_t prev_cpu_wall;
++	cputime64_t prev_cpu_nice;
+ 	struct cpufreq_policy *cur_policy;
+  	struct delayed_work work;
+ 	struct cpufreq_frequency_table *freq_table;
+@@ -86,21 +93,24 @@ static struct workqueue_struct	*kondemand_wq;
+ static struct dbs_tuners {
+ 	unsigned int sampling_rate;
+ 	unsigned int up_threshold;
++	unsigned int down_differential;
+ 	unsigned int ignore_nice;
+ 	unsigned int powersave_bias;
+ } dbs_tuners_ins = {
+ 	.up_threshold = DEF_FREQUENCY_UP_THRESHOLD,
++	.down_differential = DEF_FREQUENCY_DOWN_DIFFERENTIAL,
+ 	.ignore_nice = 0,
+ 	.powersave_bias = 0,
+ };
+ 
+-static inline cputime64_t get_cpu_idle_time(unsigned int cpu)
++static inline cputime64_t get_cpu_idle_time_jiffy(unsigned int cpu,
++							cputime64_t *wall)
+ {
+ 	cputime64_t idle_time;
+-	cputime64_t cur_jiffies;
++	cputime64_t cur_wall_time;
+ 	cputime64_t busy_time;
+ 
+-	cur_jiffies = jiffies64_to_cputime64(get_jiffies_64());
++	cur_wall_time = jiffies64_to_cputime64(get_jiffies_64());
+ 	busy_time = cputime64_add(kstat_cpu(cpu).cpustat.user,
+ 			kstat_cpu(cpu).cpustat.system);
+ 
+@@ -113,7 +123,37 @@ static inline cputime64_t get_cpu_idle_time(unsigned int cpu)
+ 				kstat_cpu(cpu).cpustat.nice);
+ 	}
+ 
+-	idle_time = cputime64_sub(cur_jiffies, busy_time);
++	idle_time = cputime64_sub(cur_wall_time, busy_time);
++	if (wall)
++		*wall = cur_wall_time;
++
++	return idle_time;
++}
++
++static inline cputime64_t get_cpu_idle_time(unsigned int cpu, cputime64_t *wall)
++{
++	u64 idle_time = get_cpu_idle_time_us(cpu, wall);
++
++	if (idle_time == -1ULL)
++		return get_cpu_idle_time_jiffy(cpu, wall);
++
++	if (dbs_tuners_ins.ignore_nice) {
++		cputime64_t cur_nice;
++		unsigned long cur_nice_jiffies;
++		struct cpu_dbs_info_s *dbs_info;
++
++		dbs_info = &per_cpu(cpu_dbs_info, cpu);
++		cur_nice = cputime64_sub(kstat_cpu(cpu).cpustat.nice,
++					 dbs_info->prev_cpu_nice);
++		/*
++		 * Assumption: nice time between sampling periods will be
++		 * less than 2^32 jiffies for 32 bit sys
++		 */
++		cur_nice_jiffies = (unsigned long)
++					cputime64_to_jiffies64(cur_nice);
++		dbs_info->prev_cpu_nice = kstat_cpu(cpu).cpustat.nice;
++		return idle_time + jiffies_to_usecs(cur_nice_jiffies);
++	}
+ 	return idle_time;
+ }
+ 
+@@ -277,8 +317,8 @@ static ssize_t store_ignore_nice_load(struct cpufreq_policy *policy,
+ 	for_each_online_cpu(j) {
+ 		struct cpu_dbs_info_s *dbs_info;
+ 		dbs_info = &per_cpu(cpu_dbs_info, j);
+-		dbs_info->prev_cpu_idle = get_cpu_idle_time(j);
+-		dbs_info->prev_cpu_wall = get_jiffies_64();
++		dbs_info->prev_cpu_idle = get_cpu_idle_time(j,
++						&dbs_info->prev_cpu_wall);
+ 	}
+ 	mutex_unlock(&dbs_mutex);
+ 
+@@ -334,9 +374,7 @@ static struct attribute_group dbs_attr_group = {
+ 
+ static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info)
+ {
+-	unsigned int idle_ticks, total_ticks;
+-	unsigned int load = 0;
+-	cputime64_t cur_jiffies;
++	unsigned int max_load_freq;
+ 
+ 	struct cpufreq_policy *policy;
+ 	unsigned int j;
+@@ -346,13 +384,7 @@ static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info)
+ 
+ 	this_dbs_info->freq_lo = 0;
+ 	policy = this_dbs_info->cur_policy;
+-	cur_jiffies = jiffies64_to_cputime64(get_jiffies_64());
+-	total_ticks = (unsigned int) cputime64_sub(cur_jiffies,
+-			this_dbs_info->prev_cpu_wall);
+-	this_dbs_info->prev_cpu_wall = get_jiffies_64();
+ 
+-	if (!total_ticks)
+-		return;
+ 	/*
+ 	 * Every sampling_rate, we check, if current idle time is less
+ 	 * than 20% (default), then we try to increase frequency
+@@ -365,27 +397,44 @@ static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info)
+ 	 * 5% (default) of current frequency
+ 	 */
+ 
+-	/* Get Idle Time */
+-	idle_ticks = UINT_MAX;
++	/* Get Absolute Load - in terms of freq */
++	max_load_freq = 0;
++
+ 	for_each_cpu_mask_nr(j, policy->cpus) {
+-		cputime64_t total_idle_ticks;
+-		unsigned int tmp_idle_ticks;
+ 		struct cpu_dbs_info_s *j_dbs_info;
++		cputime64_t cur_wall_time, cur_idle_time;
++		unsigned int idle_time, wall_time;
++		unsigned int load, load_freq;
++		int freq_avg;
+ 
+ 		j_dbs_info = &per_cpu(cpu_dbs_info, j);
+-		total_idle_ticks = get_cpu_idle_time(j);
+-		tmp_idle_ticks = (unsigned int) cputime64_sub(total_idle_ticks,
++
++		cur_idle_time = get_cpu_idle_time(j, &cur_wall_time);
++
++		wall_time = (unsigned int) cputime64_sub(cur_wall_time,
++				j_dbs_info->prev_cpu_wall);
++		j_dbs_info->prev_cpu_wall = cur_wall_time;
++
++		idle_time = (unsigned int) cputime64_sub(cur_idle_time,
+ 				j_dbs_info->prev_cpu_idle);
+-		j_dbs_info->prev_cpu_idle = total_idle_ticks;
++		j_dbs_info->prev_cpu_idle = cur_idle_time;
++
++		if (unlikely(!wall_time || wall_time < idle_time))
++			continue;
++
++		load = 100 * (wall_time - idle_time) / wall_time;
++
++		freq_avg = __cpufreq_driver_getavg(policy, j);
++		if (freq_avg <= 0)
++			freq_avg = policy->cur;
+ 
+-		if (tmp_idle_ticks < idle_ticks)
+-			idle_ticks = tmp_idle_ticks;
++		load_freq = load * freq_avg;
++		if (load_freq > max_load_freq)
++			max_load_freq = load_freq;
+ 	}
+-	if (likely(total_ticks > idle_ticks))
+-		load = (100 * (total_ticks - idle_ticks)) / total_ticks;
+ 
+ 	/* Check for frequency increase */
+-	if (load > dbs_tuners_ins.up_threshold) {
++	if (max_load_freq > dbs_tuners_ins.up_threshold * policy->cur) {
+ 		/* if we are already at full speed then break out early */
+ 		if (!dbs_tuners_ins.powersave_bias) {
+ 			if (policy->cur == policy->max)
+@@ -412,15 +461,13 @@ static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info)
+ 	 * can support the current CPU usage without triggering the up
+ 	 * policy. To be safe, we focus 10 points under the threshold.
+ 	 */
+-	if (load < (dbs_tuners_ins.up_threshold - 10)) {
+-		unsigned int freq_next, freq_cur;
+-
+-		freq_cur = __cpufreq_driver_getavg(policy);
+-		if (!freq_cur)
+-			freq_cur = policy->cur;
+-
+-		freq_next = (freq_cur * load) /
+-			(dbs_tuners_ins.up_threshold - 10);
++	if (max_load_freq <
++	    (dbs_tuners_ins.up_threshold - dbs_tuners_ins.down_differential) *
++	     policy->cur) {
++		unsigned int freq_next;
++		freq_next = max_load_freq /
++				(dbs_tuners_ins.up_threshold -
++				 dbs_tuners_ins.down_differential);
+ 
+ 		if (!dbs_tuners_ins.powersave_bias) {
+ 			__cpufreq_driver_target(policy, freq_next,
+@@ -526,8 +573,8 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
+ 			j_dbs_info = &per_cpu(cpu_dbs_info, j);
+ 			j_dbs_info->cur_policy = policy;
+ 
+-			j_dbs_info->prev_cpu_idle = get_cpu_idle_time(j);
+-			j_dbs_info->prev_cpu_wall = get_jiffies_64();
++			j_dbs_info->prev_cpu_idle = get_cpu_idle_time(j,
++						&j_dbs_info->prev_cpu_wall);
+ 		}
+ 		this_dbs_info->cpu = cpu;
+ 		/*
+@@ -579,22 +626,42 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
+ 	return 0;
+ }
+ 
++#ifndef CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND
++static
++#endif
+ struct cpufreq_governor cpufreq_gov_ondemand = {
+ 	.name			= "ondemand",
+ 	.governor		= cpufreq_governor_dbs,
+ 	.max_transition_latency = TRANSITION_LATENCY_LIMIT,
+ 	.owner			= THIS_MODULE,
+ };
+-EXPORT_SYMBOL(cpufreq_gov_ondemand);
+ 
+ static int __init cpufreq_gov_dbs_init(void)
+ {
++	int err;
++	cputime64_t wall;
++	u64 idle_time;
++	int cpu = get_cpu();
++
++	idle_time = get_cpu_idle_time_us(cpu, &wall);
++	put_cpu();
++	if (idle_time != -1ULL) {
++		/* Idle micro accounting is supported. Use finer thresholds */
++		dbs_tuners_ins.up_threshold = MICRO_FREQUENCY_UP_THRESHOLD;
++		dbs_tuners_ins.down_differential =
++					MICRO_FREQUENCY_DOWN_DIFFERENTIAL;
++	}
++
+ 	kondemand_wq = create_workqueue("kondemand");
+ 	if (!kondemand_wq) {
+ 		printk(KERN_ERR "Creation of kondemand failed\n");
+ 		return -EFAULT;
+ 	}
+-	return cpufreq_register_governor(&cpufreq_gov_ondemand);
++	err = cpufreq_register_governor(&cpufreq_gov_ondemand);
++	if (err)
++		destroy_workqueue(kondemand_wq);
++
++	return err;
+ }
+ 
+ static void __exit cpufreq_gov_dbs_exit(void)
+diff --git a/drivers/cpufreq/cpufreq_performance.c b/drivers/cpufreq/cpufreq_performance.c
+index e8e1451..7e2e515 100644
+--- a/drivers/cpufreq/cpufreq_performance.c
++++ b/drivers/cpufreq/cpufreq_performance.c
+@@ -36,12 +36,14 @@ static int cpufreq_governor_performance(struct cpufreq_policy *policy,
+ 	return 0;
+ }
+ 
++#ifdef CONFIG_CPU_FREQ_GOV_PERFORMANCE_MODULE
++static
++#endif
+ struct cpufreq_governor cpufreq_gov_performance = {
+ 	.name		= "performance",
+ 	.governor	= cpufreq_governor_performance,
+ 	.owner		= THIS_MODULE,
+ };
+-EXPORT_SYMBOL(cpufreq_gov_performance);
+ 
+ 
+ static int __init cpufreq_gov_performance_init(void)
+diff --git a/drivers/cpufreq/cpufreq_powersave.c b/drivers/cpufreq/cpufreq_powersave.c
+index 88d2f44..e6db5fa 100644
+--- a/drivers/cpufreq/cpufreq_powersave.c
++++ b/drivers/cpufreq/cpufreq_powersave.c
+@@ -35,12 +35,14 @@ static int cpufreq_governor_powersave(struct cpufreq_policy *policy,
+ 	return 0;
+ }
+ 
++#ifndef CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE
++static
++#endif
+ struct cpufreq_governor cpufreq_gov_powersave = {
+ 	.name		= "powersave",
+ 	.governor	= cpufreq_governor_powersave,
+ 	.owner		= THIS_MODULE,
+ };
+-EXPORT_SYMBOL(cpufreq_gov_powersave);
+ 
+ static int __init cpufreq_gov_powersave_init(void)
+ {
+diff --git a/drivers/cpufreq/cpufreq_userspace.c b/drivers/cpufreq/cpufreq_userspace.c
+index 32244aa..1442bba 100644
+--- a/drivers/cpufreq/cpufreq_userspace.c
++++ b/drivers/cpufreq/cpufreq_userspace.c
+@@ -187,6 +187,9 @@ static int cpufreq_governor_userspace(struct cpufreq_policy *policy,
+ }
+ 
+ 
++#ifndef CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE
++static
++#endif
+ struct cpufreq_governor cpufreq_gov_userspace = {
+ 	.name		= "userspace",
+ 	.governor	= cpufreq_governor_userspace,
+@@ -194,7 +197,6 @@ struct cpufreq_governor cpufreq_gov_userspace = {
+ 	.show_setspeed	= show_speed,
+ 	.owner		= THIS_MODULE,
+ };
+-EXPORT_SYMBOL(cpufreq_gov_userspace);
+ 
+ static int __init cpufreq_gov_userspace_init(void)
+ {
+diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
+index 6fd5668..1ee608f 100644
+--- a/include/linux/cpufreq.h
++++ b/include/linux/cpufreq.h
+@@ -187,7 +187,8 @@ extern int __cpufreq_driver_target(struct cpufreq_policy *policy,
+ 				   unsigned int relation);
+ 
+ 
+-extern int __cpufreq_driver_getavg(struct cpufreq_policy *policy);
++extern int __cpufreq_driver_getavg(struct cpufreq_policy *policy,
++				   unsigned int cpu);
+ 
+ int cpufreq_register_governor(struct cpufreq_governor *governor);
+ void cpufreq_unregister_governor(struct cpufreq_governor *governor);
+@@ -226,7 +227,9 @@ struct cpufreq_driver {
+ 	unsigned int	(*get)	(unsigned int cpu);
+ 
+ 	/* optional */
+-	unsigned int (*getavg)	(unsigned int cpu);
++	unsigned int (*getavg)	(struct cpufreq_policy *policy,
++				 unsigned int cpu);
++
+ 	int	(*exit)		(struct cpufreq_policy *policy);
+ 	int	(*suspend)	(struct cpufreq_policy *policy, pm_message_t pmsg);
+ 	int	(*resume)	(struct cpufreq_policy *policy);
+diff --git a/include/linux/tick.h b/include/linux/tick.h
+index 8cf8cfe..98921a3 100644
+--- a/include/linux/tick.h
++++ b/include/linux/tick.h
+@@ -126,7 +126,7 @@ static inline ktime_t tick_nohz_get_sleep_length(void)
+ 	return len;
+ }
+ static inline void tick_nohz_stop_idle(int cpu) { }
+-static inline u64 get_cpu_idle_time_us(int cpu, u64 *unused) { return 0; }
++static inline u64 get_cpu_idle_time_us(int cpu, u64 *unused) { return -1; }
+ # endif /* !NO_HZ */
+ 
+ #endif
+diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c
+index cb02324..a4d2193 100644
+--- a/kernel/time/tick-sched.c
++++ b/kernel/time/tick-sched.c
+@@ -20,6 +20,7 @@
+ #include <linux/profile.h>
+ #include <linux/sched.h>
+ #include <linux/tick.h>
++#include <linux/module.h>
+ 
+ #include <asm/irq_regs.h>
+ 
+@@ -190,9 +191,17 @@ u64 get_cpu_idle_time_us(int cpu, u64 *last_update_time)
+ {
+ 	struct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu);
+ 
+-	*last_update_time = ktime_to_us(ts->idle_lastupdate);
++	if (!tick_nohz_enabled)
++		return -1;
++
++	if (ts->idle_active)
++		*last_update_time = ktime_to_us(ts->idle_lastupdate);
++	else
++		*last_update_time = ktime_to_us(ktime_get());
++
+ 	return ktime_to_us(ts->idle_sleeptime);
+ }
++EXPORT_SYMBOL_GPL(get_cpu_idle_time_us);
+ 
+ /**
+  * tick_nohz_stop_sched_tick - stop the idle tick from the idle task


Index: TODO
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/devel/TODO,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- TODO	6 Oct 2008 17:13:42 -0000	1.5
+++ TODO	6 Oct 2008 19:55:32 -0000	1.6
@@ -1,3 +1,7 @@
+git-cpufreq.patch
+	Assorted fixes/improvements, especially to the ondemand governor.
+	Will go upstream in 2.6.28
+
 drm-modesetting-i915.patch
 drm-modesetting-radeon.patch
 linux-2.6-export-shmem-bits-for-gem.patch


Index: kernel.spec
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/devel/kernel.spec,v
retrieving revision 1.1019
retrieving revision 1.1020
diff -u -r1.1019 -r1.1020
--- kernel.spec	6 Oct 2008 17:11:35 -0000	1.1019
+++ kernel.spec	6 Oct 2008 19:55:32 -0000	1.1020
@@ -562,14 +562,18 @@
 Patch02: git-linus.diff
 
 # we always need nonintconfig, even for -vanilla kernels
-Patch06: linux-2.6-build-nonintconfig.patch
+Patch03: linux-2.6-build-nonintconfig.patch
 
 # we also need compile fixes for -vanilla
-Patch07: linux-2.6-compile-fixes.patch
+Patch04: linux-2.6-compile-fixes.patch
 
 %if !%{nopatches}
 
-Patch10: linux-2.6-hotfixes.patch
+# Git trees.
+Patch5: git-cpufreq.patch
+
+# Standalone patches
+Patch20: linux-2.6-hotfixes.patch
 
 Patch21: linux-2.6-utrace.patch
 Patch22: linux-2.6-x86-tracehook.patch
@@ -1017,6 +1021,8 @@
 
 %if !%{nopatches}
 
+ApplyPatch git-cpufreq.patch
+
 ApplyPatch linux-2.6-hotfixes.patch
 
 # Roland's utrace ptrace replacement.
@@ -1783,6 +1789,9 @@
 %kernel_variant_files -k vmlinux %{with_kdump} kdump
 
 %changelog
+* Mon Oct 06 2008 Dave Jones <davej at redhat.com>
+- Add cpufreq.git bits queued for 2.6.28.
+
 * Mon Oct 06 2008 Jarod Wilson <jarod at redhat.com>
 - Add driver for Hauppauge HD PVR
 




More information about the scm-commits mailing list