* [PATCH 2.5.54] cpufreq: update timer notifier
@ 2003-01-06 13:55 Dominik Brodowski
2003-01-06 21:34 ` Andrew Morton
0 siblings, 1 reply; 3+ messages in thread
From: Dominik Brodowski @ 2003-01-06 13:55 UTC (permalink / raw)
To: torvalds; +Cc: linux-kernel, cpufreq
- global loops_per_jiffy, x86 cpu_khz and x86
fast_gettimeoffset_quotient can only be safely adjusted on UP
- x86 per-CPU loops_per_jiffy does not depend on TSC
- save reference values so that rounding errors do not accumulate
arch/i386/kernel/timers/timer_tsc.c | 54 ++++++++++++++++++------------------
kernel/cpufreq.c | 20 ++++++++++---
2 files changed, 42 insertions(+), 32 deletions(-)
diff -ruN linux-original/arch/i386/kernel/timers/timer_tsc.c linux/arch/i386/kernel/timers/timer_tsc.c
--- linux-original/arch/i386/kernel/timers/timer_tsc.c 2003-01-06 12:55:43.000000000 +0100
+++ linux/arch/i386/kernel/timers/timer_tsc.c 2003-01-06 14:20:31.000000000 +0100
@@ -189,39 +189,38 @@
#ifdef CONFIG_CPU_FREQ
+static unsigned int ref_freq = 0;
+static unsigned long loops_per_jiffy_ref = 0;
+
+#ifndef CONFIG_SMP
+static unsigned long fast_gettimeoffset_ref = 0;
+static unsigned long cpu_khz_ref = 0;
+#endif
static int
time_cpufreq_notifier(struct notifier_block *nb, unsigned long val,
void *data)
{
struct cpufreq_freqs *freq = data;
- unsigned int i;
- if (!cpu_has_tsc)
- return 0;
+ if (!ref_freq) {
+ ref_freq = freq->old;
+ loops_per_jiffy_ref = cpu_data[freq->cpu].loops_per_jiffy;
+#ifndef CONFIG_SMP
+ fast_gettimeoffset_ref = fast_gettimeoffset_quotient;
+ cpu_khz_ref = cpu_khz;
+#endif
+ }
- switch (val) {
- case CPUFREQ_PRECHANGE:
- if ((freq->old < freq->new) &&
- ((freq->cpu == CPUFREQ_ALL_CPUS) || (freq->cpu == 0))) {
- cpu_khz = cpufreq_scale(cpu_khz, freq->old, freq->new);
- fast_gettimeoffset_quotient = cpufreq_scale(fast_gettimeoffset_quotient, freq->new, freq->old);
- }
- for (i=0; i<NR_CPUS; i++)
- if ((freq->cpu == CPUFREQ_ALL_CPUS) || (freq->cpu == i))
- cpu_data[i].loops_per_jiffy = cpufreq_scale(cpu_data[i].loops_per_jiffy, freq->old, freq->new);
- break;
-
- case CPUFREQ_POSTCHANGE:
- if ((freq->new < freq->old) &&
- ((freq->cpu == CPUFREQ_ALL_CPUS) || (freq->cpu == 0))) {
- cpu_khz = cpufreq_scale(cpu_khz, freq->old, freq->new);
- fast_gettimeoffset_quotient = cpufreq_scale(fast_gettimeoffset_quotient, freq->new, freq->old);
+ if ((val == CPUFREQ_PRECHANGE && freq->old < freq->new) ||
+ (val == CPUFREQ_POSTCHANGE && freq->old > freq->new)) {
+ cpu_data[freq->cpu].loops_per_jiffy = cpufreq_scale(loops_per_jiffy_ref, ref_freq, freq->new);
+#ifndef CONFIG_SMP
+ if (use_tsc) {
+ fast_gettimeoffset_quotient = cpufreq_scale(fast_gettimeoffset_ref, freq->new, ref_freq);
+ cpu_khz = cpufreq_scale(cpu_khz_ref, ref_freq, freq->new);
}
- for (i=0; i<NR_CPUS; i++)
- if ((freq->cpu == CPUFREQ_ALL_CPUS) || (freq->cpu == i))
- cpu_data[i].loops_per_jiffy = cpufreq_scale(cpu_data[i].loops_per_jiffy, freq->old, freq->new);
- break;
+#endif
}
return 0;
@@ -260,6 +259,10 @@
* moaned if you have the only one in the world - you fix it!
*/
+#ifdef CONFIG_CPU_FREQ
+ cpufreq_register_notifier(&time_cpufreq_notifier_block, CPUFREQ_TRANSITION_NOTIFIER);
+#endif
+
if (cpu_has_tsc) {
unsigned long tsc_quotient = calibrate_tsc();
if (tsc_quotient) {
@@ -282,9 +285,6 @@
"0" (eax), "1" (edx));
printk("Detected %lu.%03lu MHz processor.\n", cpu_khz / 1000, cpu_khz % 1000);
}
-#ifdef CONFIG_CPU_FREQ
- cpufreq_register_notifier(&time_cpufreq_notifier_block, CPUFREQ_TRANSITION_NOTIFIER);
-#endif
return 0;
}
}
diff -ruN linux-original/kernel/cpufreq.c linux/kernel/cpufreq.c
--- linux-original/kernel/cpufreq.c 2003-01-06 12:55:43.000000000 +0100
+++ linux/kernel/cpufreq.c 2003-01-06 13:57:18.000000000 +0100
@@ -927,17 +927,27 @@
* adjust_jiffies - adjust the system "loops_per_jiffy"
*
* This function alters the system "loops_per_jiffy" for the clock
- * speed change. Note that loops_per_jiffy is only updated if all
- * CPUs are affected - else there is a need for per-CPU loops_per_jiffy
- * values which are provided by various architectures.
+ * speed change. Note that loops_per_jiffy cannot be updated on SMP
+ * systems as each CPU might be scaled differently. So, use the arch
+ * per-CPU loops_per_jiffy value wherever possible.
*/
+#ifndef CONFIG_SMP
+static unsigned long l_p_j_ref = 0;
+static unsigned int l_p_j_ref_freq = 0;
+
static inline void adjust_jiffies(unsigned long val, struct cpufreq_freqs *ci)
{
+ if (!l_p_j_ref_freq) {
+ l_p_j_ref = loops_per_jiffy;
+ l_p_j_ref_freq = ci->old;
+ }
if ((val == CPUFREQ_PRECHANGE && ci->old < ci->new) ||
(val == CPUFREQ_POSTCHANGE && ci->old > ci->new))
- if (ci->cpu == CPUFREQ_ALL_CPUS)
- loops_per_jiffy = cpufreq_scale(loops_per_jiffy, ci->old, ci->new);
+ loops_per_jiffy = cpufreq_scale(l_p_j_ref, l_p_j_ref_freq, ci->new);
}
+#else
+#define adjust_jiffies(...)
+#endif
/**
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH 2.5.54] cpufreq: update timer notifier
2003-01-06 13:55 [PATCH 2.5.54] cpufreq: update timer notifier Dominik Brodowski
@ 2003-01-06 21:34 ` Andrew Morton
2003-01-06 22:34 ` [PATCH] cpufreq: make gcc-2.91.66 happy (Was: Re: [PATCH 2.5.54] cpufreq: update timer notifier) Dominik Brodowski
0 siblings, 1 reply; 3+ messages in thread
From: Andrew Morton @ 2003-01-06 21:34 UTC (permalink / raw)
To: Dominik Brodowski; +Cc: torvalds, linux-kernel, cpufreq
Dominik Brodowski wrote:
>
> +#else
> +#define adjust_jiffies(...)
> +#endif
This will fail to compile on gcc-2.91.66. It's OK on 2.95.3.
sparc64 requires a compiler of similar vintage (2.92.11), so
I am trying to keep 2.91.66-on-x86 limping along so that breakage
can be detected more easily.
Please use
#define adjust_jiffies(x...) do {} while (0)
here. Or an empty inline, which tends to be nicer, because you
still get argument type checking.
^ permalink raw reply [flat|nested] 3+ messages in thread
* [PATCH] cpufreq: make gcc-2.91.66 happy (Was: Re: [PATCH 2.5.54] cpufreq: update timer notifier)
2003-01-06 21:34 ` Andrew Morton
@ 2003-01-06 22:34 ` Dominik Brodowski
0 siblings, 0 replies; 3+ messages in thread
From: Dominik Brodowski @ 2003-01-06 22:34 UTC (permalink / raw)
To: Andrew Morton, torvalds; +Cc: linux-kernel, cpufreq
This patch updates the cpufreq #defines so that gcc-2.91.66 should
work happily with cpufreq.
On Mon, Jan 06, 2003 at 01:34:31PM -0800, Andrew Morton wrote:
> Dominik Brodowski wrote:
> >
> > +#else
> > +#define adjust_jiffies(...)
> > +#endif
>
> This will fail to compile on gcc-2.91.66. It's OK on 2.95.3.
>
> sparc64 requires a compiler of similar vintage (2.92.11), so
> I am trying to keep 2.91.66-on-x86 limping along so that breakage
> can be detected more easily.
>
> Please use
>
> #define adjust_jiffies(x...) do {} while (0)
>
> here. Or an empty inline, which tends to be nicer, because you
> still get argument type checking.
diff -ruN linux-original/kernel/cpufreq.c linux/kernel/cpufreq.c
--- linux-original/kernel/cpufreq.c 2003-01-06 23:27:59.000000000 +0100
+++ linux/kernel/cpufreq.c 2003-01-06 23:29:49.000000000 +0100
@@ -734,8 +734,8 @@
}
#else
-#define cpufreq_sysctl_init()
-#define cpufreq_sysctl_exit()
+#define cpufreq_sysctl_init() do {} while(0)
+#define cpufreq_sysctl_exit() do {} while(0)
#endif /* CONFIG_SYSCTL */
#endif /* CONFIG_CPU_FREQ_24_API */
@@ -946,7 +946,7 @@
loops_per_jiffy = cpufreq_scale(l_p_j_ref, l_p_j_ref_freq, ci->new);
}
#else
-#define adjust_jiffies(...)
+#define adjust_jiffies(x...) do {} while (0)
#endif
@@ -1131,6 +1131,6 @@
}
EXPORT_SYMBOL_GPL(cpufreq_restore);
#else
-#define cpufreq_restore()
+#define cpufreq_restore() do {} while (0)
#endif /* CONFIG_PM */
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2003-01-06 22:25 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2003-01-06 13:55 [PATCH 2.5.54] cpufreq: update timer notifier Dominik Brodowski
2003-01-06 21:34 ` Andrew Morton
2003-01-06 22:34 ` [PATCH] cpufreq: make gcc-2.91.66 happy (Was: Re: [PATCH 2.5.54] cpufreq: update timer notifier) Dominik Brodowski
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.