Dynamic tick for x86 version 050602-1
Quoted 41 lines
-----Original Message-----
From: [email protected] [mailto:[email protected]] On Behalf Of Jonathan Corbet
Sent: Tuesday, June 07, 2005 1:36 PM
To: Tony Lindgren
Cc: [email protected]
Subject: Re: [PATCH] Dynamic tick for x86 version 050602-1Quoted 1 line · Tony Lindgren
---
linux-dev.orig/arch/i386/kernel/irq.c2005-06-0117:51:36.000000000 -0700
Quoted 1 line
+++
linux-dev/arch/i386/kernel/irq.c2005-06-0117:54:32.000000000 -0700
Review fastcall unsigned int do_IRQ(struct pt_r · line 108
Quoted 8 lines
[...]
(quoted diff) +3
-0@@ -102,6 +103,12 @@ fastcall unsigned int do_IRQ(struct pt_r ); } else #endif + +#ifdef CONFIG_NO_IDLE_HZ + if (dyn_tick->state & (DYN_TICK_ENABLED |
DYN_TICK_SKIPPING) && irq != 0)Review fastcall unsigned int do_IRQ(struct pt_r · line 112
Quoted 4 lines
(quoted diff) +3
-0+ dyn_tick->interrupt(irq, NULL, regs); +#endif + __do_IRQ(irq, regs);Forgive me if I'm being obtuse (again...), but this hunk doesn't look like it would work well in the 4K stacks case. When 4K stacks are being
used,dyn_tick->interrupt()will only get called in the nested interrupt
case, when the interrupt stack is already in use. This change also pushes the non-assembly__do_IRQ()call out of the else branch, meaning that, when the switch is made to the interrupt stack (most of the time),__do_IRQ()will be called twice for the same interrupt.
Quoted 4 lines
It looks to me like you want to put your #ifdef chunk *after* the call to
__do_IRQ(), unless you have some reason for needing it to happen before the regular interrupt handler is invoked.
Good catch. This indeed looks like a bug.
With 050602-1 version I am seeing double the number of calls to timer_interrupt routine than expected. Say, when all CPUs are fully busy,
I see 2*HZ timer interrupt count in /proc/interrupts
And things look normal once I change this hunk as below
Quoted 3 lines
Review fastcall unsigned int do_IRQ(struct pt_r
Quoted 3 lines
(quoted diff) +1
-0} else #endif +
+ {
Quoted 7 lines
Review
Quoted 2 lines
(quoted diff) +2
-0+#ifdef CONFIG_NO_IDLE_HZ + if (dyn_tick->state & (DYN_TICK_ENABLED |
DYN_TICK_SKIPPING) && irq != 0)Review
Quoted 4 lines
(quoted diff) +3
-0+ dyn_tick->interrupt(irq, NULL, regs); +#endif + __do_IRQ(irq, regs);
+ }
Thanks,
Venki
Quoted 58 lines · Pallipadi, Venkatesh
Quoted 41 lines
-----Original Message-----
From: [email protected] [mailto:[email protected]] On Behalf Of Jonathan Corbet
Sent: Tuesday, June 07, 2005 1:36 PM
To: Tony Lindgren
Cc: [email protected]
Subject: Re: [PATCH] Dynamic tick for x86 version 050602-1Quoted 1 line · Tony Lindgren
---
linux-dev.orig/arch/i386/kernel/irq.c2005-06-0117:51:36.000000000 -0700
Quoted 1 line
+++
linux-dev/arch/i386/kernel/irq.c2005-06-0117:54:32.000000000 -0700
Review fastcall unsigned int do_IRQ(struct pt_r · line 108
Quoted 8 lines
[...]
(quoted diff) +3
-0@@ -102,6 +103,12 @@ fastcall unsigned int do_IRQ(struct pt_r ); } else #endif + +#ifdef CONFIG_NO_IDLE_HZ + if (dyn_tick->state & (DYN_TICK_ENABLED |
DYN_TICK_SKIPPING) && irq != 0)Review fastcall unsigned int do_IRQ(struct pt_r · line 112
Quoted 4 lines
(quoted diff) +3
-0+ dyn_tick->interrupt(irq, NULL, regs); +#endif + __do_IRQ(irq, regs);Forgive me if I'm being obtuse (again...), but this hunk doesn't look like it would work well in the 4K stacks case. When 4K stacks are being
used,dyn_tick->interrupt()will only get called in the nested interrupt
case, when the interrupt stack is already in use. This change also pushes the non-assembly__do_IRQ()call out of the else branch, meaning that, when the switch is made to the interrupt stack (most of the time),__do_IRQ()will be called twice for the same interrupt.Quoted 4 lines
It looks to me like you want to put your #ifdef chunk *after* the call to
__do_IRQ(), unless you have some reason for needing it to happen before the regular interrupt handler is invoked.Good catch. This indeed looks like a bug.
With 050602-1 version I am seeing double the number of calls totimer_interruptroutine than expected. Say, when all CPUs are fully busy,
I see 2*HZ timer interrupt count in/proc/interruptsAnd things look normal once I change this hunk as below
Quoted 3 lines
Review fastcall unsigned int do_IRQ(struct pt_r
Quoted 3 lines
(quoted diff) +1
-0} else #endif ++ {
Quoted 8 lines
Quoted 7 lines
Review
Quoted 2 lines
(quoted diff) +2
-0+#ifdef CONFIG_NO_IDLE_HZ + if (dyn_tick->state & (DYN_TICK_ENABLED |
DYN_TICK_SKIPPING) && irq != 0)Review
Quoted 4 lines
(quoted diff) +3
-0+ dyn_tick->interrupt(irq, NULL, regs); +#endif + __do_IRQ(irq, regs);+ }
Cool. Sorry for not responding earlier, my hard drive crashed yesterday morning... I also managed to fry my spare computer's motherboard while trying to recover some data from the broken disk :)
I'll try to post an updated patch tomorrow.
Tony
PATCH 1/1 Dynamic tick for x86 version 050609-2
Hi all,
Thanks for all the comments. Here's an updated dyntick patch.
Changes from last patch:
- Patch from Bernard Blackham for missing for cpu_has_local_apic()
- Fixed interrupt code as noted by Pavel Machek, Jonathan Corbet and Venkatesh Pallipadi.
- Added kernel command line options as in the ARM patch uggested by Russell King. You now need to pass:
dyntick=enable
and possibly dyntick=enable,forceapic if you have a P3 system that works with dyntick with APIC. (P4 won't).
You can also enable dyntick via sysfs during runtime:
# echo 1 > /sys/devices/system/timer/timer0/dyn_tick_state
- Separated debug code into another optional patch available at:
http://muru.com/linux/dyntick/
Regards,
Tony
arch/i386/Kconfig +31 -0
@@ -458,6 +458,37 @@ bool "Provide RTC interrupt" depends on HPET_TIMER && RTC=y +config NO_IDLE_HZ + bool "Dynamic Tick Timer - Skip timer ticks during idle" + help + This option enables support for skipping timer ticks when the + processor is idle. During system load, timer is continuous. + This option saves power, as it allows the system to stay in + idle mode longer. Currently supported timers are ACPI PM + timer, local APIC timer, and TSC timer. HPET timer is currently + not supported. + + Note that you need to enable dynamic tick timer either by + passing dyntick=enable command line option, or via sysfs: + + # echo 1 > /sys/devices/system/timer/timer0/dyn_tick_state + +config DYN_TICK_USE_APIC + bool "Use APIC timer instead of PIT timer" + help + This option enables using APIC timer interrupt if your hardware + supports it. APIC timer allows longer sleep periods compared + to PIT timer. + + Note that on most recent hardware disabling PIT timer also + disables APIC timer interrupts, and system won't run properly. + Symptoms include slow system boot, and time running slow. + + If unsure, don't enable this option. + + Note that to you still need to pass dyntick=enable,forceapic + command line option to use APIC timer. + config SMP bool "Symmetric multi-processing support" ---help---
arch/i386/kernel/Makefile +1 -0
@@ -31,6 +31,7 @@ obj-y += sysenter.o vsyscall.o obj-$(CONFIG_ACPI_SRAT) += srat.o obj-$(CONFIG_HPET_TIMER) += time_hpet.o +obj-$(CONFIG_NO_IDLE_HZ) += dyn-tick.o obj-$(CONFIG_EFI) += efi.o efi_stub.o obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
arch/i386/kernel/apic.c +49 -1
92 lines not on this page · raw message
arch/i386/kernel/dyn-tick.c new file +45 -0
45 lines not on this page · raw message
include/asm-i386/dyn-tick.h new file +42 -0
42 lines not on this page · raw message
arch/i386/kernel/irq.c +6 -0
@@ -15,6 +15,7 @@#include <linux/seq_file.h> #include <linux/interrupt.h> #include <linux/kernel_stat.h> +#include <linux/dyn-tick.h> DEFINE_PER_CPU(irq_cpustat_t, irq_stat) ____cacheline_maxaligned_in_smp;EXPORT_PER_CPU_SYMBOL (irq_stat);
@@ -73,6 +74,11 @@ }#endif +#ifdef CONFIG_NO_IDLE_HZ +if (dyn_tick->state & (DYN_TICK_ENABLED |DYN_TICK_SKIPPING ) && irq !=0 ) + dyn_tick->interrupt (irq,NULL , regs); +#endif +#ifdef CONFIG_4KSTACKS curctx = (union irq_ctx *)current_thread_info ();
arch/i386/kernel/process.c +3 -0
@@ -37,6 +37,7 @@#include <linux/kallsyms.h> #include <linux/ptrace.h> #include <linux/random.h> +#include <linux/dyn-tick.h> #include <asm/uaccess.h> #include <asm/pgtable.h>
@@ -160,6 +161,8 @@if (!idle) idle = default_idle; +dyn_tick_reprogram_timer (); +__get_cpu_var (irq_stat).idle_timestamp = jiffies;idle (); }
arch/i386/kernel/time.c +73 -1
103 lines not on this page · raw message
arch/i386/kernel/timers/timer_pm.c +2 -0
@@ -168,6 +168,7 @@ monotonic_base += delta *NSEC_PER_USEC ;write_sequnlock (&monotonic_lock); +#ifndef CONFIG_NO_IDLE_HZ /* convert to ticks */ delta += offset_delay; lost = delta / (USEC_PER_SEC /HZ );
@@ -184,6 +185,7 @@ first_run =0 ; offset_delay = 0; } +#endif }
arch/i386/kernel/timers/timer_tsc.c +5 -0
@@ -368,6 +368,7 @@rdtsc (last_tsc_low, last_tsc_high); +#ifndef CONFIG_NO_IDLE_HZ spin_lock (&i8253_lock);outb_p (0x00 ,PIT_MODE );/* latch the count ASAP */
@@ -435,11 +436,14 @@ cpufreq_delayed_get(); }else lost_count =0 ; +#endif +/* update the monotonic base value */ this_offset = ((unsigned long long )last_tsc_high<<32 )|last_tsc_low; monotonic_base +=cycles_2_ns (this_offset - last_offset);write_sequnlock (&monotonic_lock); +#ifndef CONFIG_NO_IDLE_HZ /* calculate delay_at_last_interrupt */ count = ((LATCH -1 ) - count) *TICK_SIZE ; delay_at_last_interrupt = (count +LATCH /2 ) /LATCH ;
@@ -450,6 +454,7 @@*/ if (lost &&abs (delay - delay_at_last_interrupt) > (900000 /HZ )) jiffies_64++; +#endif }static int __init init_tsc (char * override)
arch/i386/mach-default/setup.c +16 -0
@@ -85,6 +85,22 @@setup_irq (0 , &irq0); } +/** +* replace_timer_interrupt - allow replacing timer interrupt handler +* +* Description: +* Can be used to replace timer interrupt handler with a more optimized +* handler. Used for enabling and disabling of CONFIG_NO_IDLE_HZ. +*/ +void replace_timer_interrupt (void * new_handler) +{ +unsigned long flags; + +write_seqlock_irqsave (&xtime_lock, flags); + irq0.handler = new_handler; +write_sequnlock_irqrestore (&xtime_lock, flags); +} +#ifdef CONFIG_MCA /** * mca_nmi_hook - hook into MCA specific NMI chain
include/linux/dyn-tick.h new file +61 -0
61 lines not on this page · raw message
kernel/Makefile +1 -0
@@ -28,6 +28,7 @@ obj-$(CONFIG_SYSFS) += ksysfs.o obj-$(CONFIG_GENERIC_HARDIRQS) += irq/ obj-$(CONFIG_SECCOMP) += seccomp.o +obj-$(CONFIG_NO_IDLE_HZ) += dyn-tick.o ifneq ($(CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER),y) # According to Alan Modra <[email protected]>, the -fno-omit-frame-pointer is
kernel/dyn-tick.c new file +209 -0
209 lines not on this page · raw message
arch/i386/kernel/timers/timer_pit.c +37 -0
@@ -149,6 +149,43 @@return count; } +/* +* REVISIT: Looks like on P3 APIC timer keeps running if PIT mode +* is changed. On P4, changing PIT mode seems to kill +* APIC timer interrupts. Same thing with disabling PIT +* interrupt. +*/ +void disable_pit_timer (void ) +{ +extern spinlock_t i8253_lock; +unsigned long flags; +spin_lock_irqsave (&i8253_lock, flags); +outb_p (0x32 ,PIT_MODE );/* binary, mode 1, LSB/MSB, ch 0 */ +spin_unlock_irqrestore (&i8253_lock, flags); +} + +/* +* Reprograms the next timer interrupt +* PIT timer reprogramming code taken from APM code. +* Note that PIT timer is a 16-bit timer, which allows max +* skip of only few seconds. +*/ +void reprogram_pit_timer (int jiffies_to_skip) +{ +int skip; +extern spinlock_t i8253_lock; +unsigned long flags; + + skip = jiffies_to_skip *LATCH ; +if (skip >0xffff ) + skip =0xffff ; + +spin_lock_irqsave (&i8253_lock, flags); +outb_p (0x34 ,PIT_MODE );/* binary, mode 2, LSB/MSB, ch 0 */ +outb_p (skip &0xff ,PIT_CH0 );/* LSB */ +outb (skip >>8 ,PIT_CH0 );/* MSB */ +spin_unlock_irqrestore (&i8253_lock, flags); +}/* tsc timer_opts struct */ struct timer_opts timer_pit = {
Re: [PATCH] Dynamic tick for x86 version 050609-2
Hi!
Some more nitpicking...
Quoted 16 lines
kernel/dyn-tick.c new file +16
-0+/* +* --------------------------------------------------------------------------- +* Command line options +* --------------------------------------------------------------------------- +*/ +static int __initdata dyntick_autoenable =0 ; +static int __initdata dyntick_useapic =0 ; + +/* +* dyntick=[enable|disable],[forceapic] +*/ +static int __init dyntick_setup (char *options) +{ +if (!options) +return 0 ; +
kernel/dyn-tick.c line 118
Quoted 10 lines
kernel/dyn-tick.c new file +10
-0+if (strstr (options,"enable" )) + dyntick_autoenable =1 ; + +if (strstr (options,"forceapic" )) + dyntick_useapic =1 ; + +return 0 ; +} + +__setup ("dyntick=" , dyntick_setup);
Well, your parsing is little too simplistic. If I pass dyntick=do_not_dare_to_enable_it, it still enables :-).
Quoted 6 lines
kernel/dyn-tick.c new file +6
-0+/* +* --------------------------------------------------------------------------- +* Sysfs interface +* --------------------------------------------------------------------------- +*/ +
kernel/dyn-tick.c line 135
Quoted 10 lines
kernel/dyn-tick.c new file +10
-0+extern struct sys_device device_timer; + +static ssize_t show_dyn_tick_state (struct sys_device *dev,char *buf) +{ +return sprintf (buf,"suitable:\t%i\n" +"enabled:\t%i\n" +"using APIC:\t%i\n" , + dyn_tick->state &DYN_TICK_SUITABLE , + (dyn_tick->state &DYN_TICK_ENABLED ) >>1 , + (dyn_tick->state &DYN_TICK_USE_APIC ) >>3 );
You basically hardcode values of DYN_TICK_* here. Why not use !!() and loose dependency?
Pavel
Re: [PATCH] Dynamic tick for x86 version 050609-2
Quoted 3 lines · Pavel Machek
Hi!
Some more nitpicking...
Great!
Quoted 22 lines
Quoted 22 lines
kernel/dyn-tick.c new file +22
-0+/* +* --------------------------------------------------------------------------- +* Command line options +* --------------------------------------------------------------------------- +*/ +static int __initdata dyntick_autoenable =0 ; +static int __initdata dyntick_useapic =0 ; + +/* +* dyntick=[enable|disable],[forceapic] +*/ +static int __init dyntick_setup (char *options) +{ +if (!options) +return 0 ; + +if (strstr (options,"enable" )) + dyntick_autoenable =1 ; + +if (strstr (options,"forceapic" )) + dyntick_useapic =1 ; +
Quoted 8 lines
kernel/dyn-tick.c line 118
Quoted 4 lines
kernel/dyn-tick.c new file +4
-0+return 0 ; +} + +__setup ("dyntick=" , dyntick_setup);Well, your parsing is little too simplistic. If I pass dyntick=do_not_dare_to_enable_it, it still enables :-).
OK, I'll change that to test that enable is the first option.
Quoted 20 lines
Quoted 6 lines
kernel/dyn-tick.c new file +6
-0+/* +* --------------------------------------------------------------------------- +* Sysfs interface +* --------------------------------------------------------------------------- +*/ +kernel/dyn-tick.c line 135
Quoted 10 lines
kernel/dyn-tick.c new file +10
-0+extern struct sys_device device_timer; + +static ssize_t show_dyn_tick_state (struct sys_device *dev,char *buf) +{ +return sprintf (buf,"suitable:\t%i\n" +"enabled:\t%i\n" +"using APIC:\t%i\n" , + dyn_tick->state &DYN_TICK_SUITABLE , + (dyn_tick->state &DYN_TICK_ENABLED ) >>1 , + (dyn_tick->state &DYN_TICK_USE_APIC ) >>3 );You basically hardcode values of DYN_TICK_* here. Why not use !!() and loose dependency?
Quoted 1 line
Pavel
OK, thanks.
Tony
Re: [PATCH] Dynamic tick for x86 version 050609-2
In reply to Tony LindgrenQuoted 1 line · Tony Lindgren
Thanks for all the comments. Here's an updated dyntick patch.
Patches with 3 minor rejects against -rc6-mm1, boots, and seems to work well on my Dell Latitude C840 laptop - although running at full load with seti@home causes the expected 250 timer ticks/sec, running a mostly-idle X session only gets about 117, and having xmms and a few other things running it hits about 170 tics/sec. I've had the CPU speed bounce between 1.2G and 1.6G a few times and it didn't seem to blink either. Even NTP is happy with what it sees.. ;)
Need to rebuild with CONFIG_HZ=1000 and see what it does, and see what it does to actual power consumption.
Minor nit: The implementation of /sys/devices/system/timer/timer0/dyn_tick_state violates the one-value-per-file rule for sysfs. I suspect this needs to become a directory with 3-4 files in it, each containing one value.
Re: [PATCH] Dynamic tick for x86 version 050609-2
Quoted 10 lines · * [email protected] <[email protected]> [050612 21:55]:
Quoted 1 line · Tony Lindgren
Thanks for all the comments. Here's an updated dyntick patch.
Patches with 3 minor rejects against -rc6-mm1, boots, and seems to work well on my Dell Latitude C840 laptop - although running at full load with seti@home causes the expected 250 timer ticks/sec, running a mostly-idle X session only gets about 117, and having xmms and a few other things running it hits about 170 tics/sec. I've had the CPU speed bounce between 1.2G and 1.6G a few times and it didn't seem to blink either. Even NTP is happy with what it sees.. ;)
Cool.
Quoted 2 lines
Need to rebuild with
CONFIG_HZ=1000and see what it does, and see what it does to actual power consumption.
You may also want to check out the patch by Thomas Renninger for ACPI C-states. I've added a link to it at:
Quoted 3 lines
Minor nit: The implementation of
/sys/devices/system/timer/timer0/dyn_tick_stateviolates the one-value-per-file rule for sysfs. I suspect this needs to become a directory with 3-4 files in it, each containing one value.
Yeah, I'll clean up that for the next version.
Tony
Re: [PATCH] Dynamic tick for x86 version 050609-2
Quoted 4 lines · Tony Lindgren
You may also want to check out the patch by Thomas Renninger for ACPI C-states. I've added a link to it at:
I think that's muru.com/linux/dyntick ?
I'm not sure what Thomas's patch will do for me - here's what I currently have:
% cat /proc/acpi/processor/CPU0/power
active state: C2
max_cstate: C8
bus master activity: 00000000
states:
C1: type[C1] promotion[C2] demotion[--] latency[000] usage[00000010]*C2: type[C2] promotion[--] demotion[C1] latency[050] usage[01314979]
Near as I can tell, we start off in C1, drop into C2, and stay there no matter what happens - we never move back up to C1, and there's no C3 to drop into....
Should there be a C3/C4? Is my laptop just plain borked? :)
Re: [PATCH] Dynamic tick for x86 version 050609-2
Quoted 10 lines · [email protected] wrote:
Quoted 4 lines · Tony Lindgren
You may also want to check out the patch by Thomas Renninger for ACPI C-states. I've added a link to it at:
I think that's muru.com/linux/dyntick ?
I'm not sure what Thomas's patch will do for me
Not much.
The one measures how long your machine really stays in each C-state (Tony's pmstats should be sufficient for you).
The other one tried to calc the next C-state to go, based on statistics of bus master activity and idleness of the machine.
But it is *wrong*.
Tony could you please remove the link to:
ftp://ftp.suse.com/pub/people/trenn/dyn_tick_c_states/dynamic_tick_cstate_patch.diff Therefore we also will never get such good results as stated in:
ftp://ftp.suse.com/pub/people/trenn/dyn_tick_c_states/measures_C4_machine
The problem is that if there is bus master activity, a certain amount of time has to be waited (nobody could tell me how long this must be, currently
it's 40 ms. Then it's assumed bm transfers have been finished) before C3/C4 can be called -> -> bm activity is not interrupt driven -> this needs ticks to be enabled.
Therefore a final patch could look like:
Let ticks be enabled (maybe reduced?) as long as machine is still in C1/C2 and only disable them for deeper sleeping states (C3/C4).
- here's what I currently have:
Quoted 7 lines
% cat
/proc/acpi/processor/CPU0/poweractive state: C2 max_cstate: C8 bus master activity: 00000000 states: C1: type[C1] promotion[C2] demotion[--] latency[000] usage[00000010]
Quoted 7 lines
*C2: type[C2] promotion[--] demotion[C1] latency[050] usage[01314979]
Near as I can tell, we start off in C1, drop into C2, and stay there no matter what happens - we never move back up to C1, and there's no C3 to drop into....
Should there be a C3/C4? Is my laptop just plain borked? :)
Depends on your machine and BIOS, whether it's supported -> seems as if it's not.
You could verify by having a deeper look in your FADT/DSDT.
You need the acpi tools from Len Brown (acpidmp/acpixtract) and the iasl Intel ACPI compiler.
AFAIK checking for C-support is rather robust in recent kernels as long as you don't have a broken DSDT table.
Maybe you find a newer BIOS supporting C3?
To be honest, I doubt you save much power even with dyn tick enabled if you only have support for C1 and C2. The pmstats tool from Tony (see link above)
could tell you nicely whether you gain anything.
Thomas
Re: [PATCH] Dynamic tick for x86 version 050609-2
Quoted 9 lines · Thomas Renninger
Quoted 8 lines · [email protected] wrote:
Quoted 4 lines · Tony Lindgren
You may also want to check out the patch by Thomas Renninger for ACPI C-states. I've added a link to it at:
I think that's muru.com/linux/dyntick ?
Oops, that's correct.
Quoted 5 lines
Quoted 1 line
I'm not sure what Thomas's patch will do for me
Not much.
The one measures how long your machine really stays in each C-state (Tony's pmstats should be sufficient for you).
Quoted 7 lines
The other one tried to calc the next C-state to go, based on statistics of bus master activity and idleness of the machine.
But it is *wrong*.
Tony could you please remove the link to:
ftp://ftp.suse.com/pub/people/trenn/dyn_tick_c_states/dynamic_tick_cstate_patch.diff Therefore we also will never get such good results as stated in:
ftp://ftp.suse.com/pub/people/trenn/dyn_tick_c_states/measures_C4_machine
OK, removed.
Quoted 33 lines
The problem is that if there is bus master activity, a certain amount of time has to be waited (nobody could tell me how long this must be, currently
it's 40 ms. Then it's assumed bm transfers have been finished) before C3/C4 can be called -> -> bm activity is not interrupt driven -> this needs ticks to be enabled.Therefore a final patch could look like:
Let ticks be enabled (maybe reduced?) as long as machine is still in C1/C2 and only disable them for deeper sleeping states (C3/C4).- here's what I currently have:
Quoted 7 lines
% cat
/proc/acpi/processor/CPU0/poweractive state: C2 max_cstate: C8 bus master activity: 00000000 states: C1: type[C1] promotion[C2] demotion[--] latency[000] usage[00000010]Quoted 7 lines
*C2: type[C2] promotion[--] demotion[C1] latency[050] usage[01314979]
Near as I can tell, we start off in C1, drop into C2, and stay there no matter what happens - we never move back up to C1, and there's no C3 to drop into....
Should there be a C3/C4? Is my laptop just plain borked? :)
Depends on your machine and BIOS, whether it's supported -> seems as if it's not.
You could verify by having a deeper look in your FADT/DSDT.
You need the acpi tools from Len Brown (acpidmp/acpixtract) and the iasl Intel ACPI compiler.
AFAIK checking for C-support is rather robust in recent kernels as long as you don't have a broken DSDT table.
Maybe you find a newer BIOS supporting C3?
Quoted 3 lines
To be honest, I doubt you save much power even with dyn tick enabled if you only have support for C1 and C2. The pmstats tool from Tony (see link above)
could tell you nicely whether you gain anything.
Yes, the savings are hard to get currently. In the long run using C4 and idling some devices when the ticks to skip is longer should give better savings.
Tony
Re: [PATCH] Dynamic tick for x86 version 050609-2
In reply to Thomas RenningerQuoted 8 lines · Thomas Renninger
Quoted 1 line
Should there be a C3/C4? Is my laptop just plain borked? :)
Depends on your machine and BIOS, whether it's supported -> seems as if it's not.
You could verify by having a deeper look in your FADT/DSDT.
You need the acpi tools from Len Brown (acpidmp/acpixtract) and the iasl Intel ACPI compiler.
AFAIK checking for C-support is rather robust in recent kernels as long as you don't have a broken DSDT table.
OK, found acpidmp and iasl, now have a decompiled DSDT - now to figure out if it's busticated or not.... :)
Quoted 1 line
Maybe you find a newer BIOS supporting C3?
Nope, I just checked, and the A13 BIOS from 02/06/2004 is the latest that Dell has released for the C840. Not much hope there unless there's some special secret site that even newer BIOS updates hide until they escape.. ;)
Quoted 3 lines
To be honest, I doubt you save much power even with dyn tick enabled if you only have support for C1 and C2. The pmstats tool from Tony (see link above)
could tell you nicely whether you gain anything.
Well, it's a start, anyhow. :)
Re: [PATCH] Dynamic tick for x86 version 050609-2
Quoted 5 lines · [email protected] wrote:
Quoted 3 lines · Thomas Renninger
Quoted 1 line
Should there be a C3/C4? Is my laptop just plain borked? :)
Depends on your machine and BIOS, whether it's supported -> seems as if it's not.
Quoted 8 lines
Quoted 5 lines
You could verify by having a deeper look in your FADT/DSDT.
You need the acpi tools from Len Brown (acpidmp/acpixtract) and the iasl Intel ACPI compiler.
AFAIK checking for C-support is rather robust in recent kernels as long as you don't have a broken DSDT table.OK, found acpidmp and iasl, now have a decompiled DSDT - now to figure out if it's busticated or not.... :)
There are two ways C-state addresses are exported to OS.
- Some flags in the FADT (-> ACPI spec) -> this gives you two C-states maximum, AFAIK.
- Through the _CST function in your DSDT (-> ACPI spec, sorry). If you have have a look in dsdt.dsl at the _CST function there are that much packages returned as your BIOS claims to support. Hmm, _CST code is often in the SSDT an extention of the DSDT code. If you have one: acpidmp > acpidmp; acpixtract ssdt acpidmp >my_ssdt; iasl -d my_ssdt.
If your dsdt/ssdt compiles again without errors (better tell me privately if you get some), you should not have much hope, higher states are probably not supported.
You could also increase ACPI debug output when loading the processor module to get more information:
cat /proc/acpi/debug_level /proc/acpi/debug_layer
echo 0x00000FFF >/proc/acpi/debug_level (or whatever enables INFO, you need ACPI_DEBUG defined)
modprobe processor
Thomas
Quoted 12 lines
Quoted 2 lines
Maybe you find a newer BIOS supporting C3?
Nope, I just checked, and the A13 BIOS from 02/06/2004 is the latest that Dell has released for the C840. Not much hope there unless there's some special secret site that even newer BIOS updates hide until they escape.. ;)
Quoted 3 lines
To be honest, I doubt you save much power even with dyn tick enabled if you only have support for C1 and C2. The pmstats tool from Tony (see link above)
could tell you nicely whether you gain anything.Well, it's a start, anyhow. :)
Re: [PATCH] Dynamic tick for x86 version 050609-2
Quoted 3 lines · Thomas Renninger
There are two ways C-state addresses are exported to OS.
- Some flags in the FADT (-> ACPI spec) -> this gives you two C-states maximum, AFAIK.
This must be what I have, because...
Quoted 5 lines
- Through the
_CSTfunction in your DSDT (-> ACPI spec, sorry). If you have have a look in dsdt.dsl at the_CSTfunction there are that much packages returned as your BIOS claims to support. Hmm,_CSTcode is often in the SSDT an extention of the DSDT code. If you have one: acpidmp > acpidmp; acpixtract ssdt acpidmp >my_ssdt; iasl -dmy_ssdt.
I tried (using pmtools-20031210 and acpica-unix-20050513):
acpidmp > c840.dmp
acpixtract dsdt c840.dmp > c840.dsdt
acpixtract ssdt c840.dmp > c840.ssdt
iasl -d c840.dsdt
iasl -d c840.ssdt
No signs of a _CST in either the DSDT or SSDT (in fact, xtract ssdt got me a zero-length file, so I suspect there's no SSDT at all in there).
Oh well.. looks like short of BIOS/DSDT hacking, I'm stuck. At least the dynamic tick code got some testing out of all this... ;)
Re: [PATCH] Dynamic tick for x86 version 050609-2
In reply to Tony LindgrenHi Tony,
I went through the dynamic-tick patch on your website
(patch-dynamic-tick-2.6.12-rc6-050610-1) and was having some questions about it:
1. dyn_tick->skip is set to the number of ticks that have to be skipped. This is set on the CPU which is the last (in online_map) to go idle and is based on when that CPU's next timer is set to expire.
Other CPUs also seem to use the same interval
to skip ticks. Shouldnt other CPU check their nearest timer rather than blindly skipping dyn_tick->skip number of ticks?
2. reprogram_apic_timer seems to reprogram the count-down APIC timer (APIC_TMICT) with an integral number of apic_timer_val. How accurate will this be? Shouldnt this take into account that we may not be reprogramming the timer on exactly "jiffy" boundary?
3. Is there any strong reason why you reprogram timers only when _all_ CPUs are idle?
4. In what aspects you think does your patch differ from VST (other than not relying on HRT!)?
Signature · 5 lines
Thanks and Regards, Srivatsa Vaddagiri, Linux Technology Center, IBM Software Labs, Bangalore, INDIA - 560017
Re: [PATCH] Dynamic tick for x86 version 050609-2
Quoted 6 lines · Srivatsa Vaddagiri
2.
reprogram_apic_timerseems to reprogram the count-down APIC timer (APIC_TMICT) with an integral number ofapic_timer_val. How accurate will this be? Shouldnt this take into account that we may not be reprogramming the timer on exactly "jiffy" boundary?
All PIT based reprogramming schemes will lose time.
Only with HPET you can do better (but even there it is difficult to do properly)
Quoted 2 lines
3. Is there any strong reason why you reprogram timers only when _all_ CPUs are idle?
There is none imho - my x86-64 no idle tick patch doesn't do it.
Actually there is a small reason - RCU currently does not get updated by a fully idle CPU and can stall other CPUs. But that is in practice not too big an issue yet because so many subsystems cause ticks now and then, so the CPUs tend to wake up often enough to not stall the rest of the system too badly.
-Andi
Re: [PATCH] Dynamic tick for x86 version 050609-2
Quoted 9 lines · Andi Kleen
Quoted 6 lines · Srivatsa Vaddagiri
2.
reprogram_apic_timerseems to reprogram the count-down APIC timer (APIC_TMICT) with an integral number ofapic_timer_val. How accurate will this be? Shouldnt this take into account that we may not be reprogramming the timer on exactly "jiffy" boundary?All PIT based reprogramming schemes will lose time.
Not true if the timesource is different from interrupt source.
Consider PM timer for timesource, and PIT for interrupt source. Reprogamming PIT should not affect PM timer. Time is always updated from PM timer.
Quoted 6 lines
Only with HPET you can do better (but even there it is difficult to do properly)
Quoted 2 lines
3. Is there any strong reason why you reprogram timers only when _all_ CPUs are idle?
Quoted 7 lines
There is none imho - my x86-64 no idle tick patch doesn't do it.
Actually there is a small reason - RCU currently does not get updated by a fully idle CPU and can stall other CPUs. But that is in practice not too big an issue yet because so many subsystems cause ticks now and then, so the CPUs tend to wake up often enough to not stall the rest of the system too badly.
I guess it should be safe to reprogram timer even if other CPUs are not idle, assuming the busy CPUs reprogramming timer will also wake up the idle CPUs.
There's one thing that should be considered though; Reprogamming timers should be avoided if the system is busy as it causes performance issues. Especially reprogramming PIT.
Andi, where's your latest x86-64 patch BTW? I'd like to try it out on my laptop :)
Tony
Re: [PATCH] Dynamic tick for x86 version 050609-2
Quoted 9 lines · Tony Lindgren
Quoted 8 lines · Andi Kleen
Quoted 6 lines · Srivatsa Vaddagiri
2.
reprogram_apic_timerseems to reprogram the count-down APIC timer (APIC_TMICT) with an integral number ofapic_timer_val. How accurate will this be? Shouldnt this take into account that we may not be reprogramming the timer on exactly "jiffy" boundary?
Quoted 6 lines
Quoted 1 line
All PIT based reprogramming schemes will lose time.
Not true if the timesource is different from interrupt source.
Consider PM timer for timesource, and PIT for interrupt source. Reprogamming PIT should not affect PM timer. Time is always updated from PM timer.
PM timer is not really suitable for this because it overflows too quickly (several times a second).
Also you still lose time in timers (e.g. your internal timers slowly drift) unless you regularly sync with the time source, but that has other drawbacks.
Quoted 7 lines
Quoted 6 lines
Actually there is a small reason - RCU currently does not get updated by a fully idle CPU and can stall other CPUs. But that is in practice not too big an issue yet because so many subsystems cause ticks now and then, so the CPUs tend to wake up often enough to not stall the rest of the system too badly.
Quoted 7 lines
I guess it should be safe to reprogram timer even if other CPUs are not idle, assuming the busy CPUs reprogramming timer will also wake up the idle CPUs.
There's one thing that should be considered though; Reprogamming timers should be avoided if the system is busy as it causes performance issues. Especially reprogramming PIT.
Just forget about reprogramming with PIT. IMHO that should be never used in production. The right way for this is HPET.
The main issue with HPET is that many BIOS even though the chipsets have it don't set up the HPET table because Windows doesn't use it right now. However that can be avoided with some chipset specific code.
-Andi
Re: [PATCH] Dynamic tick for x86 version 050609-2
Quoted 12 lines · Andi Kleen
Quoted 11 lines · Tony Lindgren
Quoted 9 lines · Andi Kleen
Quoted 6 lines · Srivatsa Vaddagiri
2.
reprogram_apic_timerseems to reprogram the count-down APIC timer (APIC_TMICT) with an integral number ofapic_timer_val. How accurate will this be? Shouldnt this take into account that we may not be reprogramming the timer on exactly "jiffy" boundary?All PIT based reprogramming schemes will lose time.
Quoted 7 lines
Quoted 4 lines
Not true if the timesource is different from interrupt source.
Consider PM timer for timesource, and PIT for interrupt source. Reprogamming PIT should not affect PM timer. Time is always updated from PM timer.
PM timer is not really suitable for this because it overflows too quickly (several times a second).
It's longer than PIT overflow, which means it can be used.
Quoted 15 lines
Also you still lose time in timers (e.g. your internal timers slowly drift) unless you regularly sync with the time source, but that has other drawbacks.
Quoted 11 lines
Quoted 6 lines
Actually there is a small reason - RCU currently does not get updated by a fully idle CPU and can stall other CPUs. But that is in practice not too big an issue yet because so many subsystems cause ticks now and then, so the CPUs tend to wake up often enough to not stall the rest of the system too badly.
I guess it should be safe to reprogram timer even if other CPUs are not idle, assuming the busy CPUs reprogramming timer will also wake up the idle CPUs.
Quoted 7 lines
Quoted 3 lines
There's one thing that should be considered though; Reprogamming timers should be avoided if the system is busy as it causes performance issues. Especially reprogramming PIT.
Just forget about reprogramming with PIT. IMHO that should be never used in production. The right way for this is HPET.
PIT + PM timer / TSC is already working quite nicely. Of course it does not allow long sleeps, but it still helps in bringing down the HZ to about 35HZ.
Quoted 4 lines
The main issue with HPET is that many BIOS even though the chipsets have it don't set up the HPET table because Windows doesn't use it right now. However that can be avoided with some chipset specific code.
I don't have any x86 HPET hardware right now. But it sounds like it should allow multisecond skipping of ticks.
Regards,
Tony
Re: [PATCH] Dynamic tick for x86 version 050609-2
In reply to Andi KleenQuoted 4 lines · Andi Kleen
The main issue with HPET is that many BIOS even though the chipsets have it don't set up the HPET table because Windows doesn't use it right now. However that can be avoided with some chipset specific code.
If the Intel 845 chipset in my laptop has an HPET, I'm willing to test code. ;)
Re: [PATCH] Dynamic tick for x86 version 050609-2
In reply to Srivatsa VaddagiriQuoted 5 lines · Srivatsa Vaddagiri
Hi Tony,
I went through the dynamic-tick patch on your website
(patch-dynamic-tick-2.6.12-rc6-050610-1) and was having some questions about it:
Quoted 8 lines
1.
dyn_tick->skipis set to the number of ticks that have to be skipped. This is set on the CPU which is the last (inonline_map) to go idle and is based on when that CPU's next timer is set to expire.Other CPUs also seem to use the same interval
to skip ticks. Shouldnt other CPU check their nearest timer rather than blindly skippingdyn_tick->skipnumber of ticks?
Probably, unless the wake-up of the first CPU will also wake up the rest.
Quoted 6 lines
2.
reprogram_apic_timerseems to reprogram the count-down APIC timer (APIC_TMICT) with an integral number ofapic_timer_val. How accurate will this be? Shouldnt this take into account that we may not be reprogramming the timer on exactly "jiffy" boundary?
The timer reprogramming functions should be converted to use usecs. We just currently get the time in jifies from next_timer_interrupt().
Quoted 2 lines
3. Is there any strong reason why you reprogram timers only when _all_ CPUs are idle?
I don't know this for sure. It seemed like the safest way to go for now.
Quoted 2 lines
4. In what aspects you think does your patch differ from VST (other than not relying on HRT!)?
Dyntick uses next_timer_interrupt(), which is already part of the mainline kernel. It also works with PIT + PM timer or TSC.
Tony