public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] i386 No-Idle-Hz aka Dynamic-Ticks 3
@ 2005-08-03  5:59 Con Kolivas
  2005-08-03 11:54 ` Jan De Luyck
                   ` (9 more replies)
  0 siblings, 10 replies; 68+ messages in thread
From: Con Kolivas @ 2005-08-03  5:59 UTC (permalink / raw)
  To: linux-kernel; +Cc: ck, tony, tuukka.tikkanen

[-- Attachment #1: Type: text/plain, Size: 646 bytes --]

This is the dynamic ticks patch for i386 as written by Tony Lindgen 
<tony@atomide.com> and Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>. 
Patch for 2.6.13-rc5

There were a couple of things that I wanted to change so here is an updated 
version. This code should have stabilised enough for general testing now.

The sysfs interface was moved to its own directory 
in /sys/devices/system/dyn_tick and split into separate files to 
enable/disable dynamic ticks and usage of apic on the fly. It makes sense to 
enable dynamic ticks and usage of apic by default if they're actually built 
into the kernel so that is now done.

Cheers,
Con
---



[-- Attachment #2: 2.6.13-rc5-dtck-3.patch --]
[-- Type: text/x-diff, Size: 29976 bytes --]

This is the dynamic ticks patch for i386 as written by Tony Lindgen 
<tony@atomide.com> and Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>,
and modified by Con Kolivas <kernel@kolivas.org>.

Signed-off-by: Con Kolivas <kernel@kolivas.org>

 arch/i386/Kconfig                   |   36 ++++
 arch/i386/kernel/Makefile           |    1
 arch/i386/kernel/apic.c             |   19 ++
 arch/i386/kernel/dyn-tick.c         |  149 +++++++++++++++++++
 arch/i386/kernel/irq.c              |    3
 arch/i386/kernel/process.c          |    3
 arch/i386/kernel/time.c             |    7
 arch/i386/kernel/timers/timer_pit.c |   37 ++++
 arch/i386/kernel/timers/timer_pm.c  |    4
 arch/i386/kernel/timers/timer_tsc.c |   10 +
 arch/i386/mach-default/setup.c      |   16 ++
 include/asm-i386/dyn-tick.h         |   86 +++++++++++
 include/linux/dyn-tick.h            |   67 ++++++++
 kernel/Makefile                     |    1
 kernel/dyn-tick.c                   |  274 ++++++++++++++++++++++++++++++++++++
 15 files changed, 710 insertions(+), 3 deletions(-)

Index: linux-2.6.13-rc5-ck2/arch/i386/Kconfig
===================================================================
--- linux-2.6.13-rc5-ck2.orig/arch/i386/Kconfig	2005-08-03 11:29:08.000000000 +1000
+++ linux-2.6.13-rc5-ck2/arch/i386/Kconfig	2005-08-03 15:06:44.000000000 +1000
@@ -457,6 +457,42 @@ config HPET_EMULATE_RTC
 	bool "Provide RTC interrupt"
 	depends on HPET_TIMER && RTC=y
 
+config NO_IDLE_HZ
+	bool "Dynamic Tick Timer - Skip timer ticks during idle"
+	depends on EXPERIMENTAL
+	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 can disable dynamic tick timer either by
+	  passing dyntick=disable command line option, or via sysfs:
+
+	  # echo 0 > /sys/devices/system/dyn_tick/dyn_tick0/enable
+
+config DYN_TICK_USE_APIC
+	bool "Use APIC timer instead of PIT timer"
+	depends on NO_IDLE_HZ
+	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 you can disable apic usage by dynamic tick timer
+	  either by passing dyntick=noapic command line option, or via 
+	  sysfs:
+
+	  # echo 0 > /sys/devices/system/dyn_tick/dyn_tick0/useapic
+
 config SMP
 	bool "Symmetric multi-processing support"
 	---help---
Index: linux-2.6.13-rc5-ck2/arch/i386/kernel/Makefile
===================================================================
--- linux-2.6.13-rc5-ck2.orig/arch/i386/kernel/Makefile	2005-08-03 11:29:08.000000000 +1000
+++ linux-2.6.13-rc5-ck2/arch/i386/kernel/Makefile	2005-08-03 15:06:03.000000000 +1000
@@ -32,6 +32,7 @@ obj-$(CONFIG_MODULES)		+= module.o
 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
 
Index: linux-2.6.13-rc5-ck2/arch/i386/kernel/apic.c
===================================================================
--- linux-2.6.13-rc5-ck2.orig/arch/i386/kernel/apic.c	2005-08-03 11:29:08.000000000 +1000
+++ linux-2.6.13-rc5-ck2/arch/i386/kernel/apic.c	2005-08-03 11:29:29.000000000 +1000
@@ -27,6 +27,7 @@
 #include <linux/kernel_stat.h>
 #include <linux/sysdev.h>
 #include <linux/cpu.h>
+#include <linux/dyn-tick.h>
 
 #include <asm/atomic.h>
 #include <asm/smp.h>
@@ -931,6 +932,8 @@ void (*wait_timer_tick)(void) __devinitd
 
 #define APIC_DIVISOR 16
 
+u32 apic_timer_val;
+
 static void __setup_APIC_LVTT(unsigned int clocks)
 {
 	unsigned int lvtt_value, tmp_value, ver;
@@ -949,7 +952,12 @@ static void __setup_APIC_LVTT(unsigned i
 				& ~(APIC_TDR_DIV_1 | APIC_TDR_DIV_TMBASE))
 				| APIC_TDR_DIV_16);
 
-	apic_write_around(APIC_TMICT, clocks/APIC_DIVISOR);
+	apic_timer_val = clocks / APIC_DIVISOR;
+
+	if (apic_timer_val)
+		set_dyn_tick_max_skip(apic_timer_val);
+
+	apic_write_around(APIC_TMICT, apic_timer_val);
 }
 
 static void __devinit setup_APIC_timer(unsigned int clocks)
@@ -1062,6 +1070,8 @@ void __init setup_boot_APIC_clock(void)
 	 */
 	setup_APIC_timer(calibration_result);
 
+	setup_dyn_tick_use_apic(calibration_result);
+
 	local_irq_enable();
 }
 
@@ -1200,6 +1210,13 @@ fastcall void smp_apic_timer_interrupt(s
 	 * interrupt lock, which is the WrongThing (tm) to do.
 	 */
 	irq_enter();
+
+	/*
+	 * Check if we need to wake up PIT interrupt handler.
+	 * Otherwise just wake up local APIC timer.
+	 */
+	wakeup_pit_or_apic(cpu, regs);
+
 	smp_local_timer_interrupt(regs);
 	irq_exit();
 }
Index: linux-2.6.13-rc5-ck2/arch/i386/kernel/dyn-tick.c
===================================================================
--- linux-2.6.13-rc5-ck2.orig/arch/i386/kernel/dyn-tick.c	2005-08-03 14:58:52.000000000 +1000
+++ linux-2.6.13-rc5-ck2/arch/i386/kernel/dyn-tick.c	2005-08-03 15:06:38.000000000 +1000
@@ -0,0 +1,149 @@
+/*
+ * linux/arch/i386/kernel/dyn-tick.c
+ *
+ * Copyright (C) 2004 Nokia Corporation
+ * Written by Tony Lindgen <tony@atomide.com> and
+ * Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/version.h>
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/dyn-tick.h>
+#include <asm/apic.h>
+
+void arch_reprogram_timer(void)
+{
+	if (cpu_has_local_apic()) {
+		disable_pit_timer();
+		if (dyn_tick->state & DYN_TICK_TIMER_INT)
+			reprogram_apic_timer(dyn_tick->skip);
+	} else {
+		if (dyn_tick->state & DYN_TICK_TIMER_INT)
+			reprogram_pit_timer(dyn_tick->skip);
+		else
+			disable_pit_timer();
+	}
+}
+
+static struct dyn_tick_timer arch_dyn_tick_timer = {
+	.arch_reprogram_timer	= &arch_reprogram_timer,
+};
+
+int __init dyn_tick_init(void)
+{
+	arch_dyn_tick_timer.arch_init = dyn_tick_arch_init;
+	dyn_tick_register(&arch_dyn_tick_timer);
+
+	return 0;
+}
+arch_initcall(dyn_tick_init);
+
+static unsigned long long last_tick;
+
+/*
+ * This interrupt handler updates the time based on number of jiffies skipped
+ * It would be somewhat more optimized to have a custom handler in each timer
+ * using hardware ticks instead of nanoseconds. Note that CONFIG_NO_IDLE_HZ
+ * currently disables timer fallback on skipped jiffies.
+ */
+irqreturn_t dyn_tick_timer_interrupt(int irq, void *dev_id,
+					struct pt_regs *regs)
+{
+	unsigned long flags;
+	volatile unsigned long long now;
+	unsigned int skipped = 0;
+
+	write_seqlock_irqsave(&xtime_lock, flags);
+	now = cur_timer->monotonic_clock();
+	while (now - last_tick >= NS_TICK_LEN) {
+		last_tick += NS_TICK_LEN;
+		cur_timer->mark_offset();
+		do_timer_interrupt(irq, NULL, regs);
+		skipped++;
+	}
+	if (dyn_tick->state & (DYN_TICK_ENABLED | DYN_TICK_SKIPPING)) {
+		dyn_tick->skip = 1;
+		if (cpu_has_local_apic())
+			reprogram_apic_timer(dyn_tick->skip);
+		reprogram_pit_timer(dyn_tick->skip);
+		dyn_tick->state |= DYN_TICK_ENABLED;
+		dyn_tick->state &= ~DYN_TICK_SKIPPING;
+	}
+	write_sequnlock_irqrestore(&xtime_lock, flags);
+
+	return IRQ_HANDLED;
+}
+
+int __init dyn_tick_arch_init(void)
+{
+	unsigned long flags;
+
+	write_seqlock_irqsave(&xtime_lock, flags);
+	last_tick = cur_timer->monotonic_clock();
+	dyn_tick->skip = 1;
+	if (!(dyn_tick->state & DYN_TICK_USE_APIC) || !cpu_has_local_apic())
+		dyn_tick->max_skip = 0xffff / LATCH;	/* PIT timer length */
+	printk(KERN_INFO "dyn-tick: Maximum ticks to skip limited to %i\n",
+	       dyn_tick->max_skip);
+	write_sequnlock_irqrestore(&xtime_lock, flags);
+
+	dyn_tick->interrupt = dyn_tick_timer_interrupt;
+	replace_timer_interrupt(dyn_tick->interrupt);
+
+	return 0;
+}
+
+/* Functions that need blank prototypes for !CONFIG_NO_IDLE_HZ below here */
+inline void set_dyn_tick_max_skip(u32 apic_timer_val)
+{
+	dyn_tick->max_skip = 0xffffff / apic_timer_val;
+}
+
+inline void setup_dyn_tick_use_apic(unsigned int calibration_result)
+{
+	if (calibration_result)
+		dyn_tick->state |= DYN_TICK_USE_APIC;
+	else
+		printk(KERN_INFO "dyn-tick: Cannot use local APIC\n");
+}
+
+void wakeup_pit_or_apic(int cpu, struct pt_regs *regs)
+{
+	unsigned long seq; 
+
+	do {
+		seq = read_seqbegin(&xtime_lock);
+		if (dyn_tick->state & (DYN_TICK_ENABLED | DYN_TICK_SKIPPING)) {
+			if (dyn_tick->skip_cpu == cpu &&
+				dyn_tick->skip > DYN_TICK_MIN_SKIP)
+					dyn_tick->interrupt(99, NULL, regs);
+				else
+					reprogram_apic_timer(1);
+		}
+	} while (read_seqretry(&xtime_lock, seq));
+}
+
+void dyn_tick_interrupt(int irq, struct pt_regs *regs)
+{
+	if (dyn_tick->state & (DYN_TICK_ENABLED | DYN_TICK_SKIPPING) && irq)
+		dyn_tick->interrupt(irq, NULL, regs);
+}
+
+void dyn_tick_time_init(struct timer_opts *cur_timer)
+{
+	if (strncmp(cur_timer->name, "tsc", 3) == 0 ||
+	    strncmp(cur_timer->name, "pmtmr", 3) == 0) {
+		dyn_tick->state |= DYN_TICK_SUITABLE;
+		printk(KERN_INFO "dyn-tick: Found suitable timer: %s\n",
+		       cur_timer->name);
+	} else
+		printk(KERN_ERR "dyn-tick: Cannot use timer %s\n",
+		       cur_timer->name);
+}
Index: linux-2.6.13-rc5-ck2/arch/i386/kernel/irq.c
===================================================================
--- linux-2.6.13-rc5-ck2.orig/arch/i386/kernel/irq.c	2005-08-03 11:29:08.000000000 +1000
+++ linux-2.6.13-rc5-ck2/arch/i386/kernel/irq.c	2005-08-03 11:29:29.000000000 +1000
@@ -18,6 +18,7 @@
 #include <linux/notifier.h>
 #include <linux/cpu.h>
 #include <linux/delay.h>
+#include <linux/dyn-tick.h>
 
 DEFINE_PER_CPU(irq_cpustat_t, irq_stat) ____cacheline_maxaligned_in_smp;
 EXPORT_PER_CPU_SYMBOL(irq_stat);
@@ -76,6 +77,8 @@ fastcall unsigned int do_IRQ(struct pt_r
 	}
 #endif
 
+	dyn_tick_interrupt(irq, regs);
+
 #ifdef CONFIG_4KSTACKS
 
 	curctx = (union irq_ctx *) current_thread_info();
Index: linux-2.6.13-rc5-ck2/arch/i386/kernel/process.c
===================================================================
--- linux-2.6.13-rc5-ck2.orig/arch/i386/kernel/process.c	2005-08-03 11:29:08.000000000 +1000
+++ linux-2.6.13-rc5-ck2/arch/i386/kernel/process.c	2005-08-03 11:29:29.000000000 +1000
@@ -39,6 +39,7 @@
 #include <linux/ptrace.h>
 #include <linux/random.h>
 #include <linux/kprobes.h>
+#include <linux/dyn-tick.h>
 
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
@@ -200,6 +201,8 @@ void cpu_idle(void)
 			if (cpu_is_offline(cpu))
 				play_dead();
 
+			dyn_tick_reprogram_timer();
+
 			__get_cpu_var(irq_stat).idle_timestamp = jiffies;
 			idle();
 		}
Index: linux-2.6.13-rc5-ck2/arch/i386/kernel/time.c
===================================================================
--- linux-2.6.13-rc5-ck2.orig/arch/i386/kernel/time.c	2005-08-03 11:29:08.000000000 +1000
+++ linux-2.6.13-rc5-ck2/arch/i386/kernel/time.c	2005-08-03 11:29:29.000000000 +1000
@@ -46,6 +46,7 @@
 #include <linux/bcd.h>
 #include <linux/efi.h>
 #include <linux/mca.h>
+#include <linux/dyn-tick.h>
 
 #include <asm/io.h>
 #include <asm/smp.h>
@@ -252,7 +253,7 @@ EXPORT_SYMBOL(profile_pc);
  * timer_interrupt() needs to keep up the real-time clock,
  * as well as call the "do_timer()" routine every clocktick
  */
-static inline void do_timer_interrupt(int irq, void *dev_id,
+inline void do_timer_interrupt(int irq, void *dev_id,
 					struct pt_regs *regs)
 {
 #ifdef CONFIG_X86_IO_APIC
@@ -423,7 +424,7 @@ static struct sysdev_class timer_sysclas
 
 
 /* XXX this driverfs stuff should probably go elsewhere later -john */
-static struct sys_device device_timer = {
+struct sys_device device_timer = {
 	.id	= 0,
 	.cls	= &timer_sysclass,
 };
@@ -479,5 +480,7 @@ void __init time_init(void)
 	cur_timer = select_timer();
 	printk(KERN_INFO "Using %s for high-res timesource\n",cur_timer->name);
 
+	dyn_tick_time_init(cur_timer);
+
 	time_init_hook();
 }
Index: linux-2.6.13-rc5-ck2/arch/i386/kernel/timers/timer_pit.c
===================================================================
--- linux-2.6.13-rc5-ck2.orig/arch/i386/kernel/timers/timer_pit.c	2005-08-03 11:29:08.000000000 +1000
+++ linux-2.6.13-rc5-ck2/arch/i386/kernel/timers/timer_pit.c	2005-08-03 11:29:29.000000000 +1000
@@ -148,6 +148,43 @@ static unsigned long get_offset_pit(void
 	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 = {
Index: linux-2.6.13-rc5-ck2/arch/i386/kernel/timers/timer_pm.c
===================================================================
--- linux-2.6.13-rc5-ck2.orig/arch/i386/kernel/timers/timer_pm.c	2005-08-03 11:29:08.000000000 +1000
+++ linux-2.6.13-rc5-ck2/arch/i386/kernel/timers/timer_pm.c	2005-08-03 11:29:29.000000000 +1000
@@ -15,6 +15,7 @@
 #include <linux/module.h>
 #include <linux/device.h>
 #include <linux/init.h>
+#include <linux/dyn-tick.h>
 #include <asm/types.h>
 #include <asm/timer.h>
 #include <asm/smp.h>
@@ -168,6 +169,9 @@ static void mark_offset_pmtmr(void)
 	monotonic_base += delta * NSEC_PER_USEC;
 	write_sequnlock(&monotonic_lock);
 
+	if (dyn_tick_enabled())
+		return;
+
 	/* convert to ticks */
 	delta += offset_delay;
 	lost = delta / (USEC_PER_SEC / HZ);
Index: linux-2.6.13-rc5-ck2/arch/i386/kernel/timers/timer_tsc.c
===================================================================
--- linux-2.6.13-rc5-ck2.orig/arch/i386/kernel/timers/timer_tsc.c	2005-08-03 11:29:08.000000000 +1000
+++ linux-2.6.13-rc5-ck2/arch/i386/kernel/timers/timer_tsc.c	2005-08-03 11:29:29.000000000 +1000
@@ -14,6 +14,7 @@
 #include <linux/cpufreq.h>
 #include <linux/string.h>
 #include <linux/jiffies.h>
+#include <linux/dyn-tick.h>
 
 #include <asm/timer.h>
 #include <asm/io.h>
@@ -367,6 +368,9 @@ static void mark_offset_tsc(void)
 
 	rdtsc(last_tsc_low, last_tsc_high);
 
+	if (dyn_tick_enabled())
+		goto monotonic_base;
+
 	spin_lock(&i8253_lock);
 	outb_p(0x00, PIT_MODE);     /* latch the count ASAP */
 
@@ -434,11 +438,17 @@ static void mark_offset_tsc(void)
 			cpufreq_delayed_get();
 	} else
 		lost_count = 0;
+
+ monotonic_base:
+
 	/* 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);
 
+	if (dyn_tick_enabled())
+		return;
+
 	/* calculate delay_at_last_interrupt */
 	count = ((LATCH-1) - count) * TICK_SIZE;
 	delay_at_last_interrupt = (count + LATCH/2) / LATCH;
Index: linux-2.6.13-rc5-ck2/arch/i386/mach-default/setup.c
===================================================================
--- linux-2.6.13-rc5-ck2.orig/arch/i386/mach-default/setup.c	2005-08-03 11:29:08.000000000 +1000
+++ linux-2.6.13-rc5-ck2/arch/i386/mach-default/setup.c	2005-08-03 11:29:29.000000000 +1000
@@ -93,6 +93,22 @@ void __init time_init_hook(void)
 	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
Index: linux-2.6.13-rc5-ck2/include/asm-i386/dyn-tick.h
===================================================================
--- linux-2.6.13-rc5-ck2.orig/include/asm-i386/dyn-tick.h	2005-08-03 14:58:52.000000000 +1000
+++ linux-2.6.13-rc5-ck2/include/asm-i386/dyn-tick.h	2005-08-03 14:45:41.000000000 +1000
@@ -0,0 +1,86 @@
+/*
+ * linux/include/asm-i386/dyn-tick.h
+ *
+ * Copyright (C) 2004 Nokia Corporation
+ * Written by Tony Lindgen <tony@atomide.com> and
+ * Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef _ASM_I386_DYN_TICK_H_
+#define _ASM_I386_DYN_TICK_H_
+
+#include <asm/apic.h>
+
+#ifdef CONFIG_NO_IDLE_HZ
+extern int dyn_tick_arch_init(void);
+extern void disable_pit_timer(void);
+extern void reprogram_pit_timer(int jiffies_to_skip);
+extern void replace_timer_interrupt(void * new_handler);
+extern void set_dyn_tick_max_skip(u32 apic_timer_val);
+extern void setup_dyn_tick_use_apic(unsigned int calibration_result);
+extern void wakeup_pit_or_apic(int cpu, struct pt_regs *regs);
+extern void dyn_tick_interrupt(int irq, struct pt_regs *regs);
+extern void dyn_tick_time_init(struct timer_opts *cur_timer);
+extern void do_timer_interrupt(int irq, void *dev_id,
+					struct pt_regs *regs);
+extern irqreturn_t dyn_tick_timer_interrupt(int irq, void *dev_id,
+					struct pt_regs *regs);
+extern int __init dyn_tick_arch_init(void);
+
+extern u32 apic_timer_val;
+
+#if defined(CONFIG_DYN_TICK_USE_APIC) && \
+	(defined(CONFIG_SMP) || defined(CONFIG_X86_UP_APIC))
+#define cpu_has_local_apic()	(dyn_tick->state & DYN_TICK_USE_APIC)
+#else
+#define cpu_has_local_apic()	0
+#endif
+
+#if defined(CONFIG_DYN_TICK_USE_APIC)
+#define dyntick_apicable()	1
+#else
+#define dyntick_apicable()	0
+#endif
+
+static inline void reprogram_apic_timer(unsigned int count)
+{
+#ifdef CONFIG_X86_LOCAL_APIC
+	unsigned long flags;
+
+	count *= apic_timer_val;
+	local_irq_save(flags);
+	apic_write_around(APIC_TMICT, count);
+	local_irq_restore(flags);
+#endif	/* CONFIG_X86_LOCAL_APIC */
+}
+
+#else /* CONFIG_NO_IDLE_HZ */
+static inline void set_dyn_tick_max_skip(u32 apic_timer_val)
+{
+}
+
+static inline void reprogram_apic_timer(unsigned int count)
+{
+}
+
+static inline void setup_dyn_tick_use_apic(unsigned int calibration_result)
+{
+}
+
+static inline void wakeup_pit_or_apic(int cpu, struct pt_regs *regs)
+{
+}
+
+static inline void dyn_tick_interrupt(int irq, struct pt_regs *regs)
+{
+}
+
+static inline void dyn_tick_time_init(struct timer_opts *cur_timer)
+{
+}
+#endif /* CONFIG_NO_IDLE_HZ */
+#endif /* _ASM_I386_DYN_TICK_H_ */
Index: linux-2.6.13-rc5-ck2/include/linux/dyn-tick.h
===================================================================
--- linux-2.6.13-rc5-ck2.orig/include/linux/dyn-tick.h	2005-08-03 14:58:52.000000000 +1000
+++ linux-2.6.13-rc5-ck2/include/linux/dyn-tick.h	2005-08-03 15:06:44.000000000 +1000
@@ -0,0 +1,67 @@
+/*
+ * linux/include/linux/dyn-tick.h
+ *
+ * Copyright (C) 2004 Nokia Corporation
+ * Written by Tony Lindgen <tony@atomide.com> and
+ * Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef _DYN_TICK_TIMER_H
+#define _DYN_TICK_TIMER_H
+
+#include <linux/interrupt.h>
+#include <asm/timer.h>
+
+#define DYN_TICK_APICABLE	(1 << 5)
+#define DYN_TICK_TIMER_INT	(1 << 4)
+#define DYN_TICK_USE_APIC	(1 << 3)
+#define DYN_TICK_SKIPPING	(1 << 2)
+#define DYN_TICK_ENABLED	(1 << 1)
+#define DYN_TICK_SUITABLE	(1 << 0)
+
+struct dyn_tick_state {
+	unsigned int state;		/* Current state */
+	int skip_cpu;			/* Skip handling processor */
+	unsigned long skip;		/* Ticks to skip */
+	unsigned int max_skip;		/* Max number of ticks to skip */
+	unsigned long irq_skip_mask;	/* Do not update time from these irqs */
+	irqreturn_t (*interrupt)(int, void *, struct pt_regs *);
+};
+
+struct dyn_tick_timer {
+	int (*arch_init) (void);
+	void (*arch_enable) (void);
+	void (*arch_disable) (void);
+	void (*arch_reprogram_timer) (void);
+};
+
+extern struct dyn_tick_state *dyn_tick;
+extern void dyn_tick_register(struct dyn_tick_timer *new_timer);
+
+#define NS_TICK_LEN		((1 * 1000000000)/HZ)
+#define DYN_TICK_MIN_SKIP	2
+
+
+#ifdef CONFIG_NO_IDLE_HZ
+
+extern unsigned long dyn_tick_reprogram_timer(void);
+
+#define dyn_tick_enabled()		(dyn_tick->state & DYN_TICK_ENABLED)
+
+#else
+
+#define arch_has_safe_halt()		0
+#define dyn_tick_reprogram_timer()	do {} while (0)
+#define dyn_tick_enabled()		0
+
+#endif	/* CONFIG_NO_IDLE_HZ */
+
+
+/* Pick up arch specific header */
+#include <asm/dyn-tick.h>
+
+#endif	/* _DYN_TICK_TIMER_H */
Index: linux-2.6.13-rc5-ck2/kernel/Makefile
===================================================================
--- linux-2.6.13-rc5-ck2.orig/kernel/Makefile	2005-08-03 11:29:08.000000000 +1000
+++ linux-2.6.13-rc5-ck2/kernel/Makefile	2005-08-03 11:29:29.000000000 +1000
@@ -30,6 +30,7 @@ obj-$(CONFIG_SYSFS) += ksysfs.o
 obj-$(CONFIG_GENERIC_HARDIRQS) += irq/
 obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
 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 <alan@linuxcare.com.au>, the -fno-omit-frame-pointer is
Index: linux-2.6.13-rc5-ck2/kernel/dyn-tick.c
===================================================================
--- linux-2.6.13-rc5-ck2.orig/kernel/dyn-tick.c	2005-08-03 14:58:52.000000000 +1000
+++ linux-2.6.13-rc5-ck2/kernel/dyn-tick.c	2005-08-03 15:06:44.000000000 +1000
@@ -0,0 +1,274 @@
+/*
+ * linux/kernel/dyn-tick.c
+ *
+ * Beginnings of generic dynamic tick timer support
+ *
+ * Copyright (C) 2004 Nokia Corporation
+ * Written by Tony Lindgen <tony@atomide.com> and
+ * Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/version.h>
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/sysdev.h>
+#include <linux/interrupt.h>
+#include <linux/cpumask.h>
+#include <linux/pm.h>
+#include <linux/dyn-tick.h>
+#include <asm/io.h>
+
+#include "io_ports.h"
+
+#define DYN_TICK_VERSION	"050610-1"
+
+struct dyn_tick_state dyn_tick_state;
+struct dyn_tick_state *dyn_tick = &dyn_tick_state;
+struct dyn_tick_timer *dyn_tick_cfg;
+static cpumask_t dyn_cpu_map;
+
+/*
+ * Arch independent code needed to reprogram next timer interrupt.
+ * Gets called from cpu_idle() before entering idle loop. Note that
+ * we want to have all processors idle before reprogramming the
+ * next timer interrupt.
+ */
+unsigned long dyn_tick_reprogram_timer(void)
+{
+	int cpu;
+	unsigned long flags;
+	cpumask_t idle_cpus;
+	unsigned long next;
+
+	if (!(dyn_tick->state & DYN_TICK_ENABLED))
+		return 0;
+
+	/* Check if we are already skipping ticks and can idle other cpus */
+	if (dyn_tick->state & DYN_TICK_SKIPPING) {
+		if (cpu_has_local_apic())
+			reprogram_apic_timer(dyn_tick->skip);
+		return 0;
+	}
+
+	/* Check if we can start skipping ticks */
+	write_seqlock_irqsave(&xtime_lock, flags);
+	cpu = smp_processor_id();
+	cpu_set(cpu, dyn_cpu_map);
+	cpus_and(idle_cpus, dyn_cpu_map, cpu_online_map);
+	if (cpus_equal(idle_cpus, cpu_online_map)) {
+		next = next_timer_interrupt();
+		if (jiffies > next)
+			dyn_tick->skip = 1;
+		else
+			dyn_tick->skip = next_timer_interrupt() - jiffies;
+		if (dyn_tick->skip > DYN_TICK_MIN_SKIP) {
+			if (dyn_tick->skip > dyn_tick->max_skip)
+				dyn_tick->skip = dyn_tick->max_skip;
+
+			dyn_tick_cfg->arch_reprogram_timer();
+
+			dyn_tick->skip_cpu = cpu;
+			dyn_tick->state |= DYN_TICK_SKIPPING;
+		}
+		cpus_clear(dyn_cpu_map);
+	}
+	write_sequnlock_irqrestore(&xtime_lock, flags);
+
+	return dyn_tick->skip;
+}
+
+void __init dyn_tick_register(struct dyn_tick_timer *arch_timer)
+{
+	dyn_tick_cfg = arch_timer;
+	printk(KERN_INFO "dyn-tick: Registering dynamic tick timer v%s\n",
+	       DYN_TICK_VERSION);
+}
+
+/*
+ * ---------------------------------------------------------------------------
+ * Command line options
+ * ---------------------------------------------------------------------------
+ */
+static int __initdata dyntick_autoenable = 1;
+static int __initdata dyntick_useapic = 1;
+
+/*
+ * dyntick=[disable],[noapic]
+ */ 
+static int __init dyntick_setup(char *options)
+{
+	if (!options)
+		return 0;
+
+	if (!strncmp(options, "disable", 6)) 
+		dyntick_autoenable = 0;
+
+	if (strstr(options, "noapic"))
+		dyntick_useapic = 0;
+
+	return 0;
+}
+
+__setup("dyntick=", dyntick_setup);
+
+/*
+ * ---------------------------------------------------------------------------
+ * Sysfs interface
+ * ---------------------------------------------------------------------------
+ */
+
+extern struct sys_device device_timer;
+
+#define DYN_TICK_IS_SET(x)	((dyn_tick->state & (x)) == (x))
+
+static ssize_t show_dyn_tick_state(struct sys_device *dev, char *buf)
+{
+	return sprintf(buf,
+		       "suitable:\t%i\n"
+		       "enabled:\t%i\n"
+		       "apic suitable:\t%i\n"
+		       "using APIC:\t%i\n",
+		       DYN_TICK_IS_SET(DYN_TICK_SUITABLE),
+		       DYN_TICK_IS_SET(DYN_TICK_ENABLED),
+		       DYN_TICK_IS_SET(DYN_TICK_APICABLE),
+		       DYN_TICK_IS_SET(DYN_TICK_USE_APIC));
+}
+
+static ssize_t show_dyn_tick_enable(struct sys_device *dev, char *buf)
+{
+	return sprintf(buf, "enabled:\t%i\n",
+		DYN_TICK_IS_SET(DYN_TICK_ENABLED));
+}
+
+static ssize_t set_dyn_tick_enable(struct sys_device *dev, const char *buf,
+				size_t count)
+{
+	unsigned long flags;
+	unsigned int enable = simple_strtoul(buf, NULL, 2);
+
+	write_seqlock_irqsave(&xtime_lock, flags);
+	if (enable) {
+		if (dyn_tick_cfg->arch_enable)
+			dyn_tick_cfg->arch_enable();
+		dyn_tick->state |= DYN_TICK_ENABLED;
+	} else {
+		if (dyn_tick_cfg->arch_disable)
+			dyn_tick_cfg->arch_disable();
+		dyn_tick->state &= ~DYN_TICK_ENABLED;
+	}
+	write_sequnlock_irqrestore(&xtime_lock, flags);
+
+	return count;
+}
+
+static ssize_t show_dyn_tick_useapic(struct sys_device *dev, char *buf)
+{
+	return sprintf(buf, "using APIC:\t%i\n",
+		DYN_TICK_IS_SET(DYN_TICK_USE_APIC));
+}
+
+static ssize_t set_dyn_tick_useapic(struct sys_device *dev, const char *buf,
+				size_t count)
+{
+	unsigned long flags;
+	unsigned int enable = simple_strtoul(buf, NULL, 2);
+
+	if (!DYN_TICK_IS_SET(DYN_TICK_APICABLE))
+		goto out;
+	write_seqlock_irqsave(&xtime_lock, flags);
+	if (enable)
+		dyn_tick->state |= DYN_TICK_USE_APIC;
+	else
+		dyn_tick->state &= ~DYN_TICK_USE_APIC;
+	write_sequnlock_irqrestore(&xtime_lock, flags);
+out:
+	return count;
+}
+
+static SYSDEV_ATTR(state, 0444, show_dyn_tick_state, NULL);
+static SYSDEV_ATTR(enable, 0644, show_dyn_tick_enable,
+		   set_dyn_tick_enable);
+static SYSDEV_ATTR(useapic, 0644, show_dyn_tick_useapic,
+		   set_dyn_tick_useapic);
+
+static struct sysdev_class dyn_tick_sysclass = {
+	set_kset_name("dyn_tick"),
+};
+
+static struct sys_device device_dyn_tick = {
+	.id = 0,
+	.cls = &dyn_tick_sysclass,
+};
+
+static int init_dyn_tick_sysfs(void)
+{
+	int error = 0;
+	if ((error = sysdev_class_register(&dyn_tick_sysclass)))
+		goto out;
+	if ((error = sysdev_register(&device_dyn_tick)))
+		goto out;
+	if ((error = sysdev_create_file(&device_dyn_tick, &attr_state)))
+		goto out;
+	if ((error = sysdev_create_file(&device_dyn_tick, &attr_enable)))
+		goto out;
+	error = sysdev_create_file(&device_dyn_tick, &attr_useapic);
+
+out:
+	return error;
+}
+
+device_initcall(init_dyn_tick_sysfs);
+
+/*
+ * ---------------------------------------------------------------------------
+ * Init functions
+ * ---------------------------------------------------------------------------
+ */
+
+static int __init dyn_tick_early_init(void)
+{
+	dyn_tick->state |= DYN_TICK_TIMER_INT;
+	return 0;
+}
+
+subsys_initcall(dyn_tick_early_init);
+
+/*
+ * We need to initialize dynamic tick after calibrate delay
+ */
+static int __init dyn_tick_late_init(void)
+{
+	int ret = 0;
+
+	if (dyn_tick_cfg == NULL || dyn_tick_cfg->arch_init == NULL ||
+	    !DYN_TICK_IS_SET(DYN_TICK_SUITABLE)) {
+		printk(KERN_ERR "dyn-tick: No suitable timer found\n");
+		return -ENODEV;
+	}
+
+	if (dyntick_apicable())
+		dyn_tick->state |= DYN_TICK_APICABLE;
+	if (!dyntick_useapic || !DYN_TICK_IS_SET(DYN_TICK_APICABLE))
+		dyn_tick->state &= ~DYN_TICK_USE_APIC;
+
+	if ((ret = dyn_tick_cfg->arch_init())) {
+		printk(KERN_ERR "dyn-tick: Init failed\n");
+		return -ENODEV;
+	}
+
+	if (!ret && dyntick_autoenable) {
+		dyn_tick->state |= DYN_TICK_ENABLED;
+		printk(KERN_INFO "dyn-tick: Timer using dynamic tick\n");
+	} else
+		printk(KERN_INFO "dyn-tick: Timer not enabled during boot\n");
+
+	return ret;
+}
+
+late_initcall(dyn_tick_late_init);

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

* Re: [PATCH] i386 No-Idle-Hz aka Dynamic-Ticks 3
  2005-08-03  5:59 [PATCH] i386 No-Idle-Hz aka Dynamic-Ticks 3 Con Kolivas
@ 2005-08-03 11:54 ` Jan De Luyck
  2005-08-03 12:14   ` Con Kolivas
  2005-08-03 19:20 ` Jim MacBaine
                   ` (8 subsequent siblings)
  9 siblings, 1 reply; 68+ messages in thread
From: Jan De Luyck @ 2005-08-03 11:54 UTC (permalink / raw)
  To: linux-kernel; +Cc: Con Kolivas, ck, tony, tuukka.tikkanen

On Wednesday 03 August 2005 07:59, Con Kolivas wrote:
> This is the dynamic ticks patch for i386 as written by Tony Lindgen
> <tony@atomide.com> and Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>.
> Patch for 2.6.13-rc5
>

Compiles and runs ok here.

Is there actually any timer frequency that's advisable to set as maximum? (in 
the kernel config)

Jan
-- 
To stand and be still,
At the Birkenhead drill,
Is a damned tough bullet to chew.
		-- Rudyard Kipling

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

* Re: [PATCH] i386 No-Idle-Hz aka Dynamic-Ticks 3
  2005-08-03 11:54 ` Jan De Luyck
@ 2005-08-03 12:14   ` Con Kolivas
  2005-08-03 14:23     ` Jan De Luyck
  0 siblings, 1 reply; 68+ messages in thread
From: Con Kolivas @ 2005-08-03 12:14 UTC (permalink / raw)
  To: linux-kernel; +Cc: Jan De Luyck, ck, tony, tuukka.tikkanen

On Wed, 3 Aug 2005 21:54, Jan De Luyck wrote:
> On Wednesday 03 August 2005 07:59, Con Kolivas wrote:
> > This is the dynamic ticks patch for i386 as written by Tony Lindgen
> > <tony@atomide.com> and Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>.
> > Patch for 2.6.13-rc5
>
> Compiles and runs ok here.
>
> Is there actually any timer frequency that's advisable to set as maximum?
> (in the kernel config)

I'd recommend 1000.

Cheers,
Con

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

* Re: [PATCH] i386 No-Idle-Hz aka Dynamic-Ticks 3
  2005-08-03 12:14   ` Con Kolivas
@ 2005-08-03 14:23     ` Jan De Luyck
  2005-08-04 15:03       ` Vojtech Pavlik
  0 siblings, 1 reply; 68+ messages in thread
From: Jan De Luyck @ 2005-08-03 14:23 UTC (permalink / raw)
  To: linux-kernel; +Cc: Con Kolivas, ck, tony, tuukka.tikkanen

On Wednesday 03 August 2005 14:14, Con Kolivas wrote:
> On Wed, 3 Aug 2005 21:54, Jan De Luyck wrote:
> > On Wednesday 03 August 2005 07:59, Con Kolivas wrote:
> > > This is the dynamic ticks patch for i386 as written by Tony Lindgen
> > > <tony@atomide.com> and Tuukka Tikkanen
> > > <tuukka.tikkanen@elektrobit.com>. Patch for 2.6.13-rc5
> >
> > Compiles and runs ok here.
> >
> > Is there actually any timer frequency that's advisable to set as maximum?
> > (in the kernel config)
>
> I'd recommend 1000.

Thanks. Currently the system - under X, KDE, no artsd, bottoms at around 
300HZ. In total single mode with every module unloaded that I can unload it 
stops around 22HZ.

I guess I'll have to go hunting whatever thing is causing the pollings. no 
timertop yet, I guess? :P

Jan

-- 
If you give Congress a chance to vote on both sides of an issue, it
will always do it.
		-- Les Aspin, D., Wisconsin

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

* Re: [PATCH] i386 No-Idle-Hz aka Dynamic-Ticks 3
  2005-08-03  5:59 [PATCH] i386 No-Idle-Hz aka Dynamic-Ticks 3 Con Kolivas
  2005-08-03 11:54 ` Jan De Luyck
@ 2005-08-03 19:20 ` Jim MacBaine
  2005-08-03 21:16   ` Con Kolivas
  2005-08-03 19:54 ` Jeffrey Hundstad
                   ` (7 subsequent siblings)
  9 siblings, 1 reply; 68+ messages in thread
From: Jim MacBaine @ 2005-08-03 19:20 UTC (permalink / raw)
  To: Con Kolivas; +Cc: linux-kernel, ck, tony, tuukka.tikkanen

On 8/3/05, Con Kolivas <kernel@kolivas.org> wrote:

> This is the dynamic ticks patch for i386 as written by Tony Lindgen
> <tony@atomide.com> and Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>.
> Patch for 2.6.13-rc5
> 
> There were a couple of things that I wanted to change so here is an updated
> version. This code should have stabilised enough for general testing now.

Runs very well here on a (noname) laptop, even with apic timer, the
desktop does not "feel" different from static 1000HZ.  But dtck
reproducibly breaks software-suspend2; the kernel will simply stall on
resume.  Also stalls with dyntick=noapic.  As soon as I set
CONFIG_NO_IDLE_HZ = n, resume works again.

My kernel is 2.6.13-rc5 + swsusp-2.1.9.11 + dtck-3, the system is a
Mitac 8375 laptop, via chipset, mobile athlon xp, gcc-3.4.4

Regards,
Jim

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

* Re: [PATCH] i386 No-Idle-Hz aka Dynamic-Ticks 3
  2005-08-03  5:59 [PATCH] i386 No-Idle-Hz aka Dynamic-Ticks 3 Con Kolivas
  2005-08-03 11:54 ` Jan De Luyck
  2005-08-03 19:20 ` Jim MacBaine
@ 2005-08-03 19:54 ` Jeffrey Hundstad
  2005-08-03 20:07   ` Valdis.Kletnieks
  2005-08-03 21:13   ` Con Kolivas
  2005-08-03 23:22 ` Christian Leber
                   ` (6 subsequent siblings)
  9 siblings, 2 replies; 68+ messages in thread
From: Jeffrey Hundstad @ 2005-08-03 19:54 UTC (permalink / raw)
  To: Con Kolivas; +Cc: linux-kernel, ck, tony, tuukka.tikkanen

Con Kolivas wrote:

>This is the dynamic ticks patch for i386 as written by Tony Lindgen 
><tony@atomide.com> and Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>. 
>Patch for 2.6.13-rc5
>
>There were a couple of things that I wanted to change so here is an updated 
>version. This code should have stabilised enough for general testing now.
>
>The sysfs interface was moved to its own directory 
>in /sys/devices/system/dyn_tick and split into separate files to 
>enable/disable dynamic ticks and usage of apic on the fly. It makes sense to 
>enable dynamic ticks and usage of apic by default if they're actually built 
>into the kernel so that is now done.
>  
>

I am successfully running the dynamic tick patch on an old IBM ThinkPad 
A22m.  When I enable the APIC support console beeps, you know bash -c 
'echo -e "\a"', takes a REALLY long time to finish.  I'm assuming this 
is a badly written program and not a kernel problem.  Correct?

BTW: how do you know what HZ your machine is running at?

-- 
Jeffrey Hundstad


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

* Re: [PATCH] i386 No-Idle-Hz aka Dynamic-Ticks 3
  2005-08-03 19:54 ` Jeffrey Hundstad
@ 2005-08-03 20:07   ` Valdis.Kletnieks
  2005-08-03 21:13   ` Con Kolivas
  1 sibling, 0 replies; 68+ messages in thread
From: Valdis.Kletnieks @ 2005-08-03 20:07 UTC (permalink / raw)
  To: Jeffrey Hundstad; +Cc: Con Kolivas, linux-kernel, ck, tony, tuukka.tikkanen

[-- Attachment #1: Type: text/plain, Size: 365 bytes --]

On Wed, 03 Aug 2005 14:54:40 CDT, Jeffrey Hundstad said:

> BTW: how do you know what HZ your machine is running at?

% zcat /proc/config.gz | grep -i hz

might do what you thought you wanted.

What rate you're *actually* running at is probably best done by taking the
number of timer interrupts from /proc/interrupts and dividing by the
uptime in /proc/uptime....

[-- Attachment #2: Type: application/pgp-signature, Size: 226 bytes --]

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

* Re: [PATCH] i386 No-Idle-Hz aka Dynamic-Ticks 3
  2005-08-03 19:54 ` Jeffrey Hundstad
  2005-08-03 20:07   ` Valdis.Kletnieks
@ 2005-08-03 21:13   ` Con Kolivas
  1 sibling, 0 replies; 68+ messages in thread
From: Con Kolivas @ 2005-08-03 21:13 UTC (permalink / raw)
  To: Jeffrey Hundstad; +Cc: linux-kernel, ck, tony, tuukka.tikkanen

[-- Attachment #1: Type: text/plain, Size: 1624 bytes --]

On Thu, 4 Aug 2005 05:54, Jeffrey Hundstad wrote:
> Con Kolivas wrote:
> >This is the dynamic ticks patch for i386 as written by Tony Lindgen
> ><tony@atomide.com> and Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>.
> >Patch for 2.6.13-rc5
> >
> >There were a couple of things that I wanted to change so here is an
> > updated version. This code should have stabilised enough for general
> > testing now.
> >
> >The sysfs interface was moved to its own directory
> >in /sys/devices/system/dyn_tick and split into separate files to
> >enable/disable dynamic ticks and usage of apic on the fly. It makes sense
> > to enable dynamic ticks and usage of apic by default if they're actually
> > built into the kernel so that is now done.
>
> I am successfully running the dynamic tick patch on an old IBM ThinkPad
> A22m.  When I enable the APIC support console beeps, you know bash -c
> 'echo -e "\a"', takes a REALLY long time to finish.  I'm assuming this
> is a badly written program and not a kernel problem.  Correct?

I think the config option which recommends leaving apic support off and 
describes this behaviour should make it clearer. Indeed I found running with 
apic on produced weird results unlike running with PIT.

> BTW: how do you know what HZ your machine is running at?

vmstat 5 will show you the average interrupts per second over 5 seconds in the 
"in" column. The interrupts are obviously more than your Hz but often only a 
little more. 

The pmstats script by Tony will tell you more accurately:
http://www.muru.com/linux/dyntick/tools/pmstats-0.2.gz

Cheers,
Con

[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]

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

* Re: [PATCH] i386 No-Idle-Hz aka Dynamic-Ticks 3
  2005-08-03 19:20 ` Jim MacBaine
@ 2005-08-03 21:16   ` Con Kolivas
  2005-08-03 22:22     ` Jim MacBaine
  0 siblings, 1 reply; 68+ messages in thread
From: Con Kolivas @ 2005-08-03 21:16 UTC (permalink / raw)
  To: Jim MacBaine; +Cc: linux-kernel, ck, tony, tuukka.tikkanen

[-- Attachment #1: Type: text/plain, Size: 1185 bytes --]

On Thu, 4 Aug 2005 05:20, Jim MacBaine wrote:
> On 8/3/05, Con Kolivas <kernel@kolivas.org> wrote:
> > This is the dynamic ticks patch for i386 as written by Tony Lindgen
> > <tony@atomide.com> and Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>.
> > Patch for 2.6.13-rc5
> >
> > There were a couple of things that I wanted to change so here is an
> > updated version. This code should have stabilised enough for general
> > testing now.
>
> Runs very well here on a (noname) laptop, even with apic timer, the
> desktop does not "feel" different from static 1000HZ. 

I did find performance dropped off substantially in interbench but usually 
below the human perceptible range. Real time performance dropped off 
substantially, but is back to mainline performance when disabled (ie config 
on but disabled at runtime/boottime).

> But dtck 
> reproducibly breaks software-suspend2; the kernel will simply stall on
> resume.  Also stalls with dyntick=noapic.  As soon as I set
> CONFIG_NO_IDLE_HZ = n, resume works again.

What happens when you disable it at runtime before suspending?

echo 0 > /sys/devices/system/dyn_tick/dyn_tick0/enable

Cheers,
Con

[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]

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

* Re: [PATCH] i386 No-Idle-Hz aka Dynamic-Ticks 3
  2005-08-03 21:16   ` Con Kolivas
@ 2005-08-03 22:22     ` Jim MacBaine
  2005-08-03 22:52       ` Con Kolivas
  0 siblings, 1 reply; 68+ messages in thread
From: Jim MacBaine @ 2005-08-03 22:22 UTC (permalink / raw)
  To: Con Kolivas; +Cc: linux-kernel, ck, tony, tuukka.tikkanen

On 8/3/05, Con Kolivas <kernel@kolivas.org> wrote:

> What happens when you disable it at runtime before suspending?
> 
> echo 0 > /sys/devices/system/dyn_tick/dyn_tick0/enable

This has no effect. The system stalls at exactly the same point. The
last lines on my screen are:

...
Software Suspend Core.
Software Suspend Compression Driver loading.
Software Suspend Encryption Driver loading.
Software Suspend Swap Writer loading.
Software Suspend FileWriter loading.
dyn-tick: Maximum ticks to skip limited to 13
dyn-tick: Timer using dynamic tick
ACPI wakeup devices:
SBTN USB0 USB1 EHCI AC97 MC97 LAN0 FSD0
ACPI: (supports S0 S3 S4 S5)
Software Suspend 2.1.9.11: Swapwriter: Signature found.
Software Suspend 2.1.9.11: Suspending enabled.

Regards,
Jim

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

* Re: [PATCH] i386 No-Idle-Hz aka Dynamic-Ticks 3
  2005-08-03 22:22     ` Jim MacBaine
@ 2005-08-03 22:52       ` Con Kolivas
  2005-08-04  5:34         ` Jim MacBaine
  2005-08-14 19:47         ` Pavel Machek
  0 siblings, 2 replies; 68+ messages in thread
From: Con Kolivas @ 2005-08-03 22:52 UTC (permalink / raw)
  To: Jim MacBaine; +Cc: linux-kernel, ck, tony, tuukka.tikkanen

On Thu, 4 Aug 2005 08:22 am, Jim MacBaine wrote:
> On 8/3/05, Con Kolivas <kernel@kolivas.org> wrote:
> > What happens when you disable it at runtime before suspending?
> >
> > echo 0 > /sys/devices/system/dyn_tick/dyn_tick0/enable
>
> This has no effect. The system stalls at exactly the same point. The
> last lines on my screen are:

Ok perhaps on the resume side instead. When trying to resume can you try 
booting with 'dyntick=disable'. Note this isn't meant to be a long term fix 
but once we figure out where the problem is we should be able to code around 
it.

Cheers,
Con

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

* Re: [PATCH] i386 No-Idle-Hz aka Dynamic-Ticks 3
  2005-08-03  5:59 [PATCH] i386 No-Idle-Hz aka Dynamic-Ticks 3 Con Kolivas
                   ` (2 preceding siblings ...)
  2005-08-03 19:54 ` Jeffrey Hundstad
@ 2005-08-03 23:22 ` Christian Leber
  2005-08-04 16:25   ` Marc Ballarin
  2005-08-04  5:09 ` Jan De Luyck
                   ` (5 subsequent siblings)
  9 siblings, 1 reply; 68+ messages in thread
From: Christian Leber @ 2005-08-03 23:22 UTC (permalink / raw)
  To: linux-kernel

On Wed, Aug 03, 2005 at 03:59:24PM +1000, Con Kolivas wrote:
> Patch for 2.6.13-rc5

Just a few numbers:

I tried it on a Laptop (Dell C810, P3m 1133 mhz) and measured the power
usage with an external device and it stayed with or without patch at
27W. (HZ was at about 28)

On a desktop with AthlonXP with STOP activated i got a power usage of
57W with and without patch (without STOP activated 94W).
(HZ was about at 50)


Christian Leber

-- 
  "Omnis enim res, quae dando non deficit, dum habetur et non datur,
   nondum habetur, quomodo habenda est."       (Aurelius Augustinus)
  Translation: <http://gnuhh.org/work/fsf-europe/augustinus.html>

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

* Re: [PATCH] i386 No-Idle-Hz aka Dynamic-Ticks 3
  2005-08-04  5:09 ` Jan De Luyck
@ 2005-08-04  5:07   ` Con Kolivas
  2005-08-04  5:34     ` Jan De Luyck
  0 siblings, 1 reply; 68+ messages in thread
From: Con Kolivas @ 2005-08-04  5:07 UTC (permalink / raw)
  To: Jan De Luyck; +Cc: linux-kernel, ck, tony, tuukka.tikkanen

On Thu, 4 Aug 2005 03:09 pm, Jan De Luyck wrote:
> On Wednesday 03 August 2005 07:59, Con Kolivas wrote:
> > This is the dynamic ticks patch for i386 as written by Tony Lindgen
> > <tony@atomide.com> and Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>.
> > Patch for 2.6.13-rc5
>
> On a weird sidenote: my synaptics touchpad seems to not-like dyntick very
> much. When starting with a dyntick enabled kernel I get when psmouse.ko is
> loaded:
>
> Aug  4 06:45:47 precious kernel: Synaptics claims to have extended
> capabilities, but I'm not able to read them.<3>Unable to initialize
> Synaptics hardware. Aug  4 06:45:47 precious kernel: input: PS/2 Synaptics
> TouchPad on isa0060/serio1
>
> subsequently, X fails to start too (touchpad is set as corepointer)
>
> reloading the module right then and there solves the problem:
>
> Aug  4 06:47:47 precious kernel: Synaptics Touchpad, model: 1, fw: 5.8, id:
> 0x9d48b1, caps: 0x904713/0x4006 Aug  4 06:47:47 precious kernel: input:
> SynPS/2 Synaptics TouchPad on isa0060/serio1
>
> Also, booting the same (but non-patched) kernel gives me a clean boot:
>
> Aug  4 06:56:42 precious kernel: Synaptics Touchpad, model: 1, fw: 5.8, id:
> 0x9d48b1, caps: 0x904713/0x4006 Aug  4 06:56:42 precious kernel: input:
> SynPS/2 Synaptics TouchPad on isa0060/serio1
>
> This is constantly reproducable for me. I guess some timing issue
> somewhere?

Did you try without the apic option or disable it at runtime? The apic option 
is proving more problems than not so far for people that have tried it.

Cheers,
Con

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

* Re: [PATCH] i386 No-Idle-Hz aka Dynamic-Ticks 3
  2005-08-03  5:59 [PATCH] i386 No-Idle-Hz aka Dynamic-Ticks 3 Con Kolivas
                   ` (3 preceding siblings ...)
  2005-08-03 23:22 ` Christian Leber
@ 2005-08-04  5:09 ` Jan De Luyck
  2005-08-04  5:07   ` Con Kolivas
  2005-08-04 21:15 ` [PATCH] Timer Top was: " Daniel Petrini
                   ` (4 subsequent siblings)
  9 siblings, 1 reply; 68+ messages in thread
From: Jan De Luyck @ 2005-08-04  5:09 UTC (permalink / raw)
  To: linux-kernel; +Cc: Con Kolivas, ck, tony, tuukka.tikkanen

On Wednesday 03 August 2005 07:59, Con Kolivas wrote:
> This is the dynamic ticks patch for i386 as written by Tony Lindgen
> <tony@atomide.com> and Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>.
> Patch for 2.6.13-rc5

On a weird sidenote: my synaptics touchpad seems to not-like dyntick very much. 
When starting with a dyntick enabled kernel I get when psmouse.ko is loaded:

Aug  4 06:45:47 precious kernel: Synaptics claims to have extended capabilities, but I'm not able to read them.<3>Unable to initialize Synaptics hardware.
Aug  4 06:45:47 precious kernel: input: PS/2 Synaptics TouchPad on isa0060/serio1

subsequently, X fails to start too (touchpad is set as corepointer)

reloading the module right then and there solves the problem:

Aug  4 06:47:47 precious kernel: Synaptics Touchpad, model: 1, fw: 5.8, id: 0x9d48b1, caps: 0x904713/0x4006
Aug  4 06:47:47 precious kernel: input: SynPS/2 Synaptics TouchPad on isa0060/serio1

Also, booting the same (but non-patched) kernel gives me a clean boot:

Aug  4 06:56:42 precious kernel: Synaptics Touchpad, model: 1, fw: 5.8, id: 0x9d48b1, caps: 0x904713/0x4006
Aug  4 06:56:42 precious kernel: input: SynPS/2 Synaptics TouchPad on isa0060/serio1

This is constantly reproducable for me. I guess some timing issue somewhere?

Jan

-- 
A good name lost is seldom regained.  When character is gone,
all is gone, and one of the richest jewels of life is lost forever.
		-- J. Hawes

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

* Re: [PATCH] i386 No-Idle-Hz aka Dynamic-Ticks 3
  2005-08-04  5:07   ` Con Kolivas
@ 2005-08-04  5:34     ` Jan De Luyck
  0 siblings, 0 replies; 68+ messages in thread
From: Jan De Luyck @ 2005-08-04  5:34 UTC (permalink / raw)
  To: Con Kolivas; +Cc: linux-kernel, ck, tony, tuukka.tikkanen

On Thursday 04 August 2005 07:07, Con Kolivas wrote:
> On Thu, 4 Aug 2005 03:09 pm, Jan De Luyck wrote:
> > On Wednesday 03 August 2005 07:59, Con Kolivas wrote:
> > > This is the dynamic ticks patch for i386 as written by Tony Lindgen
> > > <tony@atomide.com> and Tuukka Tikkanen
> > > <tuukka.tikkanen@elektrobit.com>. Patch for 2.6.13-rc5
> >
> > On a weird sidenote: my synaptics touchpad seems to not-like dyntick very
> > much. When starting with a dyntick enabled kernel I get when psmouse.ko
> > is loaded:
> >
> > Aug  4 06:45:47 precious kernel: Synaptics claims to have extended
> > capabilities, but I'm not able to read them.<3>Unable to initialize
> > Synaptics hardware. Aug  4 06:45:47 precious kernel: input: PS/2
> > Synaptics TouchPad on isa0060/serio1
> >
> > subsequently, X fails to start too (touchpad is set as corepointer)
> >
> > reloading the module right then and there solves the problem:
> >
> > Aug  4 06:47:47 precious kernel: Synaptics Touchpad, model: 1, fw: 5.8,
> > id: 0x9d48b1, caps: 0x904713/0x4006 Aug  4 06:47:47 precious kernel:
> > input: SynPS/2 Synaptics TouchPad on isa0060/serio1
> >
> > Also, booting the same (but non-patched) kernel gives me a clean boot:
> >
> > Aug  4 06:56:42 precious kernel: Synaptics Touchpad, model: 1, fw: 5.8,
> > id: 0x9d48b1, caps: 0x904713/0x4006 Aug  4 06:56:42 precious kernel:
> > input: SynPS/2 Synaptics TouchPad on isa0060/serio1
> >
> > This is constantly reproducable for me. I guess some timing issue
> > somewhere?
>
> Did you try without the apic option or disable it at runtime? The apic
> option is proving more problems than not so far for people that have tried
> it.

The above was with apic enabled. With apic disabled, same story tho different 
boot-time message:

$ cat /sys/../state
suitable:       1
enabled:        1
apic suitable:  1
using APIC:     0

dmesg gives:
Unable to query Synaptics hardware.
input: PS/2 Synaptics TouchPad on isa0060/serio1

and X refuses to start. Same resolution, just reload psmouse.

Jan
-- 
The default Magic Word, "Abracadabra", actually is a corruption of the
Hebrew phrase "ha-Bracha dab'ra" which means "pronounce the blessing".

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

* Re: [PATCH] i386 No-Idle-Hz aka Dynamic-Ticks 3
  2005-08-03 22:52       ` Con Kolivas
@ 2005-08-04  5:34         ` Jim MacBaine
  2005-08-04  6:59           ` Jim MacBaine
  2005-08-14 19:47         ` Pavel Machek
  1 sibling, 1 reply; 68+ messages in thread
From: Jim MacBaine @ 2005-08-04  5:34 UTC (permalink / raw)
  To: Con Kolivas; +Cc: linux-kernel, ck, tony, tuukka.tikkanen

On 8/4/05, Con Kolivas <kernel@kolivas.org> wrote:

> Ok perhaps on the resume side instead. When trying to resume can you try
> booting with 'dyntick=disable'. Note this isn't meant to be a long term fix
> but once we figure out where the problem is we should be able to code around
> it.

Sorry, no luck. 

I tried dyntick=disable and dyntick=noapic on resume time.  I also
tried suspend and resume after the system has been started with
dyntick=noapic: Same result.

As soon as I tell swsusp2 to discard its image, the system will come
up flawlessly.

Regards,
Jim

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

* Re: [PATCH] i386 No-Idle-Hz aka Dynamic-Ticks 3
  2005-08-04  5:34         ` Jim MacBaine
@ 2005-08-04  6:59           ` Jim MacBaine
  2005-08-04  7:04             ` Con Kolivas
  2005-08-10 20:04             ` Bill Davidsen
  0 siblings, 2 replies; 68+ messages in thread
From: Jim MacBaine @ 2005-08-04  6:59 UTC (permalink / raw)
  To: Con Kolivas; +Cc: linux-kernel, ck, tony, tuukka.tikkanen

I just borrowed a power meter to see (or not to see) real effects of
dyntick. The difference between static 1000 HZ and dynamic HZ is much
less than I expected, only a very little about noise.  With dyntick
disabled at 1000 HZ my laptop needs 31,3 W.  With dyntick enabled I
get 29.8 W, the pmstats-0.2 script shows me that the system is at
35-45 HZ when it is idle.

The power consumption difference between 250 HZ static and dyntick is
below the noise, so maybe hardly worth all the struggle.

Regards,
Jim

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

* Re: [PATCH] i386 No-Idle-Hz aka Dynamic-Ticks 3
  2005-08-04  6:59           ` Jim MacBaine
@ 2005-08-04  7:04             ` Con Kolivas
  2005-08-04  7:12               ` Con Kolivas
  2005-08-10 20:04             ` Bill Davidsen
  1 sibling, 1 reply; 68+ messages in thread
From: Con Kolivas @ 2005-08-04  7:04 UTC (permalink / raw)
  To: Jim MacBaine; +Cc: linux-kernel, ck, tony, tuukka.tikkanen

On Thu, 4 Aug 2005 04:59 pm, Jim MacBaine wrote:
> I just borrowed a power meter to see (or not to see) real effects of
> dyntick. The difference between static 1000 HZ and dynamic HZ is much
> less than I expected, only a very little about noise.  With dyntick
> disabled at 1000 HZ my laptop needs 31,3 W.  With dyntick enabled I
> get 29.8 W, the pmstats-0.2 script shows me that the system is at
> 35-45 HZ when it is idle.
>
> The power consumption difference between 250 HZ static and dyntick is
> below the noise, so maybe hardly worth all the struggle.

That's not the point. We want the power savings without sacrificing the extra 
ticks if we need them.

Cheers,
Con

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

* Re: [PATCH] i386 No-Idle-Hz aka Dynamic-Ticks 3
  2005-08-04  7:04             ` Con Kolivas
@ 2005-08-04  7:12               ` Con Kolivas
  2005-08-04  7:29                 ` Tony Lindgren
  0 siblings, 1 reply; 68+ messages in thread
From: Con Kolivas @ 2005-08-04  7:12 UTC (permalink / raw)
  To: Jim MacBaine; +Cc: linux-kernel, ck, tony, tuukka.tikkanen

On Thu, 4 Aug 2005 05:04 pm, Con Kolivas wrote:
> On Thu, 4 Aug 2005 04:59 pm, Jim MacBaine wrote:
> > I just borrowed a power meter to see (or not to see) real effects of
> > dyntick. The difference between static 1000 HZ and dynamic HZ is much
> > less than I expected, only a very little about noise.  With dyntick
> > disabled at 1000 HZ my laptop needs 31,3 W.  With dyntick enabled I
> > get 29.8 W, the pmstats-0.2 script shows me that the system is at
> > 35-45 HZ when it is idle.
> >
> > The power consumption difference between 250 HZ static and dyntick is
> > below the noise, so maybe hardly worth all the struggle.
>
> That's not the point. We want the power savings without sacrificing the
> extra ticks if we need them.

Oh but thank you very much for confirming the power savings are around the 5% 
mark. If we don't measure we won't know (and everything else is mental 
masturbation according to Linus ;)).

Cheers,
Con

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

* Re: [PATCH] i386 No-Idle-Hz aka Dynamic-Ticks 3
  2005-08-04  7:12               ` Con Kolivas
@ 2005-08-04  7:29                 ` Tony Lindgren
  0 siblings, 0 replies; 68+ messages in thread
From: Tony Lindgren @ 2005-08-04  7:29 UTC (permalink / raw)
  To: Con Kolivas; +Cc: Jim MacBaine, linux-kernel, ck, tuukka.tikkanen

* Con Kolivas <kernel@kolivas.org> [050804 00:16]:
> On Thu, 4 Aug 2005 05:04 pm, Con Kolivas wrote:
> > On Thu, 4 Aug 2005 04:59 pm, Jim MacBaine wrote:
> > > I just borrowed a power meter to see (or not to see) real effects of
> > > dyntick. The difference between static 1000 HZ and dynamic HZ is much
> > > less than I expected, only a very little about noise.  With dyntick
> > > disabled at 1000 HZ my laptop needs 31,3 W.  With dyntick enabled I
> > > get 29.8 W, the pmstats-0.2 script shows me that the system is at
> > > 35-45 HZ when it is idle.
> > >
> > > The power consumption difference between 250 HZ static and dyntick is
> > > below the noise, so maybe hardly worth all the struggle.
> >
> > That's not the point. We want the power savings without sacrificing the
> > extra ticks if we need them.
> 
> Oh but thank you very much for confirming the power savings are around the 5% 
> mark. If we don't measure we won't know (and everything else is mental 
> masturbation according to Linus ;)).

Dyntick on it's own does not do much. But it allows adding better PM code
later on.

Tony

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

* Re: [PATCH] i386 No-Idle-Hz aka Dynamic-Ticks 3
  2005-08-03 14:23     ` Jan De Luyck
@ 2005-08-04 15:03       ` Vojtech Pavlik
  2005-08-05  5:12         ` Con Kolivas
  0 siblings, 1 reply; 68+ messages in thread
From: Vojtech Pavlik @ 2005-08-04 15:03 UTC (permalink / raw)
  To: Jan De Luyck; +Cc: linux-kernel, Con Kolivas, ck, tony, tuukka.tikkanen

On Wed, Aug 03, 2005 at 04:23:59PM +0200, Jan De Luyck wrote:
> On Wednesday 03 August 2005 14:14, Con Kolivas wrote:
> > On Wed, 3 Aug 2005 21:54, Jan De Luyck wrote:
> > > On Wednesday 03 August 2005 07:59, Con Kolivas wrote:
> > > > This is the dynamic ticks patch for i386 as written by Tony Lindgen
> > > > <tony@atomide.com> and Tuukka Tikkanen
> > > > <tuukka.tikkanen@elektrobit.com>. Patch for 2.6.13-rc5
> > >
> > > Compiles and runs ok here.
> > >
> > > Is there actually any timer frequency that's advisable to set as maximum?
> > > (in the kernel config)
> >
> > I'd recommend 1000.
> 
> Thanks. Currently the system - under X, KDE, no artsd, bottoms at around 
> 300HZ. In total single mode with every module unloaded that I can unload it 
> stops around 22HZ.
> 
> I guess I'll have to go hunting whatever thing is causing the pollings. no 
> timertop yet, I guess? :P

i8042 runs a steady periodic 20Hz timer. You can make it slower to get
even the total low lower, and it will not affect performance under
normal (sane hardware) circumstances. 

-- 
Vojtech Pavlik
SuSE Labs, SuSE CR

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

* Re: [PATCH] i386 No-Idle-Hz aka Dynamic-Ticks 3
  2005-08-03 23:22 ` Christian Leber
@ 2005-08-04 16:25   ` Marc Ballarin
  0 siblings, 0 replies; 68+ messages in thread
From: Marc Ballarin @ 2005-08-04 16:25 UTC (permalink / raw)
  To: Christian Leber; +Cc: linux-kernel

On Thu, 4 Aug 2005 01:22:36 +0200
Christian Leber <christian@leber.de> wrote:

> Just a few numbers:
> 
> I tried it on a Laptop (Dell C810, P3m 1133 mhz) and measured the power
> usage with an external device and it stayed with or without patch at
> 27W. (HZ was at about 28)

Does your machine enter C3 state? Check the usage
in /proc/acpi/processor/CPU0/power

If usage is 0, unplug all USB peripherals (at least those connected to
uhci controllers). Also shut down sound servers.

Without C3, there won't be any power savings from lower HZ. Desktop CPUs
often don't support C3 at all.

Marc

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

* [PATCH] Timer Top was: i386 No-Idle-Hz aka Dynamic-Ticks 3
  2005-08-03  5:59 [PATCH] i386 No-Idle-Hz aka Dynamic-Ticks 3 Con Kolivas
                   ` (4 preceding siblings ...)
  2005-08-04  5:09 ` Jan De Luyck
@ 2005-08-04 21:15 ` Daniel Petrini
  2005-08-05  4:05   ` [PATCH] Timer Top tweaks Con Kolivas
  2005-08-05  6:46   ` [ck] [PATCH] Timer Top was: i386 No-Idle-Hz aka Dynamic-Ticks 3 Jens Axboe
  2005-08-04 21:44 ` [PATCH] " Adrian Bunk
                   ` (3 subsequent siblings)
  9 siblings, 2 replies; 68+ messages in thread
From: Daniel Petrini @ 2005-08-04 21:15 UTC (permalink / raw)
  To: Con Kolivas, tony; +Cc: linux-kernel, ck, tuukka.tikkanen, ilias.biris

[-- Attachment #1: Type: text/plain, Size: 666 bytes --]

Hi,

Here we have some support to have more tests on Dynamic Tick.
We have some functions that exports timers information to a proc entry
(/proc/top_info), in a kernel patch and a script that handles this
info and give some output to analyse. We tried to make it less
intrusive as possible.

It is based in suggestions from Tony Lindgren.

It is experimental and should evolve.

Must be applied after 2.6.13-rc5-dtck-3.patch and 2.6.13-rc5.

Usage: with kernel compiled with attached patch: "perl timer_top.pl
5", to have refresh time of 5s.

Regards,

Daniel Petrini
-- 
10LE - Linux Lab
Instituto Nokia de Tecnologia - INdT
Manaus - Brazil

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: timer_top1-20050804.patch --]
[-- Type: text/x-patch; name="timer_top1-20050804.patch", Size: 3961 bytes --]

diff -uprN linux-2.6.12-orig/kernel/Makefile linux-dyn-tick/kernel/Makefile
--- linux-2.6.12-orig/kernel/Makefile	2005-08-03 23:50:26.000000000 -0400
+++ linux-dyn-tick/kernel/Makefile	2005-08-04 16:56:14.000000000 -0400
@@ -7,7 +7,7 @@ obj-y     = sched.o fork.o exec_domain.o
 	    sysctl.o capability.o ptrace.o timer.o user.o \
 	    signal.o sys.o kmod.o workqueue.o pid.o \
 	    rcupdate.o intermodule.o extable.o params.o posix-timers.o \
-	    kthread.o wait.o kfifo.o sys_ni.o posix-cpu-timers.o
+	    kthread.o wait.o kfifo.o sys_ni.o posix-cpu-timers.o timer_top.o
 
 obj-$(CONFIG_FUTEX) += futex.o
 obj-$(CONFIG_GENERIC_ISA_DMA) += dma.o
diff -uprN linux-2.6.12-orig/kernel/timer.c linux-dyn-tick/kernel/timer.c
--- linux-2.6.12-orig/kernel/timer.c	2005-08-03 23:50:27.000000000 -0400
+++ linux-dyn-tick/kernel/timer.c	2005-08-04 16:56:27.000000000 -0400
@@ -508,6 +508,8 @@ static inline void __run_timers(tvec_bas
 }
 
 #ifdef CONFIG_NO_IDLE_HZ
+extern struct timer_top_info top_info;
+extern int account_timer(unsigned int function, struct timer_top_info * top_info);
 /*
  * Find out when the next timer event is due to happen. This
  * is used on S/390 to stop all activity when a cpus is idle.
@@ -571,6 +573,7 @@ found:
 				expires = nte->expires;
 		}
 	}
+	account_timer((unsigned int)nte->function, &top_info);
 	spin_unlock(&base->t_base.lock);
 	return expires;
 }
diff -uprN linux-2.6.12-orig/kernel/timer_top.c linux-dyn-tick/kernel/timer_top.c
--- linux-2.6.12-orig/kernel/timer_top.c	1969-12-31 20:00:00.000000000 -0400
+++ linux-dyn-tick/kernel/timer_top.c	2005-08-04 16:51:36.000000000 -0400
@@ -0,0 +1,101 @@
+/*
+ * kernel/timer_top.c
+ *
+ * Export Timers information to /proc/top_info
+ *
+ * Copyright (C) 2005 Instituto Nokia de Tecnologia - INdT - Manaus
+ * Written by Daniel Petrini <d.pensator@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+
+#include <linux/list.h>
+#include <linux/proc_fs.h>
+#include <linux/module.h>
+
+static LIST_HEAD(timer_list);
+
+struct timer_top_info {
+	unsigned int		func_pointer;
+	unsigned int long	counter;
+	struct list_head 	list;      	
+};
+
+struct timer_top_info top_info;
+
+int account_timer(unsigned int function, struct timer_top_info * top_info)
+{
+	struct timer_top_info *top;
+
+	list_for_each_entry (top, &timer_list, list) {
+		/* if it is in the list increment its count */
+		if (top->func_pointer == function) {
+			top->counter += 1;
+			return 0;
+		}
+	}
+	
+	/* if you are here then it didnt find so inserts in the list */
+
+	top = kmalloc(sizeof(struct timer_top_info), GFP_KERNEL);
+	if (!top) 
+		return -ENOMEM;
+	top->func_pointer = function;
+	top->counter = 1;
+	list_add(&top->list, &timer_list);
+
+	return 0;
+}
+
+EXPORT_SYMBOL(account_timer);
+
+struct top_info_poll {
+  char value[18];
+};
+
+struct top_info_poll top_info_poll_dt;
+struct proc_dir_entry *top_info_file;
+
+static int proc_read_top_info(char *page, char **start, off_t off,
+                                int count, int *eof, void *data)
+{
+	char aux[18];
+	struct timer_top_info *top;
+
+	struct top_info_poll *info_poll_data=(struct top_info_poll *)data;
+
+	sprintf(page, "Function counter - %s\n", info_poll_data->value);
+
+	list_for_each_entry (top, &timer_list, list) {
+		sprintf(aux, "%x %lu\n", top->func_pointer, top->counter);
+		strcat(page, aux);
+	}
+
+	return strlen(page);
+ 
+} 
+
+static int init_top_info(void)
+{
+	top_info_file = create_proc_entry("top_info", 0666, NULL);
+	if(top_info_file == NULL) {
+	  return -ENOMEM;
+	}
+
+	strcpy(top_info_poll_dt.value, "Timer Top v0.9.1");
+
+	top_info_file->data = &top_info_poll_dt;
+	top_info_file->read_proc = &proc_read_top_info;
+	top_info_file->owner = THIS_MODULE;
+	
+	return 0;
+}
+
+module_init(init_top_info);
+//module_exit();
+
+
+

[-- Attachment #3: timer_top.pl --]
[-- Type: application/x-perl, Size: 2271 bytes --]

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

* Re: [PATCH] i386 No-Idle-Hz aka Dynamic-Ticks 3
  2005-08-03  5:59 [PATCH] i386 No-Idle-Hz aka Dynamic-Ticks 3 Con Kolivas
                   ` (5 preceding siblings ...)
  2005-08-04 21:15 ` [PATCH] Timer Top was: " Daniel Petrini
@ 2005-08-04 21:44 ` Adrian Bunk
  2005-08-04 22:12 ` Marc Ballarin
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 68+ messages in thread
From: Adrian Bunk @ 2005-08-04 21:44 UTC (permalink / raw)
  To: Con Kolivas; +Cc: linux-kernel, ck, tony, tuukka.tikkanen

On Wed, Aug 03, 2005 at 03:59:24PM +1000, Con Kolivas wrote:
>...
> --- linux-2.6.13-rc5-ck2.orig/arch/i386/kernel/time.c	2005-08-03 11:29:08.000000000 +1000
> +++ linux-2.6.13-rc5-ck2/arch/i386/kernel/time.c	2005-08-03 11:29:29.000000000 +1000
>...
> -static inline void do_timer_interrupt(int irq, void *dev_id,
> +inline void do_timer_interrupt(int irq, void *dev_id,
>  					struct pt_regs *regs)
>...

A global inline functions implies an increase of the size of the binary.
Can you drop the "inline"?

cu
Adrian

-- 

       "Is there not promise of rain?" Ling Tan asked suddenly out
        of the darkness. There had been need of rain for many days.
       "Only a promise," Lao Er said.
                                       Pearl S. Buck - Dragon Seed


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

* Re: [PATCH] i386 No-Idle-Hz aka Dynamic-Ticks 3
  2005-08-03  5:59 [PATCH] i386 No-Idle-Hz aka Dynamic-Ticks 3 Con Kolivas
                   ` (6 preceding siblings ...)
  2005-08-04 21:44 ` [PATCH] " Adrian Bunk
@ 2005-08-04 22:12 ` Marc Ballarin
  2005-08-05  0:31   ` Con Kolivas
  2005-08-05  1:30 ` Paul
  2005-08-05 12:37 ` Srivatsa Vaddagiri
  9 siblings, 1 reply; 68+ messages in thread
From: Marc Ballarin @ 2005-08-04 22:12 UTC (permalink / raw)
  To: Con Kolivas; +Cc: linux-kernel, ck, tony, tuukka.tikkanen

On Wed, 3 Aug 2005 15:59:24 +1000
Con Kolivas <kernel@kolivas.org> wrote:

> This is the dynamic ticks patch for i386 as written by Tony Lindgen 
> <tony@atomide.com> and Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>. 
> Patch for 2.6.13-rc5

One issue (tested the -rc4 Version on -mm):
- on interrupt flood (ping -f) HZ goes down to 0-4 HZ.
  This matches "ticks to skip" below. Coincidence?

- ping -f complains:
.Warning: time of day goes back (-304us), taking countermeasures.
...
.Warning: time of day goes back (-33us), taking countermeasures.

Yet, system time _seems_ to be kept correctly.

CPU is Pentium M.

dmesg:
Using pmtmr for high-res timesource
dyn-tick: Found suitable timer: pmtmr

dyn-tick: Maximum ticks to skip limited to 54
dyn-tick: Timer not enabled during boot

sysfs:
suitable:       1
enabled:        1
using APIC:     0

Regards

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

* Re: [PATCH] i386 No-Idle-Hz aka Dynamic-Ticks 3
  2005-08-04 22:12 ` Marc Ballarin
@ 2005-08-05  0:31   ` Con Kolivas
  0 siblings, 0 replies; 68+ messages in thread
From: Con Kolivas @ 2005-08-05  0:31 UTC (permalink / raw)
  To: Marc Ballarin; +Cc: linux-kernel, ck, tony, tuukka.tikkanen

On Fri, 5 Aug 2005 08:12 am, Marc Ballarin wrote:
> On Wed, 3 Aug 2005 15:59:24 +1000
>
> Con Kolivas <kernel@kolivas.org> wrote:
> > This is the dynamic ticks patch for i386 as written by Tony Lindgen
> > <tony@atomide.com> and Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>.
> > Patch for 2.6.13-rc5
>
> One issue (tested the -rc4 Version on -mm):
> - on interrupt flood (ping -f) HZ goes down to 0-4 HZ.
>   This matches "ticks to skip" below. Coincidence?
>
> - ping -f complains:
> .Warning: time of day goes back (-304us), taking countermeasures.
> ...
> .Warning: time of day goes back (-33us), taking countermeasures.
>
> Yet, system time _seems_ to be kept correctly.

Interesting... It almost seems like if you throw enough interrupts at it the 
next_timer_interrupt function gets confused. I wonder if S390 and ARM are 
seeing this at all since (it seems to me) they use that function?

Con

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

* Re: [PATCH] i386 No-Idle-Hz aka Dynamic-Ticks 3
  2005-08-03  5:59 [PATCH] i386 No-Idle-Hz aka Dynamic-Ticks 3 Con Kolivas
                   ` (7 preceding siblings ...)
  2005-08-04 22:12 ` Marc Ballarin
@ 2005-08-05  1:30 ` Paul
  2005-08-05  3:25   ` Con Kolivas
  2005-08-05 12:37 ` Srivatsa Vaddagiri
  9 siblings, 1 reply; 68+ messages in thread
From: Paul @ 2005-08-05  1:30 UTC (permalink / raw)
  To: linux-kernel; +Cc: kernel

Con Kolivas <kernel@kolivas.org>, on Wed Aug 03, 2005 [03:59:24 PM] said:
> This is the dynamic ticks patch for i386 as written by Tony Lindgen 
> <tony@atomide.com> and Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>. 
> Patch for 2.6.13-rc5
> 
> There were a couple of things that I wanted to change so here is an updated 
> version. This code should have stabilised enough for general testing now.
> 
> The sysfs interface was moved to its own directory 
> in /sys/devices/system/dyn_tick and split into separate files to 
> enable/disable dynamic ticks and usage of apic on the fly. It makes sense to 
> enable dynamic ticks and usage of apic by default if they're actually built 
> into the kernel so that is now done.
> 
> Cheers,
> Con

	Hi;

	Ive been running this all afternoon on a pIIx2 @400mhz desktop
machine, SMP enabled Preempt kernel.
	Initially, I tried it using APIC, got X up and tried to play
some music, but mplayer just hung and prompts in other terminals
were super slugish or blocked until I killed mplayer. (there were
no interrupts from the sound card during this time.) Without using
APIC, it seems to work just great.
	With my regular desktop running and me not doing much, 'vmstat 5'
shows interrupts at 100-200 per entry. Loading the box completely with
'make -j4' kernel build their are just over 1000 interrupts. Various other
loads show numbers in between. (eg. it seems to work as one would expect,
presuming the timer interupts dominate...)
	Time seems fine. I havent noticed any interactivity problems.
Performance on 'kernbench' was within a percentage point of 2.6.12
	It does not seem to make any difference as far as the heat of the
cpus or mb, though.

Hope this datapoint is useful;
Paul
set@pobox.com

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

* Re: [PATCH] i386 No-Idle-Hz aka Dynamic-Ticks 3
  2005-08-05  1:30 ` Paul
@ 2005-08-05  3:25   ` Con Kolivas
  0 siblings, 0 replies; 68+ messages in thread
From: Con Kolivas @ 2005-08-05  3:25 UTC (permalink / raw)
  To: Paul; +Cc: linux-kernel

On Fri, 5 Aug 2005 11:30 am, Paul wrote:
> Con Kolivas <kernel@kolivas.org>, on Wed Aug 03, 2005 [03:59:24 PM] said:
> > This is the dynamic ticks patch for i386 as written by Tony Lindgen
> > <tony@atomide.com> and Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>.
> > Patch for 2.6.13-rc5

> 	Ive been running this all afternoon on a pIIx2 @400mhz desktop
> machine, SMP enabled Preempt kernel.
> 	Initially, I tried it using APIC, got X up and tried to play
> some music, but mplayer just hung and prompts in other terminals
> were super slugish or blocked until I killed mplayer. (there were
> no interrupts from the sound card during this time.) Without using
> APIC, it seems to work just great.
> 	With my regular desktop running and me not doing much, 'vmstat 5'
> shows interrupts at 100-200 per entry. Loading the box completely with
> 'make -j4' kernel build their are just over 1000 interrupts. Various other
> loads show numbers in between. (eg. it seems to work as one would expect,
> presuming the timer interupts dominate...)
> 	Time seems fine. I havent noticed any interactivity problems.
> Performance on 'kernbench' was within a percentage point of 2.6.12
> 	It does not seem to make any difference as far as the heat of the
> cpus or mb, though.

Thanks for the feedback. As Tony mentioned, it simply allows for better power 
management to be done rather than saving power on its own. At idle it allows 
the processor to enter a lower power state for example, which I doubt the pII 
does.

Cheers,
Con

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

* [PATCH] Timer Top tweaks
  2005-08-04 21:15 ` [PATCH] Timer Top was: " Daniel Petrini
@ 2005-08-05  4:05   ` Con Kolivas
  2005-08-05  6:46   ` [ck] [PATCH] Timer Top was: i386 No-Idle-Hz aka Dynamic-Ticks 3 Jens Axboe
  1 sibling, 0 replies; 68+ messages in thread
From: Con Kolivas @ 2005-08-05  4:05 UTC (permalink / raw)
  To: Daniel Petrini; +Cc: tony, linux-kernel, ck, tuukka.tikkanen, ilias.biris

[-- Attachment #1: Type: text/plain, Size: 738 bytes --]

On Fri, 5 Aug 2005 07:15 am, Daniel Petrini wrote:
> Hi,
>
> Here we have some support to have more tests on Dynamic Tick.
> We have some functions that exports timers information to a proc entry
> (/proc/top_info), in a kernel patch and a script that handles this
> info and give some output to analyse. We tried to make it less
> intrusive as possible.
>
> It is based in suggestions from Tony Lindgren.
>
> It is experimental and should evolve.
>
> Must be applied after 2.6.13-rc5-dtck-3.patch and 2.6.13-rc5.
>
> Usage: with kernel compiled with attached patch: "perl timer_top.pl
> 5", to have refresh time of 5s.

Yes that's very nice.

It's probably premature but here's a small patch to your timer_top patch. 

Cheers,
Con
---



[-- Attachment #2: timer_top_tweaks.patch --]
[-- Type: text/x-diff, Size: 4259 bytes --]

Index: linux-2.6.13-rc5-ck2/kernel/Makefile
===================================================================
--- linux-2.6.13-rc5-ck2.orig/kernel/Makefile	2005-08-05 13:41:26.000000000 +1000
+++ linux-2.6.13-rc5-ck2/kernel/Makefile	2005-08-05 13:49:23.000000000 +1000
@@ -7,7 +7,7 @@ obj-y     = sched.o fork.o exec_domain.o
 	    sysctl.o capability.o ptrace.o timer.o user.o \
 	    signal.o sys.o kmod.o workqueue.o pid.o \
 	    rcupdate.o intermodule.o extable.o params.o posix-timers.o \
-	    kthread.o wait.o kfifo.o sys_ni.o posix-cpu-timers.o timer_top.o
+	    kthread.o wait.o kfifo.o sys_ni.o posix-cpu-timers.o
 
 obj-$(CONFIG_FUTEX) += futex.o
 obj-$(CONFIG_GENERIC_ISA_DMA) += dma.o
@@ -30,7 +30,7 @@ obj-$(CONFIG_SYSFS) += ksysfs.o
 obj-$(CONFIG_GENERIC_HARDIRQS) += irq/
 obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
 obj-$(CONFIG_SECCOMP) += seccomp.o
-obj-$(CONFIG_NO_IDLE_HZ) += dyn-tick.o
+obj-$(CONFIG_NO_IDLE_HZ) += dyn-tick.o timer_top.o
 
 ifneq ($(CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER),y)
 # According to Alan Modra <alan@linuxcare.com.au>, the -fno-omit-frame-pointer is
Index: linux-2.6.13-rc5-ck2/kernel/timer.c
===================================================================
--- linux-2.6.13-rc5-ck2.orig/kernel/timer.c	2005-08-05 13:41:26.000000000 +1000
+++ linux-2.6.13-rc5-ck2/kernel/timer.c	2005-08-05 13:57:23.000000000 +1000
@@ -509,7 +509,9 @@ static inline void __run_timers(tvec_bas
 
 #ifdef CONFIG_NO_IDLE_HZ
 extern struct timer_top_info top_info;
-extern int account_timer(unsigned int function, struct timer_top_info * top_info);
+extern int account_timer(unsigned int function,
+			struct timer_top_info *top_info);
+
 /*
  * Find out when the next timer event is due to happen. This
  * is used on S/390 to stop all activity when a cpus is idle.
Index: linux-2.6.13-rc5-ck2/kernel/timer_top.c
===================================================================
--- linux-2.6.13-rc5-ck2.orig/kernel/timer_top.c	2005-08-05 13:41:26.000000000 +1000
+++ linux-2.6.13-rc5-ck2/kernel/timer_top.c	2005-08-05 13:54:50.000000000 +1000
@@ -11,7 +11,6 @@
  * published by the Free Software Foundation.
  */
 
-
 #include <linux/list.h>
 #include <linux/proc_fs.h>
 #include <linux/module.h>
@@ -20,8 +19,8 @@ static LIST_HEAD(timer_list);
 
 struct timer_top_info {
 	unsigned int		func_pointer;
-	unsigned int long	counter;
-	struct list_head 	list;      	
+	unsigned long		counter;
+	struct list_head 	list;
 };
 
 struct timer_top_info top_info;
@@ -30,37 +29,38 @@ int account_timer(unsigned int function,
 {
 	struct timer_top_info *top;
 
-	list_for_each_entry (top, &timer_list, list) {
+	list_for_each_entry(top, &timer_list, list) {
 		/* if it is in the list increment its count */
 		if (top->func_pointer == function) {
-			top->counter += 1;
-			return 0;
+			top->counter++;
+			goto out;
 		}
 	}
-	
+
 	/* if you are here then it didnt find so inserts in the list */
 
 	top = kmalloc(sizeof(struct timer_top_info), GFP_KERNEL);
-	if (!top) 
+	if (!top)
 		return -ENOMEM;
 	top->func_pointer = function;
 	top->counter = 1;
 	list_add(&top->list, &timer_list);
 
+out:
 	return 0;
 }
 
 EXPORT_SYMBOL(account_timer);
 
 struct top_info_poll {
-  char value[18];
+	char value[18];
 };
 
 struct top_info_poll top_info_poll_dt;
 struct proc_dir_entry *top_info_file;
 
 static int proc_read_top_info(char *page, char **start, off_t off,
-                                int count, int *eof, void *data)
+				int count, int *eof, void *data)
 {
 	char aux[18];
 	struct timer_top_info *top;
@@ -69,21 +69,19 @@ static int proc_read_top_info(char *page
 
 	sprintf(page, "Function counter - %s\n", info_poll_data->value);
 
-	list_for_each_entry (top, &timer_list, list) {
+	list_for_each_entry(top, &timer_list, list) {
 		sprintf(aux, "%x %lu\n", top->func_pointer, top->counter);
 		strcat(page, aux);
 	}
 
 	return strlen(page);
- 
-} 
+}
 
 static int init_top_info(void)
 {
 	top_info_file = create_proc_entry("top_info", 0666, NULL);
-	if(top_info_file == NULL) {
-	  return -ENOMEM;
-	}
+	if (top_info_file == NULL)
+		return -ENOMEM;
 
 	strcpy(top_info_poll_dt.value, "Timer Top v0.9.1");
 
@@ -96,6 +94,3 @@ static int init_top_info(void)
 
 module_init(init_top_info);
 //module_exit();
-
-
-

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

* Re: [PATCH] i386 No-Idle-Hz aka Dynamic-Ticks 3
  2005-08-04 15:03       ` Vojtech Pavlik
@ 2005-08-05  5:12         ` Con Kolivas
  0 siblings, 0 replies; 68+ messages in thread
From: Con Kolivas @ 2005-08-05  5:12 UTC (permalink / raw)
  To: Vojtech Pavlik; +Cc: Jan De Luyck, linux-kernel, ck, tony, tuukka.tikkanen

[-- Attachment #1: Type: text/plain, Size: 1875 bytes --]

On Fri, 5 Aug 2005 01:03 am, Vojtech Pavlik wrote:
> On Wed, Aug 03, 2005 at 04:23:59PM +0200, Jan De Luyck wrote:
> > On Wednesday 03 August 2005 14:14, Con Kolivas wrote:
> > > On Wed, 3 Aug 2005 21:54, Jan De Luyck wrote:
> > > > On Wednesday 03 August 2005 07:59, Con Kolivas wrote:
> > > > > This is the dynamic ticks patch for i386 as written by Tony Lindgen
> > > > > <tony@atomide.com> and Tuukka Tikkanen
> > > > > <tuukka.tikkanen@elektrobit.com>. Patch for 2.6.13-rc5
> > > >
> > > > Compiles and runs ok here.
> > > >
> > > > Is there actually any timer frequency that's advisable to set as
> > > > maximum? (in the kernel config)
> > >
> > > I'd recommend 1000.
> >
> > Thanks. Currently the system - under X, KDE, no artsd, bottoms at around
> > 300HZ. In total single mode with every module unloaded that I can unload
> > it stops around 22HZ.
> >
> > I guess I'll have to go hunting whatever thing is causing the pollings.
> > no timertop yet, I guess? :P
>
> i8042 runs a steady periodic 20Hz timer. You can make it slower to get
> even the total low lower, and it will not affect performance under
> normal (sane hardware) circumstances.

Indeed and this patch (safely tried at home but serves no useful purpose 
really) confirms a reasonable drop without problems. After this, only fbcon 
polls at a similar rate (HZ/5).

Of interest to those using an ondemand scaling governor, now that we have 
timertop, I have found that the default ondemand settings lead to 
delayed_work_timer_fn at about 140Hz and this can be dropped substantially by 
slowing the rate of polling (and subsequently slowing the speed with which 
the ondemand governor responds) down to <25 by

echo 100000 > /sys/devices/system/cpu/cpu0/cpufreq/ondemand/sampling_rate

(the default is 10000 and the value is confusing as the rate goes down as you 
increase this value).

Cheers,
Con

[-- Attachment #2: i8042_slowpoll.patch --]
[-- Type: text/x-diff, Size: 442 bytes --]

Index: linux-2.6.13-rc5-ck2/drivers/input/serio/i8042.h
===================================================================
--- linux-2.6.13-rc5-ck2.orig/drivers/input/serio/i8042.h	2005-07-06 16:56:52.000000000 +1000
+++ linux-2.6.13-rc5-ck2/drivers/input/serio/i8042.h	2005-08-05 15:03:49.000000000 +1000
@@ -44,7 +44,7 @@
  * polling.
  */
 
-#define I8042_POLL_PERIOD	HZ/20
+#define I8042_POLL_PERIOD	HZ/5
 
 /*
  * Status register bits.

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

* Re: [ck] [PATCH] Timer Top was: i386 No-Idle-Hz aka Dynamic-Ticks 3
  2005-08-04 21:15 ` [PATCH] Timer Top was: " Daniel Petrini
  2005-08-05  4:05   ` [PATCH] Timer Top tweaks Con Kolivas
@ 2005-08-05  6:46   ` Jens Axboe
  2005-08-05 12:39     ` Daniel Petrini
  1 sibling, 1 reply; 68+ messages in thread
From: Jens Axboe @ 2005-08-05  6:46 UTC (permalink / raw)
  To: Daniel Petrini
  Cc: Con Kolivas, tony, ck, tuukka.tikkanen, linux-kernel, ilias.biris

On Thu, Aug 04 2005, Daniel Petrini wrote:
> +static LIST_HEAD(timer_list);
> +
> +struct timer_top_info {
> +	unsigned int		func_pointer;
> +	unsigned int long	counter;
> +	struct list_head 	list;      	
> +};
> +
> +struct timer_top_info top_info;
> +
> +int account_timer(unsigned int function, struct timer_top_info * top_info)
> +{
> +	struct timer_top_info *top;
> +
> +	list_for_each_entry (top, &timer_list, list) {
> +		/* if it is in the list increment its count */
> +		if (top->func_pointer == function) {
> +			top->counter += 1;
> +			return 0;
> +		}
> +	}

What protects this list?

> +	
> +	/* if you are here then it didnt find so inserts in the list */
> +
> +	top = kmalloc(sizeof(struct timer_top_info), GFP_KERNEL);
> +	if (!top) 
> +		return -ENOMEM;

You can't use GFP_KERNEL here, you are inside the timer base lock.

-- 
Jens Axboe


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

* Re: [PATCH] i386 No-Idle-Hz aka Dynamic-Ticks 3
  2005-08-03  5:59 [PATCH] i386 No-Idle-Hz aka Dynamic-Ticks 3 Con Kolivas
                   ` (8 preceding siblings ...)
  2005-08-05  1:30 ` Paul
@ 2005-08-05 12:37 ` Srivatsa Vaddagiri
  2005-08-05 13:08   ` Con Kolivas
  2005-08-08  7:26   ` [PATCH] i386 No-Idle-Hz aka Dynamic-Ticks 3 Tony Lindgren
  9 siblings, 2 replies; 68+ messages in thread
From: Srivatsa Vaddagiri @ 2005-08-05 12:37 UTC (permalink / raw)
  To: Con Kolivas
  Cc: linux-kernel, ck, tony, tuukka.tikkanen, george, Andrew Morton

On Wed, Aug 03, 2005 at 06:05:28AM +0000, Con Kolivas wrote:
> This is the dynamic ticks patch for i386 as written by Tony Lindgen 
> <tony@atomide.com> and Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>. 
> Patch for 2.6.13-rc5
> 
> There were a couple of things that I wanted to change so here is an updated 
> version. This code should have stabilised enough for general testing now.

Con,
	I have been looking at some of the requirement of tickless idle CPUs in
core kernel areas like scheduler and RCU. Basically, both power management and 
virtualization benefit if idle CPUs can cut off useless timer ticks. Especially 
from a virtualization standpoint, I think it makes sense that we enable this 
feature on a per-CPU basis i.e let individual CPUs cut off their ticks as and 
when they become idle. The benefit of this is more visible in platforms that 
host lot of (SMP) VMs on the same machine. Most of the time, these VMs may be 
partially idle (some CPUs in it are idle, some not) and it is good that we 
quiesce the timer ticks on the partial set of idle CPUs. Both S390 and Xen ports
of Linux kernel have this ability today (S390 has it in mainline already and 
Xen has it out of tree).

>From this viewpoint, I think the current implementation of dynamic tick
falls short of this requirement. It cuts of the timer ticks only when 
all CPUs go idle.

Apart from this observation, I have some others about the current dynamic tick
patch:

- All CPUs seem to cut off the same number of ticks (dyn_tick->skip). Isn't
  this wrong, considering that the timer list is per-CPU? This will cause
  some timers to be serviced much later than usual.

- The fact that dyn_tick_state is global and accessed from all CPUs
  is probably a scalability concern, especially if we allow the ticks
  to be cut off on per-CPU basis.

- Again, when we allow this on a per-CPU basis, subsystems like
  RCU need to know the partial set of idle CPUs. RCU already does
  that thr' nohz_cpu_mask (which will need to replace dyn_cpu_map).

- Looking at dyn_tick_timer_interrupt, would it be nice if we avoid calling 
  do_timer_interrupt so many times and instead update jiffies to
  (skipped_ticks - 1) and then call do_timer_interrupt once? I think
  VST does it that way.

- dyn_tick->max_skip = 0xffffff / apic_timer_val;
	From my reading of Intel docs, APIC_TMICT is 32-bit. So why does the
  above calculation take only 24-bits into account? What am I missing here?


I can take a shot at addressing these concerns in dynamic_tick patch, but it 
seems to me that VST has already addressed all these to a big extent. Had you 
considered VST before? The biggest bottleneck I see in VST going mainline is 
its dependency on HRT patch but IMO it should be possible to write a small patch
to support VST w/o HRT. 

George, what do you think?


-- 


Thanks and Regards,
Srivatsa Vaddagiri,
Linux Technology Center,
IBM Software Labs,
Bangalore, INDIA - 560017

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

* Re: [ck] [PATCH] Timer Top was: i386 No-Idle-Hz aka Dynamic-Ticks 3
  2005-08-05  6:46   ` [ck] [PATCH] Timer Top was: i386 No-Idle-Hz aka Dynamic-Ticks 3 Jens Axboe
@ 2005-08-05 12:39     ` Daniel Petrini
  2005-08-05 13:55       ` Daniel Petrini
  0 siblings, 1 reply; 68+ messages in thread
From: Daniel Petrini @ 2005-08-05 12:39 UTC (permalink / raw)
  To: Jens Axboe
  Cc: Con Kolivas, tony, ck, tuukka.tikkanen, linux-kernel, ilias.biris

[-- Attachment #1: Type: text/plain, Size: 153 bytes --]

Hi,

> --
> Jens Axboe
> 

Thanks for your corrections. Here we have a new version. 

Daniel Petrini
-- 
10LE - Linux
INdT - Manaus - Brazil

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: timer_top2-20050805.patch --]
[-- Type: text/x-patch; name="timer_top2-20050805.patch", Size: 4228 bytes --]

diff -uprN linux-2.6.12-orig/kernel/Makefile linux-dyn-tick/kernel/Makefile
--- linux-2.6.12-orig/kernel/Makefile	2005-08-03 23:50:26.000000000 -0400
+++ linux-dyn-tick/kernel/Makefile	2005-08-04 16:56:14.000000000 -0400
@@ -7,7 +7,7 @@ obj-y     = sched.o fork.o exec_domain.o
 	    sysctl.o capability.o ptrace.o timer.o user.o \
 	    signal.o sys.o kmod.o workqueue.o pid.o \
 	    rcupdate.o intermodule.o extable.o params.o posix-timers.o \
-	    kthread.o wait.o kfifo.o sys_ni.o posix-cpu-timers.o
+	    kthread.o wait.o kfifo.o sys_ni.o posix-cpu-timers.o timer_top.o
 
 obj-$(CONFIG_FUTEX) += futex.o
 obj-$(CONFIG_GENERIC_ISA_DMA) += dma.o
diff -uprN linux-2.6.12-orig/kernel/timer.c linux-dyn-tick/kernel/timer.c
--- linux-2.6.12-orig/kernel/timer.c	2005-08-03 23:50:27.000000000 -0400
+++ linux-dyn-tick/kernel/timer.c	2005-08-04 16:56:27.000000000 -0400
@@ -508,6 +508,8 @@ static inline void __run_timers(tvec_bas
 }
 
 #ifdef CONFIG_NO_IDLE_HZ
+extern struct timer_top_info top_info;
+extern int account_timer(unsigned int function, struct timer_top_info * top_info);
 /*
  * Find out when the next timer event is due to happen. This
  * is used on S/390 to stop all activity when a cpus is idle.
@@ -571,6 +573,7 @@ found:
 				expires = nte->expires;
 		}
 	}
+	account_timer((unsigned int)nte->function, &top_info);
 	spin_unlock(&base->t_base.lock);
 	return expires;
 }
diff -uprN linux-2.6.12-orig/kernel/timer_top.c linux-dyn-tick/kernel/timer_top.c
--- linux-2.6.12-orig/kernel/timer_top.c	1969-12-31 20:00:00.000000000 -0400
+++ linux-dyn-tick/kernel/timer_top.c	2005-08-05 08:31:08.000000000 -0400
@@ -0,0 +1,111 @@
+/*
+ * kernel/timer_top.c
+ *
+ * Export Timers information to /proc/top_info
+ *
+ * Copyright (C) 2005 Instituto Nokia de Tecnologia - INdT - Manaus
+ * Written by Daniel Petrini <d.pensator@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+
+#include <linux/list.h>
+#include <linux/proc_fs.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+
+static LIST_HEAD(timer_list);
+
+struct timer_top_info {
+	unsigned int		func_pointer;
+	unsigned int long	counter;
+	struct list_head 	list;      	
+};
+
+struct timer_top_info top_info;
+
+static spinlock_t timer_lock = SPIN_LOCK_UNLOCKED;
+static unsigned long flags;
+
+
+int account_timer(unsigned int function, struct timer_top_info * top_info)
+{
+	struct timer_top_info *top;
+
+	spin_lock_irqsave(&timer_lock, flags);
+
+	list_for_each_entry (top, &timer_list, list) {
+		/* if it is in the list increment its count */
+		if (top->func_pointer == function) {
+			top->counter += 1;
+			spin_unlock_irqrestore(&timer_lock, flags);
+			return 0;
+		}
+	}
+	
+	/* if you are here then it didnt find so inserts in the list */
+
+	top = kmalloc(sizeof(struct timer_top_info), GFP_ATOMIC);
+	if (!top) 
+		return -ENOMEM;
+	top->func_pointer = function;
+	top->counter = 1;
+	list_add(&top->list, &timer_list);
+
+	spin_unlock_irqrestore(&timer_lock, flags);
+
+	return 0;
+}
+
+EXPORT_SYMBOL(account_timer);
+
+struct top_info_poll {
+  char value[18];
+};
+
+static struct top_info_poll top_info_poll_dt;
+static struct proc_dir_entry *top_info_file;
+
+static int proc_read_top_info(char *page, char **start, off_t off,
+                                int count, int *eof, void *data)
+{
+	char aux[18];
+	struct timer_top_info *top;
+
+	struct top_info_poll *info_poll_data=(struct top_info_poll *)data;
+
+	sprintf(page, "Function counter - %s\n", info_poll_data->value);
+
+	list_for_each_entry (top, &timer_list, list) {
+		sprintf(aux, "%x %lu\n", top->func_pointer, top->counter);
+		strcat(page, aux);
+	}
+
+	return strlen(page);
+ 
+} 
+
+static int init_top_info(void)
+{
+	top_info_file = create_proc_entry("top_info", 0666, NULL);
+	if(top_info_file == NULL) {
+	  return -ENOMEM;
+	}
+
+	strcpy(top_info_poll_dt.value, "Timer Top v0.9.1");
+
+	top_info_file->data = &top_info_poll_dt;
+	top_info_file->read_proc = &proc_read_top_info;
+	top_info_file->owner = THIS_MODULE;
+	
+	return 0;
+}
+
+module_init(init_top_info);
+//module_exit();
+
+
+

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

* Re: [PATCH] i386 No-Idle-Hz aka Dynamic-Ticks 3
  2005-08-05 12:37 ` Srivatsa Vaddagiri
@ 2005-08-05 13:08   ` Con Kolivas
  2005-08-05 16:39     ` [PATCH] i386 No-Idle-Hz aka Dynamic-Ticks 4 Con Kolivas
  2005-08-08  7:26   ` [PATCH] i386 No-Idle-Hz aka Dynamic-Ticks 3 Tony Lindgren
  1 sibling, 1 reply; 68+ messages in thread
From: Con Kolivas @ 2005-08-05 13:08 UTC (permalink / raw)
  To: vatsa; +Cc: linux-kernel, ck, tony, tuukka.tikkanen, george, Andrew Morton

On Fri, 5 Aug 2005 22:37, Srivatsa Vaddagiri wrote:
> On Wed, Aug 03, 2005 at 06:05:28AM +0000, Con Kolivas wrote:
> > This is the dynamic ticks patch for i386 as written by Tony Lindgen
> > <tony@atomide.com> and Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>.
> > Patch for 2.6.13-rc5
> >
> > There were a couple of things that I wanted to change so here is an
> > updated version. This code should have stabilised enough for general
> > testing now.
>
> Con,
> 	I have been looking at some of the requirement of tickless idle CPUs in
> core kernel areas like scheduler and RCU. Basically, both power management
> and virtualization benefit if idle CPUs can cut off useless timer ticks.
> Especially from a virtualization standpoint, I think it makes sense that we
> enable this feature on a per-CPU basis i.e let individual CPUs cut off
> their ticks as and when they become idle. The benefit of this is more
> visible in platforms that host lot of (SMP) VMs on the same machine. Most
> of the time, these VMs may be partially idle (some CPUs in it are idle,
> some not) and it is good that we quiesce the timer ticks on the partial set
> of idle CPUs. Both S390 and Xen ports of Linux kernel have this ability
> today (S390 has it in mainline already and Xen has it out of tree).

Hi Srivatsa.

Thanks very much for your comments. The actual codebase for dynticks I've 
never staked any claim to as it isn't mine. The demand for such a feature in 
the kernel on multiple architectures appears to have reached critical mass 
with mainline now considering another Hz change. This is why I decided to 
champion this patch at this time by polishing and tweaking it (in purely 
cosmetic ways). I mostly agree with your comments about limitations of this 
patch and would like to see changes like those you describe done in an 
arch-neutral fashion as well. I have not the hardware resources to develop 
such code and would be more than happy if have generated enough interest in 
dynticks for you to develop it further via whatever means. Knowing arm and 
S390 already have dynticks makes it more important that cross-arch code is 
consolidated sooner rather than later.

Cheers,
Con

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

* Re: [ck] [PATCH] Timer Top was: i386 No-Idle-Hz aka Dynamic-Ticks 3
  2005-08-05 12:39     ` Daniel Petrini
@ 2005-08-05 13:55       ` Daniel Petrini
  0 siblings, 0 replies; 68+ messages in thread
From: Daniel Petrini @ 2005-08-05 13:55 UTC (permalink / raw)
  To: Jens Axboe, ck
  Cc: Con Kolivas, tony, tuukka.tikkanen, linux-kernel, ilias.biris

[-- Attachment #1: Type: text/plain, Size: 163 bytes --]

Hi,

Here we have a new version that includes Jens Axboe's corrections and
Con Kolivas tweaks.

Thanks,

Daniel
-- 
10LE - Linux
INdT - Manaus - Brazil

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: timer_top3-20050805.patch --]
[-- Type: text/x-patch; name="timer_top3-20050805.patch", Size: 4167 bytes --]

diff -uprN linux-2.6.12-orig/kernel/Makefile linux-dyn-tick/kernel/Makefile
--- linux-2.6.12-orig/kernel/Makefile	2005-08-05 09:33:24.000000000 -0400
+++ linux-dyn-tick/kernel/Makefile	2005-08-05 09:28:18.000000000 -0400
@@ -30,7 +30,7 @@ obj-$(CONFIG_SYSFS) += ksysfs.o
 obj-$(CONFIG_GENERIC_HARDIRQS) += irq/
 obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
 obj-$(CONFIG_SECCOMP) += seccomp.o
-obj-$(CONFIG_NO_IDLE_HZ) += dyn-tick.o
+obj-$(CONFIG_NO_IDLE_HZ) += dyn-tick.o timer_top.o
 
 ifneq ($(CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER),y)
 # According to Alan Modra <alan@linuxcare.com.au>, the -fno-omit-frame-pointer is
diff -uprN linux-2.6.12-orig/kernel/timer.c linux-dyn-tick/kernel/timer.c
--- linux-2.6.12-orig/kernel/timer.c	2005-08-05 09:33:31.000000000 -0400
+++ linux-dyn-tick/kernel/timer.c	2005-08-05 09:38:33.000000000 -0400
@@ -508,6 +508,9 @@ static inline void __run_timers(tvec_bas
 }
 
 #ifdef CONFIG_NO_IDLE_HZ
+extern struct timer_top_info top_info;
+extern int account_timer(unsigned int function,
+	       		struct timer_top_info * top_info);
 /*
  * Find out when the next timer event is due to happen. This
  * is used on S/390 to stop all activity when a cpus is idle.
@@ -571,6 +574,7 @@ found:
 				expires = nte->expires;
 		}
 	}
+	account_timer((unsigned int)nte->function, &top_info);
 	spin_unlock(&base->t_base.lock);
 	return expires;
 }
diff -uprN linux-2.6.12-orig/kernel/timer_top.c linux-dyn-tick/kernel/timer_top.c
--- linux-2.6.12-orig/kernel/timer_top.c	1969-12-31 20:00:00.000000000 -0400
+++ linux-dyn-tick/kernel/timer_top.c	2005-08-05 09:28:38.000000000 -0400
@@ -0,0 +1,108 @@
+/*
+ * kernel/timer_top.c
+ *
+ * Export Timers information to /proc/top_info
+ *
+ * Copyright (C) 2005 Instituto Nokia de Tecnologia - INdT - Manaus
+ * Written by Daniel Petrini <d.pensator@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+
+#include <linux/list.h>
+#include <linux/proc_fs.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+
+static LIST_HEAD(timer_list);
+
+struct timer_top_info {
+	unsigned int		func_pointer;
+	unsigned long		counter;
+	struct list_head 	list;      	
+};
+
+struct timer_top_info top_info;
+
+static spinlock_t timer_lock = SPIN_LOCK_UNLOCKED;
+static unsigned long flags;
+
+
+int account_timer(unsigned int function, struct timer_top_info * top_info)
+{
+	struct timer_top_info *top;
+
+	spin_lock_irqsave(&timer_lock, flags);
+
+	list_for_each_entry(top, &timer_list, list) {
+		/* if it is in the list increment its count */
+		if (top->func_pointer == function) {
+			top->counter++;
+			spin_unlock_irqrestore(&timer_lock, flags);
+			goto out;
+		}
+	}
+	
+	/* if you are here then it didnt find so inserts in the list */
+
+	top = kmalloc(sizeof(struct timer_top_info), GFP_ATOMIC);
+	if (!top) 
+		return -ENOMEM;
+	top->func_pointer = function;
+	top->counter = 1;
+	list_add(&top->list, &timer_list);
+
+	spin_unlock_irqrestore(&timer_lock, flags);
+
+out:	
+	return 0;
+}
+
+EXPORT_SYMBOL(account_timer);
+
+struct top_info_poll {
+	char value[18];
+};
+
+static struct top_info_poll top_info_poll_dt;
+static struct proc_dir_entry *top_info_file;
+
+static int proc_read_top_info(char *page, char **start, off_t off,
+				int count, int *eof, void *data)
+{
+	char aux[18];
+	struct timer_top_info *top;
+
+	struct top_info_poll *info_poll_data=(struct top_info_poll *)data;
+
+	sprintf(page, "Function counter - %s\n", info_poll_data->value);
+
+	list_for_each_entry(top, &timer_list, list) {
+		sprintf(aux, "%x %lu\n", top->func_pointer, top->counter);
+		strcat(page, aux);
+	}
+
+	return strlen(page);
+} 
+
+static int init_top_info(void)
+{
+	top_info_file = create_proc_entry("top_info", 0666, NULL);
+	if (top_info_file == NULL) {
+		return -ENOMEM;
+	}
+
+	strcpy(top_info_poll_dt.value, "Timer Top v0.9.1");
+
+	top_info_file->data = &top_info_poll_dt;
+	top_info_file->read_proc = &proc_read_top_info;
+	top_info_file->owner = THIS_MODULE;
+	
+	return 0;
+}
+
+module_init(init_top_info);
+//module_exit();

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

* [PATCH] i386 No-Idle-Hz aka Dynamic-Ticks 4
  2005-08-05 13:08   ` Con Kolivas
@ 2005-08-05 16:39     ` Con Kolivas
  2005-08-06 17:47       ` Adrian Bunk
  0 siblings, 1 reply; 68+ messages in thread
From: Con Kolivas @ 2005-08-05 16:39 UTC (permalink / raw)
  To: linux-kernel; +Cc: vatsa, ck, tony, tuukka.tikkanen, george, Andrew Morton

[-- Attachment #1: Type: text/plain, Size: 221 bytes --]

Here's my most current version of the dynamic ticks patch for i386 with some 
more minor cleanups already discussed and cosmetic changes ( also available 
at http://ck.kolivas.org/patches/dyn-ticks/ ).

Cheers,
Con
---



[-- Attachment #2: 2.6.13-rc5-dtck-4.patch --]
[-- Type: text/x-diff, Size: 30195 bytes --]

Index: linux-2.6.13-rc5-ck2/arch/i386/Kconfig
===================================================================
--- linux-2.6.13-rc5-ck2.orig/arch/i386/Kconfig	2005-08-05 20:41:44.000000000 +1000
+++ linux-2.6.13-rc5-ck2/arch/i386/Kconfig	2005-08-05 20:44:28.000000000 +1000
@@ -457,6 +457,41 @@ config HPET_EMULATE_RTC
 	bool "Provide RTC interrupt"
 	depends on HPET_TIMER && RTC=y
 
+config NO_IDLE_HZ
+	bool "Dynamic Tick Timer - Skip timer ticks during idle"
+	depends on EXPERIMENTAL
+	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 can disable dynamic tick timer either by
+	  passing dyntick=disable command line option, or via sysfs:
+
+	  # echo 0 > /sys/devices/system/dyn_tick/dyn_tick0/enable
+
+config DYN_TICK_USE_APIC
+	bool "Use APIC timer instead of PIT timer"
+	depends on NO_IDLE_HZ
+	help
+	  This option enables using APIC timer interrupt if your hardware
+	  supports it. APIC timer allows longer sleep periods compared
+	  to PIT timer, however on MOST recent hardware disabling the PIT
+	  timer also disables APIC timer interrupts, and the system won't
+	  run properly. Symptoms include slow system boot, and time running 
+	  slow.
+
+	  If unsure, do NOT enable this option.
+
+	  Note that you can disable apic usage by dynamic tick timer
+	  either by passing dyntick=noapic command line option, or via 
+	  sysfs:
+
+	  # echo 0 > /sys/devices/system/dyn_tick/dyn_tick0/useapic
+
 config SMP
 	bool "Symmetric multi-processing support"
 	---help---
Index: linux-2.6.13-rc5-ck2/arch/i386/kernel/apic.c
===================================================================
--- linux-2.6.13-rc5-ck2.orig/arch/i386/kernel/apic.c	2005-08-05 20:41:44.000000000 +1000
+++ linux-2.6.13-rc5-ck2/arch/i386/kernel/apic.c	2005-08-05 20:42:18.000000000 +1000
@@ -27,6 +27,7 @@
 #include <linux/kernel_stat.h>
 #include <linux/sysdev.h>
 #include <linux/cpu.h>
+#include <linux/dyn-tick.h>
 
 #include <asm/atomic.h>
 #include <asm/smp.h>
@@ -931,6 +932,8 @@ void (*wait_timer_tick)(void) __devinitd
 
 #define APIC_DIVISOR 16
 
+u32 apic_timer_val;
+
 static void __setup_APIC_LVTT(unsigned int clocks)
 {
 	unsigned int lvtt_value, tmp_value, ver;
@@ -949,7 +952,12 @@ static void __setup_APIC_LVTT(unsigned i
 				& ~(APIC_TDR_DIV_1 | APIC_TDR_DIV_TMBASE))
 				| APIC_TDR_DIV_16);
 
-	apic_write_around(APIC_TMICT, clocks/APIC_DIVISOR);
+	apic_timer_val = clocks / APIC_DIVISOR;
+
+	if (apic_timer_val)
+		set_dyn_tick_max_skip(apic_timer_val);
+
+	apic_write_around(APIC_TMICT, apic_timer_val);
 }
 
 static void __devinit setup_APIC_timer(unsigned int clocks)
@@ -1062,6 +1070,8 @@ void __init setup_boot_APIC_clock(void)
 	 */
 	setup_APIC_timer(calibration_result);
 
+	setup_dyn_tick_use_apic(calibration_result);
+
 	local_irq_enable();
 }
 
@@ -1200,6 +1210,13 @@ fastcall void smp_apic_timer_interrupt(s
 	 * interrupt lock, which is the WrongThing (tm) to do.
 	 */
 	irq_enter();
+
+	/*
+	 * Check if we need to wake up PIT interrupt handler.
+	 * Otherwise just wake up local APIC timer.
+	 */
+	wakeup_pit_or_apic(cpu, regs);
+
 	smp_local_timer_interrupt(regs);
 	irq_exit();
 }
Index: linux-2.6.13-rc5-ck2/arch/i386/kernel/dyn-tick.c
===================================================================
--- linux-2.6.13-rc5-ck2.orig/arch/i386/kernel/dyn-tick.c	2005-01-12 16:19:45.000000000 +1100
+++ linux-2.6.13-rc5-ck2/arch/i386/kernel/dyn-tick.c	2005-08-05 20:48:57.000000000 +1000
@@ -0,0 +1,150 @@
+/*
+ * linux/arch/i386/kernel/dyn-tick.c
+ *
+ * Copyright (C) 2004 Nokia Corporation
+ * Written by Tony Lindgen <tony@atomide.com> and
+ * Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/version.h>
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/dyn-tick.h>
+#include <asm/apic.h>
+
+void arch_reprogram_timer(void)
+{
+	if (cpu_has_local_apic()) {
+		disable_pit_timer();
+		if (dyn_tick->state & DYN_TICK_TIMER_INT)
+			reprogram_apic_timer(dyn_tick->skip);
+	} else {
+		if (dyn_tick->state & DYN_TICK_TIMER_INT)
+			reprogram_pit_timer(dyn_tick->skip);
+		else
+			disable_pit_timer();
+	}
+}
+
+static struct dyn_tick_timer arch_dyn_tick_timer = {
+	.arch_reprogram_timer	= &arch_reprogram_timer,
+};
+
+int __init dyn_tick_init(void)
+{
+	arch_dyn_tick_timer.arch_init = dyn_tick_arch_init;
+	dyn_tick_register(&arch_dyn_tick_timer);
+
+	return 0;
+}
+
+arch_initcall(dyn_tick_init);
+
+static unsigned long long last_tick;
+
+/*
+ * This interrupt handler updates the time based on number of jiffies skipped
+ * It would be somewhat more optimized to have a custom handler in each timer
+ * using hardware ticks instead of nanoseconds. Note that CONFIG_NO_IDLE_HZ
+ * currently disables timer fallback on skipped jiffies.
+ */
+irqreturn_t dyn_tick_timer_interrupt(int irq, void *dev_id,
+				     struct pt_regs *regs)
+{
+	unsigned long flags;
+	volatile unsigned long long now;
+	unsigned int skipped = 0;
+
+	write_seqlock_irqsave(&xtime_lock, flags);
+	now = cur_timer->monotonic_clock();
+	while (now - last_tick >= NS_TICK_LEN) {
+		last_tick += NS_TICK_LEN;
+		cur_timer->mark_offset();
+		do_timer_interrupt(irq, NULL, regs);
+		skipped++;
+	}
+	if (dyn_tick->state & (DYN_TICK_ENABLED | DYN_TICK_SKIPPING)) {
+		dyn_tick->skip = 1;
+		if (cpu_has_local_apic())
+			reprogram_apic_timer(dyn_tick->skip);
+		reprogram_pit_timer(dyn_tick->skip);
+		dyn_tick->state |= DYN_TICK_ENABLED;
+		dyn_tick->state &= ~DYN_TICK_SKIPPING;
+	}
+	write_sequnlock_irqrestore(&xtime_lock, flags);
+
+	return IRQ_HANDLED;
+}
+
+int __init dyn_tick_arch_init(void)
+{
+	unsigned long flags;
+
+	write_seqlock_irqsave(&xtime_lock, flags);
+	last_tick = cur_timer->monotonic_clock();
+	dyn_tick->skip = 1;
+	if (!(dyn_tick->state & DYN_TICK_USE_APIC) || !cpu_has_local_apic())
+		dyn_tick->max_skip = 0xffff / LATCH;	/* PIT timer length */
+	printk(KERN_INFO "dyn-tick: Maximum ticks to skip limited to %i\n",
+	       dyn_tick->max_skip);
+	write_sequnlock_irqrestore(&xtime_lock, flags);
+
+	dyn_tick->interrupt = dyn_tick_timer_interrupt;
+	replace_timer_interrupt(dyn_tick->interrupt);
+
+	return 0;
+}
+
+/* Functions that need blank prototypes for !CONFIG_NO_IDLE_HZ below here */
+inline void set_dyn_tick_max_skip(u32 apic_timer_val)
+{
+	dyn_tick->max_skip = 0xffffff / apic_timer_val;
+}
+
+inline void setup_dyn_tick_use_apic(unsigned int calibration_result)
+{
+	if (calibration_result)
+		dyn_tick->state |= DYN_TICK_USE_APIC;
+	else
+		printk(KERN_INFO "dyn-tick: Cannot use local APIC\n");
+}
+
+void wakeup_pit_or_apic(int cpu, struct pt_regs *regs)
+{
+	unsigned long seq; 
+
+	do {
+		seq = read_seqbegin(&xtime_lock);
+		if (dyn_tick->state & (DYN_TICK_ENABLED | DYN_TICK_SKIPPING)) {
+			if (dyn_tick->skip_cpu == cpu &&
+				dyn_tick->skip > DYN_TICK_MIN_SKIP)
+					dyn_tick->interrupt(99, NULL, regs);
+				else
+					reprogram_apic_timer(1);
+		}
+	} while (read_seqretry(&xtime_lock, seq));
+}
+
+void dyn_tick_interrupt(int irq, struct pt_regs *regs)
+{
+	if (dyn_tick->state & (DYN_TICK_ENABLED | DYN_TICK_SKIPPING) && irq)
+		dyn_tick->interrupt(irq, NULL, regs);
+}
+
+void dyn_tick_time_init(struct timer_opts *cur_timer)
+{
+	if (strncmp(cur_timer->name, "tsc", 3) == 0 ||
+	    strncmp(cur_timer->name, "pmtmr", 3) == 0) {
+		dyn_tick->state |= DYN_TICK_SUITABLE;
+		printk(KERN_INFO "dyn-tick: Found suitable timer: %s\n",
+		       cur_timer->name);
+	} else
+		printk(KERN_ERR "dyn-tick: Cannot use timer %s\n",
+		       cur_timer->name);
+}
Index: linux-2.6.13-rc5-ck2/arch/i386/kernel/irq.c
===================================================================
--- linux-2.6.13-rc5-ck2.orig/arch/i386/kernel/irq.c	2005-08-05 20:41:44.000000000 +1000
+++ linux-2.6.13-rc5-ck2/arch/i386/kernel/irq.c	2005-08-05 20:42:18.000000000 +1000
@@ -18,6 +18,7 @@
 #include <linux/notifier.h>
 #include <linux/cpu.h>
 #include <linux/delay.h>
+#include <linux/dyn-tick.h>
 
 DEFINE_PER_CPU(irq_cpustat_t, irq_stat) ____cacheline_maxaligned_in_smp;
 EXPORT_PER_CPU_SYMBOL(irq_stat);
@@ -76,6 +77,8 @@ fastcall unsigned int do_IRQ(struct pt_r
 	}
 #endif
 
+	dyn_tick_interrupt(irq, regs);
+
 #ifdef CONFIG_4KSTACKS
 
 	curctx = (union irq_ctx *) current_thread_info();
Index: linux-2.6.13-rc5-ck2/arch/i386/kernel/Makefile
===================================================================
--- linux-2.6.13-rc5-ck2.orig/arch/i386/kernel/Makefile	2005-08-05 20:41:44.000000000 +1000
+++ linux-2.6.13-rc5-ck2/arch/i386/kernel/Makefile	2005-08-05 20:42:18.000000000 +1000
@@ -32,6 +32,7 @@ obj-$(CONFIG_MODULES)		+= module.o
 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
 
Index: linux-2.6.13-rc5-ck2/arch/i386/kernel/process.c
===================================================================
--- linux-2.6.13-rc5-ck2.orig/arch/i386/kernel/process.c	2005-08-05 20:41:44.000000000 +1000
+++ linux-2.6.13-rc5-ck2/arch/i386/kernel/process.c	2005-08-05 20:42:18.000000000 +1000
@@ -39,6 +39,7 @@
 #include <linux/ptrace.h>
 #include <linux/random.h>
 #include <linux/kprobes.h>
+#include <linux/dyn-tick.h>
 
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
@@ -200,6 +201,8 @@ void cpu_idle(void)
 			if (cpu_is_offline(cpu))
 				play_dead();
 
+			dyn_tick_reprogram_timer();
+
 			__get_cpu_var(irq_stat).idle_timestamp = jiffies;
 			idle();
 		}
Index: linux-2.6.13-rc5-ck2/arch/i386/kernel/time.c
===================================================================
--- linux-2.6.13-rc5-ck2.orig/arch/i386/kernel/time.c	2005-08-05 20:41:44.000000000 +1000
+++ linux-2.6.13-rc5-ck2/arch/i386/kernel/time.c	2005-08-05 20:50:38.000000000 +1000
@@ -46,6 +46,7 @@
 #include <linux/bcd.h>
 #include <linux/efi.h>
 #include <linux/mca.h>
+#include <linux/dyn-tick.h>
 
 #include <asm/io.h>
 #include <asm/smp.h>
@@ -252,8 +253,7 @@ EXPORT_SYMBOL(profile_pc);
  * timer_interrupt() needs to keep up the real-time clock,
  * as well as call the "do_timer()" routine every clocktick
  */
-static inline void do_timer_interrupt(int irq, void *dev_id,
-					struct pt_regs *regs)
+void do_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
 #ifdef CONFIG_X86_IO_APIC
 	if (timer_ack) {
@@ -423,7 +423,7 @@ static struct sysdev_class timer_sysclas
 
 
 /* XXX this driverfs stuff should probably go elsewhere later -john */
-static struct sys_device device_timer = {
+struct sys_device device_timer = {
 	.id	= 0,
 	.cls	= &timer_sysclass,
 };
@@ -479,5 +479,7 @@ void __init time_init(void)
 	cur_timer = select_timer();
 	printk(KERN_INFO "Using %s for high-res timesource\n",cur_timer->name);
 
+	dyn_tick_time_init(cur_timer);
+
 	time_init_hook();
 }
Index: linux-2.6.13-rc5-ck2/arch/i386/kernel/timers/timer_pit.c
===================================================================
--- linux-2.6.13-rc5-ck2.orig/arch/i386/kernel/timers/timer_pit.c	2005-08-05 20:41:44.000000000 +1000
+++ linux-2.6.13-rc5-ck2/arch/i386/kernel/timers/timer_pit.c	2005-08-05 20:51:37.000000000 +1000
@@ -148,6 +148,44 @@ static unsigned long get_offset_pit(void
 	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 = {
Index: linux-2.6.13-rc5-ck2/arch/i386/kernel/timers/timer_pm.c
===================================================================
--- linux-2.6.13-rc5-ck2.orig/arch/i386/kernel/timers/timer_pm.c	2005-08-05 20:41:44.000000000 +1000
+++ linux-2.6.13-rc5-ck2/arch/i386/kernel/timers/timer_pm.c	2005-08-05 20:42:18.000000000 +1000
@@ -15,6 +15,7 @@
 #include <linux/module.h>
 #include <linux/device.h>
 #include <linux/init.h>
+#include <linux/dyn-tick.h>
 #include <asm/types.h>
 #include <asm/timer.h>
 #include <asm/smp.h>
@@ -168,6 +169,9 @@ static void mark_offset_pmtmr(void)
 	monotonic_base += delta * NSEC_PER_USEC;
 	write_sequnlock(&monotonic_lock);
 
+	if (dyn_tick_enabled())
+		return;
+
 	/* convert to ticks */
 	delta += offset_delay;
 	lost = delta / (USEC_PER_SEC / HZ);
Index: linux-2.6.13-rc5-ck2/arch/i386/kernel/timers/timer_tsc.c
===================================================================
--- linux-2.6.13-rc5-ck2.orig/arch/i386/kernel/timers/timer_tsc.c	2005-08-05 20:41:44.000000000 +1000
+++ linux-2.6.13-rc5-ck2/arch/i386/kernel/timers/timer_tsc.c	2005-08-05 20:42:18.000000000 +1000
@@ -14,6 +14,7 @@
 #include <linux/cpufreq.h>
 #include <linux/string.h>
 #include <linux/jiffies.h>
+#include <linux/dyn-tick.h>
 
 #include <asm/timer.h>
 #include <asm/io.h>
@@ -166,10 +167,19 @@ static void delay_tsc(unsigned long loop
 	} while ((now-bclock) < loops);
 }
 
+/* update the monotonic base value */
+static inline void update_monotonic_base(unsigned long long last_offset)
+{
+	unsigned long long this_offset;
+
+	this_offset = ((unsigned long long)last_tsc_high << 32) | last_tsc_low;
+	monotonic_base += cycles_2_ns(this_offset - last_offset);
+}
+
 #ifdef CONFIG_HPET_TIMER
 static void mark_offset_tsc_hpet(void)
 {
-	unsigned long long this_offset, last_offset;
+	unsigned long long last_offset;
  	unsigned long offset, temp, hpet_current;
 
 	write_seqlock(&monotonic_lock);
@@ -197,9 +207,7 @@ static void mark_offset_tsc_hpet(void)
 	}
 	hpet_last = hpet_current;
 
-	/* 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);
+	update_monotonic_base(last_offset);
 	write_sequnlock(&monotonic_lock);
 
 	/* calculate delay_at_last_interrupt */
@@ -346,7 +354,7 @@ static void mark_offset_tsc(void)
 	int count;
 	int countmp;
 	static int count1 = 0;
-	unsigned long long this_offset, last_offset;
+	unsigned long long last_offset;
 	static int lost_count = 0;
 
 	write_seqlock(&monotonic_lock);
@@ -367,6 +375,12 @@ static void mark_offset_tsc(void)
 
 	rdtsc(last_tsc_low, last_tsc_high);
 
+	if (dyn_tick_enabled()) {
+		update_monotonic_base(last_offset);
+		write_sequnlock(&monotonic_lock);
+		return;
+	}
+
 	spin_lock(&i8253_lock);
 	outb_p(0x00, PIT_MODE);     /* latch the count ASAP */
 
@@ -434,9 +448,8 @@ static void mark_offset_tsc(void)
 			cpufreq_delayed_get();
 	} else
 		lost_count = 0;
-	/* 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);
+
+	update_monotonic_base(last_offset);
 	write_sequnlock(&monotonic_lock);
 
 	/* calculate delay_at_last_interrupt */
Index: linux-2.6.13-rc5-ck2/arch/i386/mach-default/setup.c
===================================================================
--- linux-2.6.13-rc5-ck2.orig/arch/i386/mach-default/setup.c	2005-08-05 20:41:44.000000000 +1000
+++ linux-2.6.13-rc5-ck2/arch/i386/mach-default/setup.c	2005-08-05 20:42:18.000000000 +1000
@@ -93,6 +93,22 @@ void __init time_init_hook(void)
 	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
Index: linux-2.6.13-rc5-ck2/include/asm-i386/dyn-tick.h
===================================================================
--- linux-2.6.13-rc5-ck2.orig/include/asm-i386/dyn-tick.h	2005-01-12 16:19:45.000000000 +1100
+++ linux-2.6.13-rc5-ck2/include/asm-i386/dyn-tick.h	2005-08-05 20:57:02.000000000 +1000
@@ -0,0 +1,85 @@
+/*
+ * linux/include/asm-i386/dyn-tick.h
+ *
+ * Copyright (C) 2004 Nokia Corporation
+ * Written by Tony Lindgen <tony@atomide.com> and
+ * Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef _ASM_I386_DYN_TICK_H_
+#define _ASM_I386_DYN_TICK_H_
+
+#include <asm/apic.h>
+
+#ifdef CONFIG_NO_IDLE_HZ
+extern int dyn_tick_arch_init(void);
+extern void disable_pit_timer(void);
+extern void reprogram_pit_timer(int jiffies_to_skip);
+extern void replace_timer_interrupt(void * new_handler);
+extern void set_dyn_tick_max_skip(u32 apic_timer_val);
+extern void setup_dyn_tick_use_apic(unsigned int calibration_result);
+extern void wakeup_pit_or_apic(int cpu, struct pt_regs *regs);
+extern void dyn_tick_interrupt(int irq, struct pt_regs *regs);
+extern void dyn_tick_time_init(struct timer_opts *cur_timer);
+extern void do_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+extern irqreturn_t dyn_tick_timer_interrupt(int irq, void *dev_id,
+					    struct pt_regs *regs);
+extern int __init dyn_tick_arch_init(void);
+extern u32 apic_timer_val;
+
+#if defined(CONFIG_DYN_TICK_USE_APIC) && \
+	(defined(CONFIG_SMP) || defined(CONFIG_X86_UP_APIC))
+#define cpu_has_local_apic()	(dyn_tick->state & DYN_TICK_USE_APIC)
+#else
+#define cpu_has_local_apic()	0
+#endif
+
+#if defined(CONFIG_DYN_TICK_USE_APIC)
+#define dyntick_apicable()	1
+#else
+#define dyntick_apicable()	0
+#endif
+
+static inline void reprogram_apic_timer(unsigned int count)
+{
+#ifdef CONFIG_X86_LOCAL_APIC
+	unsigned long flags;
+
+	count *= apic_timer_val;
+	local_irq_save(flags);
+	apic_write_around(APIC_TMICT, count);
+	local_irq_restore(flags);
+#endif	/* CONFIG_X86_LOCAL_APIC */
+}
+
+#else /* CONFIG_NO_IDLE_HZ */
+static inline void set_dyn_tick_max_skip(u32 apic_timer_val)
+{
+}
+
+static inline void reprogram_apic_timer(unsigned int count)
+{
+}
+
+static inline void setup_dyn_tick_use_apic(unsigned int calibration_result)
+{
+}
+
+static inline void wakeup_pit_or_apic(int cpu, struct pt_regs *regs)
+{
+}
+
+static inline void dyn_tick_interrupt(int irq, struct pt_regs *regs)
+{
+}
+
+static inline void dyn_tick_time_init(struct timer_opts *cur_timer)
+{
+}
+#endif /* CONFIG_NO_IDLE_HZ */
+
+#endif /* _ASM_I386_DYN_TICK_H_ */
Index: linux-2.6.13-rc5-ck2/include/linux/dyn-tick.h
===================================================================
--- linux-2.6.13-rc5-ck2.orig/include/linux/dyn-tick.h	2005-01-12 16:19:45.000000000 +1100
+++ linux-2.6.13-rc5-ck2/include/linux/dyn-tick.h	2005-08-05 20:56:42.000000000 +1000
@@ -0,0 +1,61 @@
+/*
+ * linux/include/linux/dyn-tick.h
+ *
+ * Copyright (C) 2004 Nokia Corporation
+ * Written by Tony Lindgen <tony@atomide.com> and
+ * Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef _DYN_TICK_TIMER_H
+#define _DYN_TICK_TIMER_H
+
+#include <linux/interrupt.h>
+#include <asm/timer.h>
+
+#define DYN_TICK_APICABLE	(1 << 5)
+#define DYN_TICK_TIMER_INT	(1 << 4)
+#define DYN_TICK_USE_APIC	(1 << 3)
+#define DYN_TICK_SKIPPING	(1 << 2)
+#define DYN_TICK_ENABLED	(1 << 1)
+#define DYN_TICK_SUITABLE	(1 << 0)
+
+#define NS_TICK_LEN		((1 * 1000000000) / HZ)
+#define DYN_TICK_MIN_SKIP	2
+
+struct dyn_tick_state {
+	unsigned int state;		/* Current state */
+	int skip_cpu;			/* Skip handling processor */
+	unsigned long skip;		/* Ticks to skip */
+	unsigned int max_skip;		/* Max number of ticks to skip */
+	unsigned long irq_skip_mask;	/* Do not update time from these irqs */
+	irqreturn_t (*interrupt)(int, void *, struct pt_regs *);
+};
+
+struct dyn_tick_timer {
+	int (*arch_init) (void);
+	void (*arch_enable) (void);
+	void (*arch_disable) (void);
+	void (*arch_reprogram_timer) (void);
+};
+
+extern struct dyn_tick_state *dyn_tick;
+extern void dyn_tick_register(struct dyn_tick_timer *new_timer);
+
+#ifdef CONFIG_NO_IDLE_HZ
+extern unsigned long dyn_tick_reprogram_timer(void);
+
+#define dyn_tick_enabled()		(dyn_tick->state & DYN_TICK_ENABLED)
+#else	/* CONFIG_NO_IDLE_HZ */
+#define arch_has_safe_halt()		0
+#define dyn_tick_reprogram_timer()	do {} while (0)
+#define dyn_tick_enabled()		0
+#endif	/* CONFIG_NO_IDLE_HZ */
+
+/* Pick up arch specific header */
+#include <asm/dyn-tick.h>
+
+#endif	/* _DYN_TICK_TIMER_H */
Index: linux-2.6.13-rc5-ck2/kernel/dyn-tick.c
===================================================================
--- linux-2.6.13-rc5-ck2.orig/kernel/dyn-tick.c	2005-01-12 16:19:45.000000000 +1100
+++ linux-2.6.13-rc5-ck2/kernel/dyn-tick.c	2005-08-05 21:02:44.000000000 +1000
@@ -0,0 +1,273 @@
+/*
+ * linux/kernel/dyn-tick.c
+ *
+ * Beginnings of generic dynamic tick timer support
+ *
+ * Copyright (C) 2004 Nokia Corporation
+ * Written by Tony Lindgen <tony@atomide.com> and
+ * Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/version.h>
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/sysdev.h>
+#include <linux/interrupt.h>
+#include <linux/cpumask.h>
+#include <linux/pm.h>
+#include <linux/dyn-tick.h>
+#include <asm/io.h>
+
+#include "io_ports.h"
+
+#define DYN_TICK_VERSION	"050610-1"
+#define DYN_TICK_IS_SET(x)	((dyn_tick->state & (x)) == (x))
+
+struct dyn_tick_state dyn_tick_state;
+struct dyn_tick_state *dyn_tick = &dyn_tick_state;
+struct dyn_tick_timer *dyn_tick_cfg;
+static cpumask_t dyn_cpu_map;
+
+/*
+ * Arch independent code needed to reprogram next timer interrupt.
+ * Gets called from cpu_idle() before entering idle loop. Note that
+ * we want to have all processors idle before reprogramming the
+ * next timer interrupt.
+ */
+unsigned long dyn_tick_reprogram_timer(void)
+{
+	int cpu;
+	unsigned long flags;
+	cpumask_t idle_cpus;
+	unsigned long next;
+
+	if (!DYN_TICK_IS_SET(DYN_TICK_ENABLED))
+		return 0;
+
+	/* Check if we are already skipping ticks and can idle other cpus */
+	if (DYN_TICK_IS_SET(DYN_TICK_SKIPPING)) {
+		if (cpu_has_local_apic())
+			reprogram_apic_timer(dyn_tick->skip);
+		return 0;
+	}
+
+	/* Check if we can start skipping ticks */
+	write_seqlock_irqsave(&xtime_lock, flags);
+	cpu = smp_processor_id();
+	cpu_set(cpu, dyn_cpu_map);
+	cpus_and(idle_cpus, dyn_cpu_map, cpu_online_map);
+	if (cpus_equal(idle_cpus, cpu_online_map)) {
+		next = next_timer_interrupt();
+		if (jiffies > next)
+			dyn_tick->skip = 1;
+		else
+			dyn_tick->skip = next_timer_interrupt() - jiffies;
+		if (dyn_tick->skip > DYN_TICK_MIN_SKIP) {
+			if (dyn_tick->skip > dyn_tick->max_skip)
+				dyn_tick->skip = dyn_tick->max_skip;
+
+			dyn_tick_cfg->arch_reprogram_timer();
+
+			dyn_tick->skip_cpu = cpu;
+			dyn_tick->state |= DYN_TICK_SKIPPING;
+		}
+		cpus_clear(dyn_cpu_map);
+	}
+	write_sequnlock_irqrestore(&xtime_lock, flags);
+
+	return dyn_tick->skip;
+}
+
+void __init dyn_tick_register(struct dyn_tick_timer *arch_timer)
+{
+	dyn_tick_cfg = arch_timer;
+	printk(KERN_INFO "dyn-tick: Registering dynamic tick timer v%s\n",
+	       DYN_TICK_VERSION);
+}
+
+/*
+ * ---------------------------------------------------------------------------
+ * Command line options
+ * ---------------------------------------------------------------------------
+ */
+static int __initdata dyntick_autoenable = 1;
+static int __initdata dyntick_useapic = 1;
+
+/*
+ * dyntick=[disable],[noapic]
+ */ 
+static int __init dyntick_setup(char *options)
+{
+	if (!options)
+		return 0;
+
+	if (!strncmp(options, "disable", 6))
+		dyntick_autoenable = 0;
+
+	if (strstr(options, "noapic"))
+		dyntick_useapic = 0;
+
+	return 0;
+}
+
+__setup("dyntick=", dyntick_setup);
+
+/*
+ * ---------------------------------------------------------------------------
+ * Sysfs interface
+ * ---------------------------------------------------------------------------
+ */
+
+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"
+		       "apic suitable:\t%i\n"
+		       "using APIC:\t%i\n",
+		       DYN_TICK_IS_SET(DYN_TICK_SUITABLE),
+		       DYN_TICK_IS_SET(DYN_TICK_ENABLED),
+		       DYN_TICK_IS_SET(DYN_TICK_APICABLE),
+		       DYN_TICK_IS_SET(DYN_TICK_USE_APIC));
+}
+
+static ssize_t show_dyn_tick_enable(struct sys_device *dev, char *buf)
+{
+	return sprintf(buf, "enabled:\t%i\n",
+		DYN_TICK_IS_SET(DYN_TICK_ENABLED));
+}
+
+static ssize_t set_dyn_tick_enable(struct sys_device *dev, const char *buf,
+				size_t count)
+{
+	unsigned long flags;
+	unsigned int enable = simple_strtoul(buf, NULL, 2);
+
+	write_seqlock_irqsave(&xtime_lock, flags);
+	if (enable) {
+		if (dyn_tick_cfg->arch_enable)
+			dyn_tick_cfg->arch_enable();
+		dyn_tick->state |= DYN_TICK_ENABLED;
+	} else {
+		if (dyn_tick_cfg->arch_disable)
+			dyn_tick_cfg->arch_disable();
+		dyn_tick->state &= ~DYN_TICK_ENABLED;
+	}
+	write_sequnlock_irqrestore(&xtime_lock, flags);
+
+	return count;
+}
+
+static ssize_t show_dyn_tick_useapic(struct sys_device *dev, char *buf)
+{
+	return sprintf(buf, "using APIC:\t%i\n",
+		       DYN_TICK_IS_SET(DYN_TICK_USE_APIC));
+}
+
+static ssize_t set_dyn_tick_useapic(struct sys_device *dev, const char *buf,
+				    size_t count)
+{
+	unsigned long flags;
+	unsigned int enable = simple_strtoul(buf, NULL, 2);
+
+	if (!DYN_TICK_IS_SET(DYN_TICK_APICABLE))
+		goto out;
+	write_seqlock_irqsave(&xtime_lock, flags);
+	if (enable)
+		dyn_tick->state |= DYN_TICK_USE_APIC;
+	else
+		dyn_tick->state &= ~DYN_TICK_USE_APIC;
+	write_sequnlock_irqrestore(&xtime_lock, flags);
+out:
+	return count;
+}
+
+static SYSDEV_ATTR(state, 0444, show_dyn_tick_state, NULL);
+static SYSDEV_ATTR(enable, 0644, show_dyn_tick_enable,
+		   set_dyn_tick_enable);
+static SYSDEV_ATTR(useapic, 0644, show_dyn_tick_useapic,
+		   set_dyn_tick_useapic);
+
+static struct sysdev_class dyn_tick_sysclass = {
+	set_kset_name("dyn_tick"),
+};
+
+static struct sys_device device_dyn_tick = {
+	.id = 0,
+	.cls = &dyn_tick_sysclass,
+};
+
+static int init_dyn_tick_sysfs(void)
+{
+	int error = 0;
+	if ((error = sysdev_class_register(&dyn_tick_sysclass)))
+		goto out;
+	if ((error = sysdev_register(&device_dyn_tick)))
+		goto out;
+	if ((error = sysdev_create_file(&device_dyn_tick, &attr_state)))
+		goto out;
+	if ((error = sysdev_create_file(&device_dyn_tick, &attr_enable)))
+		goto out;
+	error = sysdev_create_file(&device_dyn_tick, &attr_useapic);
+
+out:
+	return error;
+}
+
+device_initcall(init_dyn_tick_sysfs);
+
+/*
+ * ---------------------------------------------------------------------------
+ * Init functions
+ * ---------------------------------------------------------------------------
+ */
+
+static int __init dyn_tick_early_init(void)
+{
+	dyn_tick->state |= DYN_TICK_TIMER_INT;
+	return 0;
+}
+
+subsys_initcall(dyn_tick_early_init);
+
+/*
+ * We need to initialize dynamic tick after calibrate delay
+ */
+static int __init dyn_tick_late_init(void)
+{
+	int ret = 0;
+
+	if (dyn_tick_cfg == NULL || dyn_tick_cfg->arch_init == NULL ||
+	    !DYN_TICK_IS_SET(DYN_TICK_SUITABLE)) {
+		printk(KERN_ERR "dyn-tick: No suitable timer found\n");
+		return -ENODEV;
+	}
+
+	if (dyntick_apicable())
+		dyn_tick->state |= DYN_TICK_APICABLE;
+	if (!dyntick_useapic || !DYN_TICK_IS_SET(DYN_TICK_APICABLE))
+		dyn_tick->state &= ~DYN_TICK_USE_APIC;
+
+	if ((ret = dyn_tick_cfg->arch_init())) {
+		printk(KERN_ERR "dyn-tick: Init failed\n");
+		return -ENODEV;
+	}
+
+	if (!ret && dyntick_autoenable) {
+		dyn_tick->state |= DYN_TICK_ENABLED;
+		printk(KERN_INFO "dyn-tick: Timer using dynamic tick\n");
+	} else
+		printk(KERN_INFO "dyn-tick: Timer not enabled during boot\n");
+
+	return ret;
+}
+
+late_initcall(dyn_tick_late_init);
Index: linux-2.6.13-rc5-ck2/kernel/Makefile
===================================================================
--- linux-2.6.13-rc5-ck2.orig/kernel/Makefile	2005-08-05 20:41:44.000000000 +1000
+++ linux-2.6.13-rc5-ck2/kernel/Makefile	2005-08-05 20:42:18.000000000 +1000
@@ -30,6 +30,7 @@ obj-$(CONFIG_SYSFS) += ksysfs.o
 obj-$(CONFIG_GENERIC_HARDIRQS) += irq/
 obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
 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 <alan@linuxcare.com.au>, the -fno-omit-frame-pointer is

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

* Re: [PATCH] i386 No-Idle-Hz aka Dynamic-Ticks 4
  2005-08-05 16:39     ` [PATCH] i386 No-Idle-Hz aka Dynamic-Ticks 4 Con Kolivas
@ 2005-08-06 17:47       ` Adrian Bunk
  2005-08-07  5:12         ` [PATCH] i386 No-Idle-Hz aka Dynamic-Ticks 5 Con Kolivas
  0 siblings, 1 reply; 68+ messages in thread
From: Adrian Bunk @ 2005-08-06 17:47 UTC (permalink / raw)
  To: Con Kolivas
  Cc: linux-kernel, vatsa, ck, tony, tuukka.tikkanen, george,
	Andrew Morton

On Sat, Aug 06, 2005 at 02:39:40AM +1000, Con Kolivas wrote:

> Here's my most current version of the dynamic ticks patch for i386 with some 
> more minor cleanups already discussed and cosmetic changes ( also available 
> at http://ck.kolivas.org/patches/dyn-ticks/ ).
> 
> Cheers,
> Con
>...
> --- linux-2.6.13-rc5-ck2.orig/arch/i386/kernel/dyn-tick.c	2005-01-12 16:19:45.000000000 +1100
> +++ linux-2.6.13-rc5-ck2/arch/i386/kernel/dyn-tick.c	2005-08-05 20:48:57.000000000 +1000
>...
> +void arch_reprogram_timer(void)
> +{

static?

>...
> +int __init dyn_tick_init(void)
> +{

static?

>...
> +irqreturn_t dyn_tick_timer_interrupt(int irq, void *dev_id,
> +				     struct pt_regs *regs)
> +{

static?

>...
> +int __init dyn_tick_arch_init(void)
> +{

static?

>...
> +/* Functions that need blank prototypes for !CONFIG_NO_IDLE_HZ below here */
> +inline void set_dyn_tick_max_skip(u32 apic_timer_val)
> +{
> +	dyn_tick->max_skip = 0xffffff / apic_timer_val;
> +}
> +
> +inline void setup_dyn_tick_use_apic(unsigned int calibration_result)
> +{
> +	if (calibration_result)
> +		dyn_tick->state |= DYN_TICK_USE_APIC;
> +	else
> +		printk(KERN_INFO "dyn-tick: Cannot use local APIC\n");
> +}

You can drop the "inline" on both functions (it doesn't make any 
practical difference since they are only called from other files).

>...
> --- linux-2.6.13-rc5-ck2.orig/include/asm-i386/dyn-tick.h	2005-01-12 16:19:45.000000000 +1100
> +++ linux-2.6.13-rc5-ck2/include/asm-i386/dyn-tick.h	2005-08-05 20:57:02.000000000 +1000
>...
> +#if defined(CONFIG_DYN_TICK_USE_APIC) && \
> +	(defined(CONFIG_SMP) || defined(CONFIG_X86_UP_APIC))
> +#define cpu_has_local_apic()	(dyn_tick->state & DYN_TICK_USE_APIC)
> +#else
> +#define cpu_has_local_apic()	0
> +#endif
> +
> +#if defined(CONFIG_DYN_TICK_USE_APIC)
> +#define dyntick_apicable()	1
> +#else
> +#define dyntick_apicable()	0
> +#endif

Constants that mimic functions aren't good coding style.

Please make them either uppercase #define's without function braces or 
"static inline" functions.

>...
> --- linux-2.6.13-rc5-ck2.orig/kernel/dyn-tick.c	2005-01-12 16:19:45.000000000 +1100
> +++ linux-2.6.13-rc5-ck2/kernel/dyn-tick.c	2005-08-05 21:02:44.000000000 +1000
>...
> +struct dyn_tick_state dyn_tick_state;

static?

>...
> +struct dyn_tick_timer *dyn_tick_cfg;
>...

static?


cu
Adrian

-- 

       "Is there not promise of rain?" Ling Tan asked suddenly out
        of the darkness. There had been need of rain for many days.
       "Only a promise," Lao Er said.
                                       Pearl S. Buck - Dragon Seed


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

* [PATCH] i386 No-Idle-Hz aka Dynamic-Ticks 5
  2005-08-06 17:47       ` Adrian Bunk
@ 2005-08-07  5:12         ` Con Kolivas
  2005-08-07 16:58           ` Srivatsa Vaddagiri
  2005-08-08 15:08           ` Folkert van Heusden
  0 siblings, 2 replies; 68+ messages in thread
From: Con Kolivas @ 2005-08-07  5:12 UTC (permalink / raw)
  To: Adrian Bunk
  Cc: linux-kernel, vatsa, ck, tony, tuukka.tikkanen, george,
	Andrew Morton

[-- Attachment #1: Type: text/plain, Size: 147 bytes --]

Respin of the dynamic ticks patch for i386 by Tony Lindgen and Tuukka Tikkanen 
with further code cleanups. Are were there yet?

Cheers,
Con
---



[-- Attachment #2: 2.6.13-rc5-dtck-5.patch --]
[-- Type: text/x-diff, Size: 31506 bytes --]

This is the dynamic ticks patch for i386 as written by Tony Lindgen 
<tony@atomide.com> and Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>,
and modified by Con Kolivas <kernel@kolivas.org>.

Signed-off-by: Con Kolivas <kernel@kolivas.org>

 arch/i386/Kconfig                   |   35 ++++
 arch/i386/kernel/Makefile           |    1
 arch/i386/kernel/apic.c             |   19 ++
 arch/i386/kernel/dyn-tick.c         |  150 +++++++++++++++++++
 arch/i386/kernel/irq.c              |    3
 arch/i386/kernel/process.c          |    3
 arch/i386/kernel/time.c             |    8 -
 arch/i386/kernel/timers/timer_pit.c |   38 +++++
 arch/i386/kernel/timers/timer_pm.c  |    4
 arch/i386/kernel/timers/timer_tsc.c |   29 ++-
 arch/i386/mach-default/setup.c      |   16 ++
 include/asm-i386/dyn-tick.h         |   93 ++++++++++++
 include/linux/dyn-tick.h            |   75 +++++++++
 kernel/Makefile                     |    1
 kernel/dyn-tick.c                   |  273 ++++++++++++++++++++++++++++++++++++
 15 files changed, 736 insertions(+), 12 deletions(-)

Index: linux-2.6.13-rc5-ck2/arch/i386/Kconfig
===================================================================
--- linux-2.6.13-rc5-ck2.orig/arch/i386/Kconfig	2005-08-07 13:07:12.000000000 +1000
+++ linux-2.6.13-rc5-ck2/arch/i386/Kconfig	2005-08-07 13:07:45.000000000 +1000
@@ -457,6 +457,41 @@ config HPET_EMULATE_RTC
 	bool "Provide RTC interrupt"
 	depends on HPET_TIMER && RTC=y
 
+config NO_IDLE_HZ
+	bool "Dynamic Tick Timer - Skip timer ticks during idle"
+	depends on EXPERIMENTAL
+	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 can disable dynamic tick timer either by
+	  passing dyntick=disable command line option, or via sysfs:
+
+	  # echo 0 > /sys/devices/system/dyn_tick/dyn_tick0/enable
+
+config DYN_TICK_USE_APIC
+	bool "Use APIC timer instead of PIT timer"
+	depends on NO_IDLE_HZ
+	help
+	  This option enables using APIC timer interrupt if your hardware
+	  supports it. APIC timer allows longer sleep periods compared
+	  to PIT timer, however on MOST recent hardware disabling the PIT
+	  timer also disables APIC timer interrupts, and the system won't
+	  run properly. Symptoms include slow system boot, and time running 
+	  slow.
+
+	  If unsure, do NOT enable this option.
+
+	  Note that you can disable apic usage by dynamic tick timer
+	  either by passing dyntick=noapic command line option, or via 
+	  sysfs:
+
+	  # echo 0 > /sys/devices/system/dyn_tick/dyn_tick0/useapic
+
 config SMP
 	bool "Symmetric multi-processing support"
 	---help---
Index: linux-2.6.13-rc5-ck2/arch/i386/kernel/apic.c
===================================================================
--- linux-2.6.13-rc5-ck2.orig/arch/i386/kernel/apic.c	2005-08-07 13:07:12.000000000 +1000
+++ linux-2.6.13-rc5-ck2/arch/i386/kernel/apic.c	2005-08-07 13:07:45.000000000 +1000
@@ -27,6 +27,7 @@
 #include <linux/kernel_stat.h>
 #include <linux/sysdev.h>
 #include <linux/cpu.h>
+#include <linux/dyn-tick.h>
 
 #include <asm/atomic.h>
 #include <asm/smp.h>
@@ -931,6 +932,8 @@ void (*wait_timer_tick)(void) __devinitd
 
 #define APIC_DIVISOR 16
 
+u32 apic_timer_val;
+
 static void __setup_APIC_LVTT(unsigned int clocks)
 {
 	unsigned int lvtt_value, tmp_value, ver;
@@ -949,7 +952,12 @@ static void __setup_APIC_LVTT(unsigned i
 				& ~(APIC_TDR_DIV_1 | APIC_TDR_DIV_TMBASE))
 				| APIC_TDR_DIV_16);
 
-	apic_write_around(APIC_TMICT, clocks/APIC_DIVISOR);
+	apic_timer_val = clocks / APIC_DIVISOR;
+
+	if (apic_timer_val)
+		set_dyn_tick_max_skip(apic_timer_val);
+
+	apic_write_around(APIC_TMICT, apic_timer_val);
 }
 
 static void __devinit setup_APIC_timer(unsigned int clocks)
@@ -1062,6 +1070,8 @@ void __init setup_boot_APIC_clock(void)
 	 */
 	setup_APIC_timer(calibration_result);
 
+	setup_dyn_tick_use_apic(calibration_result);
+
 	local_irq_enable();
 }
 
@@ -1200,6 +1210,13 @@ fastcall void smp_apic_timer_interrupt(s
 	 * interrupt lock, which is the WrongThing (tm) to do.
 	 */
 	irq_enter();
+
+	/*
+	 * Check if we need to wake up PIT interrupt handler.
+	 * Otherwise just wake up local APIC timer.
+	 */
+	wakeup_pit_or_apic(cpu, regs);
+
 	smp_local_timer_interrupt(regs);
 	irq_exit();
 }
Index: linux-2.6.13-rc5-ck2/arch/i386/kernel/dyn-tick.c
===================================================================
--- linux-2.6.13-rc5-ck2.orig/arch/i386/kernel/dyn-tick.c	2005-01-12 16:19:45.000000000 +1100
+++ linux-2.6.13-rc5-ck2/arch/i386/kernel/dyn-tick.c	2005-08-07 14:41:00.000000000 +1000
@@ -0,0 +1,150 @@
+/*
+ * linux/arch/i386/kernel/dyn-tick.c
+ *
+ * Copyright (C) 2004 Nokia Corporation
+ * Written by Tony Lindgen <tony@atomide.com> and
+ * Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/version.h>
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/dyn-tick.h>
+#include <asm/apic.h>
+
+static void arch_reprogram_timer(void)
+{
+	if (cpu_has_local_apic()) {
+		disable_pit_timer();
+		if (dyn_tick->state & DYN_TICK_TIMER_INT)
+			reprogram_apic_timer(dyn_tick->skip);
+	} else {
+		if (dyn_tick->state & DYN_TICK_TIMER_INT)
+			reprogram_pit_timer(dyn_tick->skip);
+		else
+			disable_pit_timer();
+	}
+}
+
+static struct dyn_tick_timer arch_dyn_tick_timer = {
+	.arch_reprogram_timer	= &arch_reprogram_timer,
+};
+
+static int __init dyn_tick_init(void)
+{
+	arch_dyn_tick_timer.arch_init = dyn_tick_arch_init;
+	dyn_tick_register(&arch_dyn_tick_timer);
+
+	return 0;
+}
+
+arch_initcall(dyn_tick_init);
+
+static unsigned long long last_tick;
+
+/*
+ * This interrupt handler updates the time based on number of jiffies skipped
+ * It would be somewhat more optimized to have a custom handler in each timer
+ * using hardware ticks instead of nanoseconds. Note that CONFIG_NO_IDLE_HZ
+ * currently disables timer fallback on skipped jiffies.
+ */
+static irqreturn_t dyn_tick_timer_interrupt(int irq, void *dev_id,
+				     struct pt_regs *regs)
+{
+	unsigned long flags;
+	volatile unsigned long long now;
+	unsigned int skipped = 0;
+
+	write_seqlock_irqsave(&xtime_lock, flags);
+	now = cur_timer->monotonic_clock();
+	while (now - last_tick >= NS_TICK_LEN) {
+		last_tick += NS_TICK_LEN;
+		cur_timer->mark_offset();
+		do_timer_interrupt(irq, NULL, regs);
+		skipped++;
+	}
+	if (dyn_tick->state & (DYN_TICK_ENABLED | DYN_TICK_SKIPPING)) {
+		dyn_tick->skip = 1;
+		if (cpu_has_local_apic())
+			reprogram_apic_timer(dyn_tick->skip);
+		reprogram_pit_timer(dyn_tick->skip);
+		dyn_tick->state |= DYN_TICK_ENABLED;
+		dyn_tick->state &= ~DYN_TICK_SKIPPING;
+	}
+	write_sequnlock_irqrestore(&xtime_lock, flags);
+
+	return IRQ_HANDLED;
+}
+
+int __init dyn_tick_arch_init(void)
+{
+	unsigned long flags;
+
+	write_seqlock_irqsave(&xtime_lock, flags);
+	last_tick = cur_timer->monotonic_clock();
+	dyn_tick->skip = 1;
+	if (!(dyn_tick->state & DYN_TICK_USE_APIC) || !cpu_has_local_apic())
+		dyn_tick->max_skip = 0xffff / LATCH;	/* PIT timer length */
+	printk(KERN_INFO "dyn-tick: Maximum ticks to skip limited to %i\n",
+	       dyn_tick->max_skip);
+	write_sequnlock_irqrestore(&xtime_lock, flags);
+
+	dyn_tick->interrupt = dyn_tick_timer_interrupt;
+	replace_timer_interrupt(dyn_tick->interrupt);
+
+	return 0;
+}
+
+/* Functions that need blank prototypes for !CONFIG_NO_IDLE_HZ below here */
+void set_dyn_tick_max_skip(u32 apic_timer_val)
+{
+	dyn_tick->max_skip = 0xffffff / apic_timer_val;
+}
+
+void setup_dyn_tick_use_apic(unsigned int calibration_result)
+{
+	if (calibration_result)
+		dyn_tick->state |= DYN_TICK_USE_APIC;
+	else
+		printk(KERN_INFO "dyn-tick: Cannot use local APIC\n");
+}
+
+void wakeup_pit_or_apic(int cpu, struct pt_regs *regs)
+{
+	unsigned long seq; 
+
+	do {
+		seq = read_seqbegin(&xtime_lock);
+		if (dyn_tick->state & (DYN_TICK_ENABLED | DYN_TICK_SKIPPING)) {
+			if (dyn_tick->skip_cpu == cpu &&
+				dyn_tick->skip > DYN_TICK_MIN_SKIP)
+					dyn_tick->interrupt(99, NULL, regs);
+				else
+					reprogram_apic_timer(1);
+		}
+	} while (read_seqretry(&xtime_lock, seq));
+}
+
+void dyn_tick_interrupt(int irq, struct pt_regs *regs)
+{
+	if (dyn_tick->state & (DYN_TICK_ENABLED | DYN_TICK_SKIPPING) && irq)
+		dyn_tick->interrupt(irq, NULL, regs);
+}
+
+void dyn_tick_time_init(struct timer_opts *cur_timer)
+{
+	if (strncmp(cur_timer->name, "tsc", 3) == 0 ||
+	    strncmp(cur_timer->name, "pmtmr", 3) == 0) {
+		dyn_tick->state |= DYN_TICK_SUITABLE;
+		printk(KERN_INFO "dyn-tick: Found suitable timer: %s\n",
+		       cur_timer->name);
+	} else
+		printk(KERN_ERR "dyn-tick: Cannot use timer %s\n",
+		       cur_timer->name);
+}
Index: linux-2.6.13-rc5-ck2/arch/i386/kernel/irq.c
===================================================================
--- linux-2.6.13-rc5-ck2.orig/arch/i386/kernel/irq.c	2005-08-07 13:07:12.000000000 +1000
+++ linux-2.6.13-rc5-ck2/arch/i386/kernel/irq.c	2005-08-07 13:07:45.000000000 +1000
@@ -18,6 +18,7 @@
 #include <linux/notifier.h>
 #include <linux/cpu.h>
 #include <linux/delay.h>
+#include <linux/dyn-tick.h>
 
 DEFINE_PER_CPU(irq_cpustat_t, irq_stat) ____cacheline_maxaligned_in_smp;
 EXPORT_PER_CPU_SYMBOL(irq_stat);
@@ -76,6 +77,8 @@ fastcall unsigned int do_IRQ(struct pt_r
 	}
 #endif
 
+	dyn_tick_interrupt(irq, regs);
+
 #ifdef CONFIG_4KSTACKS
 
 	curctx = (union irq_ctx *) current_thread_info();
Index: linux-2.6.13-rc5-ck2/arch/i386/kernel/Makefile
===================================================================
--- linux-2.6.13-rc5-ck2.orig/arch/i386/kernel/Makefile	2005-08-07 13:07:12.000000000 +1000
+++ linux-2.6.13-rc5-ck2/arch/i386/kernel/Makefile	2005-08-07 13:07:45.000000000 +1000
@@ -32,6 +32,7 @@ obj-$(CONFIG_MODULES)		+= module.o
 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
 
Index: linux-2.6.13-rc5-ck2/arch/i386/kernel/process.c
===================================================================
--- linux-2.6.13-rc5-ck2.orig/arch/i386/kernel/process.c	2005-08-07 13:07:12.000000000 +1000
+++ linux-2.6.13-rc5-ck2/arch/i386/kernel/process.c	2005-08-07 13:07:45.000000000 +1000
@@ -39,6 +39,7 @@
 #include <linux/ptrace.h>
 #include <linux/random.h>
 #include <linux/kprobes.h>
+#include <linux/dyn-tick.h>
 
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
@@ -200,6 +201,8 @@ void cpu_idle(void)
 			if (cpu_is_offline(cpu))
 				play_dead();
 
+			dyn_tick_reprogram_timer();
+
 			__get_cpu_var(irq_stat).idle_timestamp = jiffies;
 			idle();
 		}
Index: linux-2.6.13-rc5-ck2/arch/i386/kernel/time.c
===================================================================
--- linux-2.6.13-rc5-ck2.orig/arch/i386/kernel/time.c	2005-08-07 13:07:12.000000000 +1000
+++ linux-2.6.13-rc5-ck2/arch/i386/kernel/time.c	2005-08-07 13:07:45.000000000 +1000
@@ -46,6 +46,7 @@
 #include <linux/bcd.h>
 #include <linux/efi.h>
 #include <linux/mca.h>
+#include <linux/dyn-tick.h>
 
 #include <asm/io.h>
 #include <asm/smp.h>
@@ -252,8 +253,7 @@ EXPORT_SYMBOL(profile_pc);
  * timer_interrupt() needs to keep up the real-time clock,
  * as well as call the "do_timer()" routine every clocktick
  */
-static inline void do_timer_interrupt(int irq, void *dev_id,
-					struct pt_regs *regs)
+void do_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
 #ifdef CONFIG_X86_IO_APIC
 	if (timer_ack) {
@@ -423,7 +423,7 @@ static struct sysdev_class timer_sysclas
 
 
 /* XXX this driverfs stuff should probably go elsewhere later -john */
-static struct sys_device device_timer = {
+struct sys_device device_timer = {
 	.id	= 0,
 	.cls	= &timer_sysclass,
 };
@@ -479,5 +479,7 @@ void __init time_init(void)
 	cur_timer = select_timer();
 	printk(KERN_INFO "Using %s for high-res timesource\n",cur_timer->name);
 
+	dyn_tick_time_init(cur_timer);
+
 	time_init_hook();
 }
Index: linux-2.6.13-rc5-ck2/arch/i386/kernel/timers/timer_pit.c
===================================================================
--- linux-2.6.13-rc5-ck2.orig/arch/i386/kernel/timers/timer_pit.c	2005-08-07 13:07:12.000000000 +1000
+++ linux-2.6.13-rc5-ck2/arch/i386/kernel/timers/timer_pit.c	2005-08-07 13:07:45.000000000 +1000
@@ -148,6 +148,44 @@ static unsigned long get_offset_pit(void
 	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 = {
Index: linux-2.6.13-rc5-ck2/arch/i386/kernel/timers/timer_pm.c
===================================================================
--- linux-2.6.13-rc5-ck2.orig/arch/i386/kernel/timers/timer_pm.c	2005-08-07 13:07:12.000000000 +1000
+++ linux-2.6.13-rc5-ck2/arch/i386/kernel/timers/timer_pm.c	2005-08-07 13:07:45.000000000 +1000
@@ -15,6 +15,7 @@
 #include <linux/module.h>
 #include <linux/device.h>
 #include <linux/init.h>
+#include <linux/dyn-tick.h>
 #include <asm/types.h>
 #include <asm/timer.h>
 #include <asm/smp.h>
@@ -168,6 +169,9 @@ static void mark_offset_pmtmr(void)
 	monotonic_base += delta * NSEC_PER_USEC;
 	write_sequnlock(&monotonic_lock);
 
+	if (dyn_tick_enabled())
+		return;
+
 	/* convert to ticks */
 	delta += offset_delay;
 	lost = delta / (USEC_PER_SEC / HZ);
Index: linux-2.6.13-rc5-ck2/arch/i386/kernel/timers/timer_tsc.c
===================================================================
--- linux-2.6.13-rc5-ck2.orig/arch/i386/kernel/timers/timer_tsc.c	2005-08-07 13:07:12.000000000 +1000
+++ linux-2.6.13-rc5-ck2/arch/i386/kernel/timers/timer_tsc.c	2005-08-07 13:07:45.000000000 +1000
@@ -14,6 +14,7 @@
 #include <linux/cpufreq.h>
 #include <linux/string.h>
 #include <linux/jiffies.h>
+#include <linux/dyn-tick.h>
 
 #include <asm/timer.h>
 #include <asm/io.h>
@@ -166,10 +167,19 @@ static void delay_tsc(unsigned long loop
 	} while ((now-bclock) < loops);
 }
 
+/* update the monotonic base value */
+static inline void update_monotonic_base(unsigned long long last_offset)
+{
+	unsigned long long this_offset;
+
+	this_offset = ((unsigned long long)last_tsc_high << 32) | last_tsc_low;
+	monotonic_base += cycles_2_ns(this_offset - last_offset);
+}
+
 #ifdef CONFIG_HPET_TIMER
 static void mark_offset_tsc_hpet(void)
 {
-	unsigned long long this_offset, last_offset;
+	unsigned long long last_offset;
  	unsigned long offset, temp, hpet_current;
 
 	write_seqlock(&monotonic_lock);
@@ -197,9 +207,7 @@ static void mark_offset_tsc_hpet(void)
 	}
 	hpet_last = hpet_current;
 
-	/* 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);
+	update_monotonic_base(last_offset);
 	write_sequnlock(&monotonic_lock);
 
 	/* calculate delay_at_last_interrupt */
@@ -346,7 +354,7 @@ static void mark_offset_tsc(void)
 	int count;
 	int countmp;
 	static int count1 = 0;
-	unsigned long long this_offset, last_offset;
+	unsigned long long last_offset;
 	static int lost_count = 0;
 
 	write_seqlock(&monotonic_lock);
@@ -367,6 +375,12 @@ static void mark_offset_tsc(void)
 
 	rdtsc(last_tsc_low, last_tsc_high);
 
+	if (dyn_tick_enabled()) {
+		update_monotonic_base(last_offset);
+		write_sequnlock(&monotonic_lock);
+		return;
+	}
+
 	spin_lock(&i8253_lock);
 	outb_p(0x00, PIT_MODE);     /* latch the count ASAP */
 
@@ -434,9 +448,8 @@ static void mark_offset_tsc(void)
 			cpufreq_delayed_get();
 	} else
 		lost_count = 0;
-	/* 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);
+
+	update_monotonic_base(last_offset);
 	write_sequnlock(&monotonic_lock);
 
 	/* calculate delay_at_last_interrupt */
Index: linux-2.6.13-rc5-ck2/arch/i386/mach-default/setup.c
===================================================================
--- linux-2.6.13-rc5-ck2.orig/arch/i386/mach-default/setup.c	2005-08-07 13:07:12.000000000 +1000
+++ linux-2.6.13-rc5-ck2/arch/i386/mach-default/setup.c	2005-08-07 13:07:45.000000000 +1000
@@ -93,6 +93,22 @@ void __init time_init_hook(void)
 	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
Index: linux-2.6.13-rc5-ck2/include/asm-i386/dyn-tick.h
===================================================================
--- linux-2.6.13-rc5-ck2.orig/include/asm-i386/dyn-tick.h	2005-01-12 16:19:45.000000000 +1100
+++ linux-2.6.13-rc5-ck2/include/asm-i386/dyn-tick.h	2005-08-07 14:47:00.000000000 +1000
@@ -0,0 +1,93 @@
+/*
+ * linux/include/asm-i386/dyn-tick.h
+ *
+ * Copyright (C) 2004 Nokia Corporation
+ * Written by Tony Lindgen <tony@atomide.com> and
+ * Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef _ASM_I386_DYN_TICK_H_
+#define _ASM_I386_DYN_TICK_H_
+
+#include <asm/apic.h>
+
+#ifdef CONFIG_NO_IDLE_HZ
+extern int dyn_tick_arch_init(void);
+extern void disable_pit_timer(void);
+extern void reprogram_pit_timer(int jiffies_to_skip);
+extern void replace_timer_interrupt(void *new_handler);
+extern void set_dyn_tick_max_skip(u32 apic_timer_val);
+extern void setup_dyn_tick_use_apic(unsigned int calibration_result);
+extern void wakeup_pit_or_apic(int cpu, struct pt_regs *regs);
+extern void dyn_tick_interrupt(int irq, struct pt_regs *regs);
+extern void dyn_tick_time_init(struct timer_opts *cur_timer);
+extern void do_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+extern u32 apic_timer_val;
+
+#if defined(CONFIG_DYN_TICK_USE_APIC)
+#define DYNTICK_APICABLE	1
+
+#if (defined(CONFIG_SMP) || defined(CONFIG_X86_UP_APIC))
+static inline int cpu_has_local_apic(void)
+{
+	return (dyn_tick->state & DYN_TICK_USE_APIC);
+}
+
+#else	/* (defined(CONFIG_SMP) || defined(CONFIG_X86_UP_APIC)) */
+static inline int cpu_has_local_apic(void)
+{
+	return 0;
+}
+#endif	/* (defined(CONFIG_SMP) || defined(CONFIG_X86_UP_APIC)) */
+
+#else	/*  defined(CONFIG_DYN_TICK_USE_APIC) */
+#define DYNTICK_APICABLE	0
+static inline int cpu_has_local_apic(void)
+{
+	return 0;
+}
+#endif	/*  defined(CONFIG_DYN_TICK_USE_APIC) */
+
+static inline void reprogram_apic_timer(unsigned int count)
+{
+#ifdef CONFIG_X86_LOCAL_APIC
+	unsigned long flags;
+
+	count *= apic_timer_val;
+	local_irq_save(flags);
+	apic_write_around(APIC_TMICT, count);
+	local_irq_restore(flags);
+#endif	/* CONFIG_X86_LOCAL_APIC */
+}
+
+#else /* CONFIG_NO_IDLE_HZ */
+static inline void set_dyn_tick_max_skip(u32 apic_timer_val)
+{
+}
+
+static inline void reprogram_apic_timer(unsigned int count)
+{
+}
+
+static inline void setup_dyn_tick_use_apic(unsigned int calibration_result)
+{
+}
+
+static inline void wakeup_pit_or_apic(int cpu, struct pt_regs *regs)
+{
+}
+
+static inline void dyn_tick_interrupt(int irq, struct pt_regs *regs)
+{
+}
+
+static inline void dyn_tick_time_init(struct timer_opts *cur_timer)
+{
+}
+#endif /* CONFIG_NO_IDLE_HZ */
+
+#endif /* _ASM_I386_DYN_TICK_H_ */
Index: linux-2.6.13-rc5-ck2/include/linux/dyn-tick.h
===================================================================
--- linux-2.6.13-rc5-ck2.orig/include/linux/dyn-tick.h	2005-01-12 16:19:45.000000000 +1100
+++ linux-2.6.13-rc5-ck2/include/linux/dyn-tick.h	2005-08-07 14:55:46.000000000 +1000
@@ -0,0 +1,75 @@
+/*
+ * linux/include/linux/dyn-tick.h
+ *
+ * Copyright (C) 2004 Nokia Corporation
+ * Written by Tony Lindgen <tony@atomide.com> and
+ * Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef _DYN_TICK_TIMER_H
+#define _DYN_TICK_TIMER_H
+
+#include <linux/interrupt.h>
+#include <asm/timer.h>
+
+#define DYN_TICK_APICABLE	(1 << 5)
+#define DYN_TICK_TIMER_INT	(1 << 4)
+#define DYN_TICK_USE_APIC	(1 << 3)
+#define DYN_TICK_SKIPPING	(1 << 2)
+#define DYN_TICK_ENABLED	(1 << 1)
+#define DYN_TICK_SUITABLE	(1 << 0)
+
+#define NS_TICK_LEN		((1 * 1000000000) / HZ)
+#define DYN_TICK_MIN_SKIP	2
+
+struct dyn_tick_state {
+	unsigned int state;		/* Current state */
+	int skip_cpu;			/* Skip handling processor */
+	unsigned long skip;		/* Ticks to skip */
+	unsigned int max_skip;		/* Max number of ticks to skip */
+	unsigned long irq_skip_mask;	/* Do not update time from these irqs */
+	irqreturn_t (*interrupt)(int, void *, struct pt_regs *);
+};
+
+struct dyn_tick_timer {
+	int (*arch_init) (void);
+	void (*arch_enable) (void);
+	void (*arch_disable) (void);
+	void (*arch_reprogram_timer) (void);
+};
+
+extern struct dyn_tick_state *dyn_tick;
+extern void dyn_tick_register(struct dyn_tick_timer *new_timer);
+
+#ifdef CONFIG_NO_IDLE_HZ
+extern unsigned long dyn_tick_reprogram_timer(void);
+
+static inline int dyn_tick_enabled(void)
+{
+	return (dyn_tick->state & DYN_TICK_ENABLED);
+}
+
+#else	/* CONFIG_NO_IDLE_HZ */
+static inline int arch_has_safe_halt(void)
+{
+	return 0;
+}
+
+static inline void dyn_tick_reprogram_timer(void)
+{
+}
+
+static inline int dyn_tick_enabled(void)
+{
+	return 0;
+}
+#endif	/* CONFIG_NO_IDLE_HZ */
+
+/* Pick up arch specific header */
+#include <asm/dyn-tick.h>
+
+#endif	/* _DYN_TICK_TIMER_H */
Index: linux-2.6.13-rc5-ck2/kernel/dyn-tick.c
===================================================================
--- linux-2.6.13-rc5-ck2.orig/kernel/dyn-tick.c	2005-01-12 16:19:45.000000000 +1100
+++ linux-2.6.13-rc5-ck2/kernel/dyn-tick.c	2005-08-07 14:48:37.000000000 +1000
@@ -0,0 +1,273 @@
+/*
+ * linux/kernel/dyn-tick.c
+ *
+ * Beginnings of generic dynamic tick timer support
+ *
+ * Copyright (C) 2004 Nokia Corporation
+ * Written by Tony Lindgen <tony@atomide.com> and
+ * Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/version.h>
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/sysdev.h>
+#include <linux/interrupt.h>
+#include <linux/cpumask.h>
+#include <linux/pm.h>
+#include <linux/dyn-tick.h>
+#include <asm/io.h>
+
+#include "io_ports.h"
+
+#define DYN_TICK_VERSION	"050610-1"
+#define DYN_TICK_IS_SET(x)	((dyn_tick->state & (x)) == (x))
+
+static struct dyn_tick_state dyn_tick_state;
+struct dyn_tick_state *dyn_tick = &dyn_tick_state;
+static struct dyn_tick_timer *dyn_tick_cfg;
+static cpumask_t dyn_cpu_map;
+
+/*
+ * Arch independent code needed to reprogram next timer interrupt.
+ * Gets called from cpu_idle() before entering idle loop. Note that
+ * we want to have all processors idle before reprogramming the
+ * next timer interrupt.
+ */
+unsigned long dyn_tick_reprogram_timer(void)
+{
+	int cpu;
+	unsigned long flags;
+	cpumask_t idle_cpus;
+	unsigned long next;
+
+	if (!DYN_TICK_IS_SET(DYN_TICK_ENABLED))
+		return 0;
+
+	/* Check if we are already skipping ticks and can idle other cpus */
+	if (DYN_TICK_IS_SET(DYN_TICK_SKIPPING)) {
+		if (cpu_has_local_apic())
+			reprogram_apic_timer(dyn_tick->skip);
+		return 0;
+	}
+
+	/* Check if we can start skipping ticks */
+	write_seqlock_irqsave(&xtime_lock, flags);
+	cpu = smp_processor_id();
+	cpu_set(cpu, dyn_cpu_map);
+	cpus_and(idle_cpus, dyn_cpu_map, cpu_online_map);
+	if (cpus_equal(idle_cpus, cpu_online_map)) {
+		next = next_timer_interrupt();
+		if (jiffies > next)
+			dyn_tick->skip = 1;
+		else
+			dyn_tick->skip = next_timer_interrupt() - jiffies;
+		if (dyn_tick->skip > DYN_TICK_MIN_SKIP) {
+			if (dyn_tick->skip > dyn_tick->max_skip)
+				dyn_tick->skip = dyn_tick->max_skip;
+
+			dyn_tick_cfg->arch_reprogram_timer();
+
+			dyn_tick->skip_cpu = cpu;
+			dyn_tick->state |= DYN_TICK_SKIPPING;
+		}
+		cpus_clear(dyn_cpu_map);
+	}
+	write_sequnlock_irqrestore(&xtime_lock, flags);
+
+	return dyn_tick->skip;
+}
+
+void __init dyn_tick_register(struct dyn_tick_timer *arch_timer)
+{
+	dyn_tick_cfg = arch_timer;
+	printk(KERN_INFO "dyn-tick: Registering dynamic tick timer v%s\n",
+	       DYN_TICK_VERSION);
+}
+
+/*
+ * ---------------------------------------------------------------------------
+ * Command line options
+ * ---------------------------------------------------------------------------
+ */
+static int __initdata dyntick_autoenable = 1;
+static int __initdata dyntick_useapic = 1;
+
+/*
+ * dyntick=[disable],[noapic]
+ */ 
+static int __init dyntick_setup(char *options)
+{
+	if (!options)
+		return 0;
+
+	if (!strncmp(options, "disable", 6))
+		dyntick_autoenable = 0;
+
+	if (strstr(options, "noapic"))
+		dyntick_useapic = 0;
+
+	return 0;
+}
+
+__setup("dyntick=", dyntick_setup);
+
+/*
+ * ---------------------------------------------------------------------------
+ * Sysfs interface
+ * ---------------------------------------------------------------------------
+ */
+
+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"
+		       "apic suitable:\t%i\n"
+		       "using APIC:\t%i\n",
+		       DYN_TICK_IS_SET(DYN_TICK_SUITABLE),
+		       DYN_TICK_IS_SET(DYN_TICK_ENABLED),
+		       DYN_TICK_IS_SET(DYN_TICK_APICABLE),
+		       DYN_TICK_IS_SET(DYN_TICK_USE_APIC));
+}
+
+static ssize_t show_dyn_tick_enable(struct sys_device *dev, char *buf)
+{
+	return sprintf(buf, "enabled:\t%i\n",
+		DYN_TICK_IS_SET(DYN_TICK_ENABLED));
+}
+
+static ssize_t set_dyn_tick_enable(struct sys_device *dev, const char *buf,
+				size_t count)
+{
+	unsigned long flags;
+	unsigned int enable = simple_strtoul(buf, NULL, 2);
+
+	write_seqlock_irqsave(&xtime_lock, flags);
+	if (enable) {
+		if (dyn_tick_cfg->arch_enable)
+			dyn_tick_cfg->arch_enable();
+		dyn_tick->state |= DYN_TICK_ENABLED;
+	} else {
+		if (dyn_tick_cfg->arch_disable)
+			dyn_tick_cfg->arch_disable();
+		dyn_tick->state &= ~DYN_TICK_ENABLED;
+	}
+	write_sequnlock_irqrestore(&xtime_lock, flags);
+
+	return count;
+}
+
+static ssize_t show_dyn_tick_useapic(struct sys_device *dev, char *buf)
+{
+	return sprintf(buf, "using APIC:\t%i\n",
+		       DYN_TICK_IS_SET(DYN_TICK_USE_APIC));
+}
+
+static ssize_t set_dyn_tick_useapic(struct sys_device *dev, const char *buf,
+				    size_t count)
+{
+	unsigned long flags;
+	unsigned int enable = simple_strtoul(buf, NULL, 2);
+
+	if (!DYN_TICK_IS_SET(DYN_TICK_APICABLE))
+		goto out;
+	write_seqlock_irqsave(&xtime_lock, flags);
+	if (enable)
+		dyn_tick->state |= DYN_TICK_USE_APIC;
+	else
+		dyn_tick->state &= ~DYN_TICK_USE_APIC;
+	write_sequnlock_irqrestore(&xtime_lock, flags);
+out:
+	return count;
+}
+
+static SYSDEV_ATTR(state, 0444, show_dyn_tick_state, NULL);
+static SYSDEV_ATTR(enable, 0644, show_dyn_tick_enable,
+		   set_dyn_tick_enable);
+static SYSDEV_ATTR(useapic, 0644, show_dyn_tick_useapic,
+		   set_dyn_tick_useapic);
+
+static struct sysdev_class dyn_tick_sysclass = {
+	set_kset_name("dyn_tick"),
+};
+
+static struct sys_device device_dyn_tick = {
+	.id = 0,
+	.cls = &dyn_tick_sysclass,
+};
+
+static int init_dyn_tick_sysfs(void)
+{
+	int error = 0;
+	if ((error = sysdev_class_register(&dyn_tick_sysclass)))
+		goto out;
+	if ((error = sysdev_register(&device_dyn_tick)))
+		goto out;
+	if ((error = sysdev_create_file(&device_dyn_tick, &attr_state)))
+		goto out;
+	if ((error = sysdev_create_file(&device_dyn_tick, &attr_enable)))
+		goto out;
+	error = sysdev_create_file(&device_dyn_tick, &attr_useapic);
+
+out:
+	return error;
+}
+
+device_initcall(init_dyn_tick_sysfs);
+
+/*
+ * ---------------------------------------------------------------------------
+ * Init functions
+ * ---------------------------------------------------------------------------
+ */
+
+static int __init dyn_tick_early_init(void)
+{
+	dyn_tick->state |= DYN_TICK_TIMER_INT;
+	return 0;
+}
+
+subsys_initcall(dyn_tick_early_init);
+
+/*
+ * We need to initialize dynamic tick after calibrate delay
+ */
+static int __init dyn_tick_late_init(void)
+{
+	int ret = 0;
+
+	if (dyn_tick_cfg == NULL || dyn_tick_cfg->arch_init == NULL ||
+	    !DYN_TICK_IS_SET(DYN_TICK_SUITABLE)) {
+		printk(KERN_ERR "dyn-tick: No suitable timer found\n");
+		return -ENODEV;
+	}
+
+	if (DYNTICK_APICABLE)
+		dyn_tick->state |= DYN_TICK_APICABLE;
+	if (!dyntick_useapic || !DYN_TICK_IS_SET(DYN_TICK_APICABLE))
+		dyn_tick->state &= ~DYN_TICK_USE_APIC;
+
+	if ((ret = dyn_tick_cfg->arch_init())) {
+		printk(KERN_ERR "dyn-tick: Init failed\n");
+		return -ENODEV;
+	}
+
+	if (!ret && dyntick_autoenable) {
+		dyn_tick->state |= DYN_TICK_ENABLED;
+		printk(KERN_INFO "dyn-tick: Timer using dynamic tick\n");
+	} else
+		printk(KERN_INFO "dyn-tick: Timer not enabled during boot\n");
+
+	return ret;
+}
+
+late_initcall(dyn_tick_late_init);
Index: linux-2.6.13-rc5-ck2/kernel/Makefile
===================================================================
--- linux-2.6.13-rc5-ck2.orig/kernel/Makefile	2005-08-07 13:07:12.000000000 +1000
+++ linux-2.6.13-rc5-ck2/kernel/Makefile	2005-08-07 13:07:45.000000000 +1000
@@ -30,6 +30,7 @@ obj-$(CONFIG_SYSFS) += ksysfs.o
 obj-$(CONFIG_GENERIC_HARDIRQS) += irq/
 obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
 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 <alan@linuxcare.com.au>, the -fno-omit-frame-pointer is

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

* Re: [PATCH] i386 No-Idle-Hz aka Dynamic-Ticks 5
  2005-08-07  5:12         ` [PATCH] i386 No-Idle-Hz aka Dynamic-Ticks 5 Con Kolivas
@ 2005-08-07 16:58           ` Srivatsa Vaddagiri
  2005-08-07 23:51             ` Con Kolivas
                               ` (2 more replies)
  2005-08-08 15:08           ` Folkert van Heusden
  1 sibling, 3 replies; 68+ messages in thread
From: Srivatsa Vaddagiri @ 2005-08-07 16:58 UTC (permalink / raw)
  To: Con Kolivas
  Cc: Adrian Bunk, linux-kernel, ck, tony, tuukka.tikkanen, george,
	Andrew Morton

On Sun, Aug 07, 2005 at 03:12:21PM +1000, Con Kolivas wrote:
> Respin of the dynamic ticks patch for i386 by Tony Lindgen and Tuukka Tikkanen 
> with further code cleanups. Are were there yet?

Con,
	I am afraid until SMP correctness is resolved, then this is not
in a position to go in (unless you want to enable it only for UP, which
I think should not be our target). I am working on making this work 
correctly on SMP systems. Hopefully I will post a patch soon.

Another observation I have made regarding dynamic tick patch is that PIT is 
being reprogrammed whenever the CPUs are coming out of sleep state (because of 
an interrupt say). This can happen at any arbitary time, not necessarily on 
jiffy boundaries. As a result, there will be an offset between when jiffy 
interrupts will now occur vs when they would have originally occured had PIT 
never been stopped. Not sure if having this offset is good, but atleast one 
necessary change that I foresee if zeroing delay_at_last_interrupt when 
disabling dynamic tick.  For that matter, it may be easier to disable the PIT 
timer by just masking PIT interrupts (instead of changing its mode).

Will keep you posted of my progress with dynamic tick patch.


-- 


Thanks and Regards,
Srivatsa Vaddagiri,
Linux Technology Center,
IBM Software Labs,
Bangalore, INDIA - 560017

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

* Re: [PATCH] i386 No-Idle-Hz aka Dynamic-Ticks 5
  2005-08-07 16:58           ` Srivatsa Vaddagiri
@ 2005-08-07 23:51             ` Con Kolivas
  2005-08-08  1:20               ` Kyle Moffett
  2005-08-08  7:38             ` Tony Lindgren
  2005-08-09 19:36             ` George Anzinger
  2 siblings, 1 reply; 68+ messages in thread
From: Con Kolivas @ 2005-08-07 23:51 UTC (permalink / raw)
  To: vatsa
  Cc: Adrian Bunk, linux-kernel, ck, tony, tuukka.tikkanen, george,
	Andrew Morton

On Mon, 8 Aug 2005 02:58, Srivatsa Vaddagiri wrote:
> On Sun, Aug 07, 2005 at 03:12:21PM +1000, Con Kolivas wrote:
> > Respin of the dynamic ticks patch for i386 by Tony Lindgen and Tuukka
> > Tikkanen with further code cleanups. Are were there yet?
>
> Con,
> 	I am afraid until SMP correctness is resolved, then this is not
> in a position to go in (unless you want to enable it only for UP, which
> I think should not be our target). I am working on making this work
> correctly on SMP systems. Hopefully I will post a patch soon.

> Will keep you posted of my progress with dynamic tick patch.

Great! I wasn't sure what time frame you meant when you last posted. I won't 
do anything more, leaving this patch as it is, and pass the baton to you.

Cheers,
Con

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

* Re: [PATCH] i386 No-Idle-Hz aka Dynamic-Ticks 5
  2005-08-07 23:51             ` Con Kolivas
@ 2005-08-08  1:20               ` Kyle Moffett
  2005-08-08  1:30                 ` Con Kolivas
  0 siblings, 1 reply; 68+ messages in thread
From: Kyle Moffett @ 2005-08-08  1:20 UTC (permalink / raw)
  To: Con Kolivas
  Cc: vatsa, Adrian Bunk, linux-kernel, ck, tony, tuukka.tikkanen,
	george, Andrew Morton

On Aug 7, 2005, at 19:51:25, Con Kolivas wrote:
> On Mon, 8 Aug 2005 02:58, Srivatsa Vaddagiri wrote:
>> Con,
>>     I am afraid until SMP correctness is resolved, then this is not
>> in a position to go in (unless you want to enable it only for UP,  
>> which
>> I think should not be our target). I am working on making this work
>> correctly on SMP systems. Hopefully I will post a patch soon.
>
> Great! I wasn't sure what time frame you meant when you last  
> posted. I won't
> do anything more, leaving this patch as it is, and pass the baton  
> to you.

I'm curious what has happened to the PPC side of the patch.  IIRC,  
someone
was working on such a port, but it seems to have been lost along the way
at some point.  Is there any additional information on that patch?

Cheers,
Kyle Moffett

--
Unix was not designed to stop people from doing stupid things,  
because that
would also stop them from doing clever things.
   -- Doug Gwyn



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

* Re: [PATCH] i386 No-Idle-Hz aka Dynamic-Ticks 5
  2005-08-08  1:20               ` Kyle Moffett
@ 2005-08-08  1:30                 ` Con Kolivas
  2005-08-08  1:45                   ` [ck] " Gabriel Devenyi
  2005-08-08  2:44                   ` Srivatsa Vaddagiri
  0 siblings, 2 replies; 68+ messages in thread
From: Con Kolivas @ 2005-08-08  1:30 UTC (permalink / raw)
  To: Kyle Moffett
  Cc: vatsa, Adrian Bunk, linux-kernel, ck, tony, tuukka.tikkanen,
	george, Andrew Morton

On Mon, 8 Aug 2005 11:20 am, Kyle Moffett wrote:
> On Aug 7, 2005, at 19:51:25, Con Kolivas wrote:
> > On Mon, 8 Aug 2005 02:58, Srivatsa Vaddagiri wrote:
> >> Con,
> >>     I am afraid until SMP correctness is resolved, then this is not
> >> in a position to go in (unless you want to enable it only for UP,
> >> which
> >> I think should not be our target). I am working on making this work
> >> correctly on SMP systems. Hopefully I will post a patch soon.
> >
> > Great! I wasn't sure what time frame you meant when you last
> > posted. I won't
> > do anything more, leaving this patch as it is, and pass the baton
> > to you.
>
> I'm curious what has happened to the PPC side of the patch.  IIRC,
> someone
> was working on such a port, but it seems to have been lost along the way
> at some point.  Is there any additional information on that patch?

Tony said he had it lying around somewhere and needed to find time to dust it 
off and get it up to speed.

Cheers,
Con

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

* Re: [ck] Re: [PATCH] i386 No-Idle-Hz aka Dynamic-Ticks 5
  2005-08-08  1:30                 ` Con Kolivas
@ 2005-08-08  1:45                   ` Gabriel Devenyi
  2005-08-08  2:44                   ` Srivatsa Vaddagiri
  1 sibling, 0 replies; 68+ messages in thread
From: Gabriel Devenyi @ 2005-08-08  1:45 UTC (permalink / raw)
  To: ck
  Cc: Con Kolivas, Kyle Moffett, Andrew Morton, vatsa, tony,
	linux-kernel, Adrian Bunk, tuukka.tikkanen, george

Along the same lines, is there an x86_64 patch around?

On August 07, 2005 21:30, Con Kolivas wrote:
> On Mon, 8 Aug 2005 11:20 am, Kyle Moffett wrote:
> > On Aug 7, 2005, at 19:51:25, Con Kolivas wrote:
> > > On Mon, 8 Aug 2005 02:58, Srivatsa Vaddagiri wrote:
> > >> Con,
> > >>     I am afraid until SMP correctness is resolved, then this is not
> > >> in a position to go in (unless you want to enable it only for UP,
> > >> which
> > >> I think should not be our target). I am working on making this work
> > >> correctly on SMP systems. Hopefully I will post a patch soon.
> > >
> > > Great! I wasn't sure what time frame you meant when you last
> > > posted. I won't
> > > do anything more, leaving this patch as it is, and pass the baton
> > > to you.
> >
> > I'm curious what has happened to the PPC side of the patch.  IIRC,
> > someone
> > was working on such a port, but it seems to have been lost along the way
> > at some point.  Is there any additional information on that patch?
>
> Tony said he had it lying around somewhere and needed to find time to dust
> it off and get it up to speed.
>
> Cheers,
> Con
> _______________________________________________
> ck@vds.kolivas.org
> ck mailing list. Please reply-to-all when posting.
> If replying to an email please reply below the original message.
> http://bhhdoa.org.au/mailman/listinfo/ck

-- 
Gabriel Devenyi
ace@staticwave.ca

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

* Re: [PATCH] i386 No-Idle-Hz aka Dynamic-Ticks 5
  2005-08-08  1:30                 ` Con Kolivas
  2005-08-08  1:45                   ` [ck] " Gabriel Devenyi
@ 2005-08-08  2:44                   ` Srivatsa Vaddagiri
  2005-08-08  7:05                     ` Nigel Cunningham
  1 sibling, 1 reply; 68+ messages in thread
From: Srivatsa Vaddagiri @ 2005-08-08  2:44 UTC (permalink / raw)
  To: Con Kolivas
  Cc: Kyle Moffett, Adrian Bunk, linux-kernel, ck, tony,
	tuukka.tikkanen, george, Andrew Morton

On Mon, Aug 08, 2005 at 11:30:23AM +1000, Con Kolivas wrote:
> Tony said he had it lying around somewhere and needed to find time to dust it 
> off and get it up to speed.

PPC64 is on my ToDo list as well. Will take it up after the dyn-tick is cleaned 
up for SMP.

-- 


Thanks and Regards,
Srivatsa Vaddagiri,
Linux Technology Center,
IBM Software Labs,
Bangalore, INDIA - 560017

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

* Re: [PATCH] i386 No-Idle-Hz aka Dynamic-Ticks 5
  2005-08-08  2:44                   ` Srivatsa Vaddagiri
@ 2005-08-08  7:05                     ` Nigel Cunningham
  0 siblings, 0 replies; 68+ messages in thread
From: Nigel Cunningham @ 2005-08-08  7:05 UTC (permalink / raw)
  To: vatsa
  Cc: Con Kolivas, Kyle Moffett, Adrian Bunk, Linux Kernel Mailing List,
	ck, tony, tuukka.tikkanen, george, Andrew Morton

Hi.

On Mon, 2005-08-08 at 12:44, Srivatsa Vaddagiri wrote:
> On Mon, Aug 08, 2005 at 11:30:23AM +1000, Con Kolivas wrote:
> > Tony said he had it lying around somewhere and needed to find time to dust it 
> > off and get it up to speed.
> 
> PPC64 is on my ToDo list as well. Will take it up after the dyn-tick is cleaned 
> up for SMP.

An SMP related area you might want to look at (if you haven't already)
is hotplug cpu support. There seems to be some interaction between
dynticks and hotplug that prevents a CPU from getting to set its state
to CPU_DEAD (despite being in the idle function), while the thread
seeking to down it sits in __cpu_die waiting. I observed the issue while
testing Suspend2 - about 1 in 5 resumes would lock solid or have a big
delay at resume time (never when suspending, interestingly). Turning off
dynticks allowed me to do 15 successful resumes on the trot.

Regards.

Nigel
-- 
Evolution.
Enumerate the requirements.
Consider the interdependencies.
Calculate the probabilities.


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

* Re: [PATCH] i386 No-Idle-Hz aka Dynamic-Ticks 3
  2005-08-05 12:37 ` Srivatsa Vaddagiri
  2005-08-05 13:08   ` Con Kolivas
@ 2005-08-08  7:26   ` Tony Lindgren
  2005-08-08 14:54     ` Srivatsa Vaddagiri
  2005-08-09 20:05     ` George Anzinger
  1 sibling, 2 replies; 68+ messages in thread
From: Tony Lindgren @ 2005-08-08  7:26 UTC (permalink / raw)
  To: Srivatsa Vaddagiri
  Cc: Con Kolivas, linux-kernel, ck, tuukka.tikkanen, george,
	Andrew Morton

* Srivatsa Vaddagiri <vatsa@in.ibm.com> [050805 05:37]:
> On Wed, Aug 03, 2005 at 06:05:28AM +0000, Con Kolivas wrote:
> > This is the dynamic ticks patch for i386 as written by Tony Lindgen 
> > <tony@atomide.com> and Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>. 
> > Patch for 2.6.13-rc5
> > 
> > There were a couple of things that I wanted to change so here is an updated 
> > version. This code should have stabilised enough for general testing now.
> 
> Con,
> 	I have been looking at some of the requirement of tickless idle CPUs in
> core kernel areas like scheduler and RCU. Basically, both power management and 
> virtualization benefit if idle CPUs can cut off useless timer ticks. Especially 
> from a virtualization standpoint, I think it makes sense that we enable this 
> feature on a per-CPU basis i.e let individual CPUs cut off their ticks as and 
> when they become idle. The benefit of this is more visible in platforms that 
> host lot of (SMP) VMs on the same machine. Most of the time, these VMs may be 
> partially idle (some CPUs in it are idle, some not) and it is good that we 
> quiesce the timer ticks on the partial set of idle CPUs. Both S390 and Xen ports
> of Linux kernel have this ability today (S390 has it in mainline already and 
> Xen has it out of tree).

Good point, and it would be nice to have it resolved for systems that support
idling individual CPUs. The current setup was done because when I was tinkering
with the amd76x_pm patch a while a back, I noticed that idling the cpu
disconnects all cpus from the bus. (As far as I remember)

So this may need to be configured depending on the system.

> From this viewpoint, I think the current implementation of dynamic tick
> falls short of this requirement. It cuts of the timer ticks only when 
> all CPUs go idle.
> 
> Apart from this observation, I have some others about the current dynamic tick
> patch:
> 
> - All CPUs seem to cut off the same number of ticks (dyn_tick->skip). Isn't
>   this wrong, considering that the timer list is per-CPU? This will cause
>   some timers to be serviced much later than usual.

Yes if it's done on per-CPU basis. In the current setup the first interrupt
will kick the system off the dyn-tick state and the timers get checked again.

> - The fact that dyn_tick_state is global and accessed from all CPUs
>   is probably a scalability concern, especially if we allow the ticks
>   to be cut off on per-CPU basis.

>From idling devices point of view, we still need some global variable I
believe. How else would you be able to tell all devices that the whole
system does not have any timers for next 2 seconds?

> - Again, when we allow this on a per-CPU basis, subsystems like
>   RCU need to know the partial set of idle CPUs. RCU already does
>   that thr' nohz_cpu_mask (which will need to replace dyn_cpu_map).

Sounds like that could work for dyn-tick too.

> - Looking at dyn_tick_timer_interrupt, would it be nice if we avoid calling 
>   do_timer_interrupt so many times and instead update jiffies to
>   (skipped_ticks - 1) and then call do_timer_interrupt once? I think
>   VST does it that way.

In the long run we would do the calculations in usecs and just emulate
jiffies from the hw timer. But yes, optimizing updating the time would be
great.

> - dyn_tick->max_skip = 0xffffff / apic_timer_val;
> 	From my reading of Intel docs, APIC_TMICT is 32-bit. So why does the
>   above calculation take only 24-bits into account? What am I missing here?

Hmm, could be a bug here, needs to be checked. Maybe 32-bit APIC timer is
optional support, or maybe I accidentally pulled the optional 24-bit support
from the ACPI PM timer.

But in any case on P4 systems the APIC timer is not the bottleneck as
stopping or reprogramming PIT also kills APIC. (This does not happen on P3
systems). So the bottleneck most likely is the length of PIT.

> I can take a shot at addressing these concerns in dynamic_tick patch, but it 
> seems to me that VST has already addressed all these to a big extent. Had you 
> considered VST before? The biggest bottleneck I see in VST going mainline is 
> its dependency on HRT patch but IMO it should be possible to write a small patch
> to support VST w/o HRT. 
>
> George, what do you think?

HRT + VST depend on APIC only, and does not use next_timer_interrupt().
CONFIG_NO_IDLE_HZ is already integrated in the mainline kernel for s390
and ARM. 

You may also want to check out the ARM implementation as it does not have
the issues listed above, which are mostly x86 specific issues.

Regards,

Tony


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

* Re: [PATCH] i386 No-Idle-Hz aka Dynamic-Ticks 5
  2005-08-07 16:58           ` Srivatsa Vaddagiri
  2005-08-07 23:51             ` Con Kolivas
@ 2005-08-08  7:38             ` Tony Lindgren
  2005-08-08 15:06               ` Srivatsa Vaddagiri
  2005-08-09 19:36             ` George Anzinger
  2 siblings, 1 reply; 68+ messages in thread
From: Tony Lindgren @ 2005-08-08  7:38 UTC (permalink / raw)
  To: Srivatsa Vaddagiri
  Cc: Con Kolivas, Adrian Bunk, linux-kernel, ck, tuukka.tikkanen,
	george, Andrew Morton

* Srivatsa Vaddagiri <vatsa@in.ibm.com> [050807 09:58]:
> On Sun, Aug 07, 2005 at 03:12:21PM +1000, Con Kolivas wrote:
> > Respin of the dynamic ticks patch for i386 by Tony Lindgen and Tuukka Tikkanen 
> > with further code cleanups. Are were there yet?
> 
> Con,
> 	I am afraid until SMP correctness is resolved, then this is not
> in a position to go in (unless you want to enable it only for UP, which
> I think should not be our target). I am working on making this work 
> correctly on SMP systems. Hopefully I will post a patch soon.

Hopefully you get something worked out that works for all. Please see my
amd76x_pm related comments earlier too.

> Another observation I have made regarding dynamic tick patch is that PIT is 
> being reprogrammed whenever the CPUs are coming out of sleep state (because of 
> an interrupt say). This can happen at any arbitary time, not necessarily on 
> jiffy boundaries. As a result, there will be an offset between when jiffy 
> interrupts will now occur vs when they would have originally occured had PIT 
> never been stopped. Not sure if having this offset is good, but atleast one 
> necessary change that I foresee if zeroing delay_at_last_interrupt when 
> disabling dynamic tick.  For that matter, it may be easier to disable the PIT 
> timer by just masking PIT interrupts (instead of changing its mode).

It should not matter when the PIT gets reprogrammed, as the system time is
not updated from PIT timer. Jiffies are calculated from a second timer, such
as ACPI PM timer or TSC.

Tony

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

* Re: [PATCH] i386 No-Idle-Hz aka Dynamic-Ticks 3
  2005-08-08  7:26   ` [PATCH] i386 No-Idle-Hz aka Dynamic-Ticks 3 Tony Lindgren
@ 2005-08-08 14:54     ` Srivatsa Vaddagiri
  2005-08-08 15:20       ` Tony Lindgren
  2005-08-09 20:05     ` George Anzinger
  1 sibling, 1 reply; 68+ messages in thread
From: Srivatsa Vaddagiri @ 2005-08-08 14:54 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: Con Kolivas, linux-kernel, ck, tuukka.tikkanen, george,
	Andrew Morton

On Mon, Aug 08, 2005 at 12:26:01AM -0700, Tony Lindgren wrote:
> Good point, and it would be nice to have it resolved for systems that support
> idling individual CPUs. The current setup was done because when I was tinkering
> with the amd76x_pm patch a while a back, I noticed that idling the cpu
> disconnects all cpus from the bus. (As far as I remember)
> So this may need to be configured depending on the system.

What do you mean by "idling" a cpu? Is it reprogramming the timer source
to skip ticks? Or putting the cpu actually in some low-power state?
And what do you mean by "disconnect all CPUs from the bus"? Is it
the system bus? And what happens if the CPUs are disconnected from
the bus like this while it is executing?

Both requirements (idling all CPUs together vs individually) I think
will make the patch more complex.  Are such systems (which require having to 
idle all CPUs together) pretty common that we have to care about?!


> > - All CPUs seem to cut off the same number of ticks (dyn_tick->skip). Isn't
> >   this wrong, considering that the timer list is per-CPU? This will cause
> >   some timers to be serviced much later than usual.
> 
> Yes if it's done on per-CPU basis. In the current setup the first interrupt
> will kick the system off the dyn-tick state and the timers get checked again.

But that may be too late on some CPUs. If dyn_tick->skip = 100, all
CPUs skip 100 ticks. However some CPUs may have timers that need to be
service much before that.

> > - The fact that dyn_tick_state is global and accessed from all CPUs
> >   is probably a scalability concern, especially if we allow the ticks
> >   to be cut off on per-CPU basis.
> 
> >From idling devices point of view, we still need some global variable I
> believe. How else would you be able to tell all devices that the whole
> system does not have any timers for next 2 seconds?

Why would anyone want to know that? Moreover, when we enable this
per-CPU, the no-timer-interval is also distributed across CPUs.

> But in any case on P4 systems the APIC timer is not the bottleneck as
> stopping or reprogramming PIT also kills APIC. (This does not happen on P3
> systems). So the bottleneck most likely is the length of PIT.

On these systems, do you disabled APIC (dyntick=noapic)?

> HRT + VST depend on APIC only, and does not use next_timer_interrupt().

AFAIK, it supports pm timer too and yes it has its own implementation
of next_timer_interrupt, which makes it more work for merging. 
At this point, looks like dyn-tick is gaining more momentum and is 
more likely a candidate for merging. I will send out my SMP-support
changes to dynamic tick soon.

> You may also want to check out the ARM implementation as it does not have
> the issues listed above, which are mostly x86 specific issues.

Thanks for the pointer. Will look at it.


-- 


Thanks and Regards,
Srivatsa Vaddagiri,
Linux Technology Center,
IBM Software Labs,
Bangalore, INDIA - 560017

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

* Re: [PATCH] i386 No-Idle-Hz aka Dynamic-Ticks 5
  2005-08-08  7:38             ` Tony Lindgren
@ 2005-08-08 15:06               ` Srivatsa Vaddagiri
  0 siblings, 0 replies; 68+ messages in thread
From: Srivatsa Vaddagiri @ 2005-08-08 15:06 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: Con Kolivas, Adrian Bunk, linux-kernel, ck, tuukka.tikkanen,
	george, Andrew Morton

On Mon, Aug 08, 2005 at 12:38:23AM -0700, Tony Lindgren wrote:
> It should not matter when the PIT gets reprogrammed, as the system time is
> not updated from PIT timer. Jiffies are calculated from a second timer, such
> as ACPI PM timer or TSC.

I am more worried about timer latencies and its effects. Because of this skew 
between when jiffy interrupt was originally supposed to happen and when it 
will now happen, it can lead to, for example, scheduling latencies upto
1 jiffy (for HZ=100, that could hurt some apps?) Not to mention that
this will not play well with high-res-timers, but that is probably
not a concern now!


-- 


Thanks and Regards,
Srivatsa Vaddagiri,
Linux Technology Center,
IBM Software Labs,
Bangalore, INDIA - 560017

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

* Re: [PATCH] i386 No-Idle-Hz aka Dynamic-Ticks 5
  2005-08-07  5:12         ` [PATCH] i386 No-Idle-Hz aka Dynamic-Ticks 5 Con Kolivas
  2005-08-07 16:58           ` Srivatsa Vaddagiri
@ 2005-08-08 15:08           ` Folkert van Heusden
  2005-08-08 15:16             ` Daniel Petrini
  1 sibling, 1 reply; 68+ messages in thread
From: Folkert van Heusden @ 2005-08-08 15:08 UTC (permalink / raw)
  To: Con Kolivas
  Cc: Adrian Bunk, linux-kernel, vatsa, ck, tony, tuukka.tikkanen,
	george, Andrew Morton

Are there any tools for checking the current number of ticks?
I currently do:
#!/bin/sh

S1=`cat /proc/interrupts | grep "^  0: " | awk '{ print $2; }'`
sleep 1
S2=`cat /proc/interrupts | grep "^  0: " | awk '{ print $2; }'`
echo $((S2-S1))

But that gives me output like this on a quiet system with only firefox,
a couple of gnometerms and a bittorrent downloader values like:
folkert@ehm:~$ for i in `seq 1 10` ; do ./ticks ; done
566
511
630
501
522
533
503
516
518
515
which I find quiet high, aren't they?


On Sun, Aug 07, 2005 at 03:12:21PM +1000, Con Kolivas wrote:
> Respin of the dynamic ticks patch for i386 by Tony Lindgen and Tuukka Tikkanen 
> with further code cleanups. Are were there yet?
> 
> Cheers,
> Con
> ---
> 
> 


Folkert van Heusden

-- 
Auto te koop, zie: http://www.vanheusden.com/daihatsu.php
--------------------------------------------------------------------
Get your PGP/GPG key signed at www.biglumber.com!
--------------------------------------------------------------------
Phone: +31-6-41278122, PGP-key: 1F28D8AE

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

* Re: [PATCH] i386 No-Idle-Hz aka Dynamic-Ticks 5
  2005-08-08 15:08           ` Folkert van Heusden
@ 2005-08-08 15:16             ` Daniel Petrini
  0 siblings, 0 replies; 68+ messages in thread
From: Daniel Petrini @ 2005-08-08 15:16 UTC (permalink / raw)
  To: Folkert van Heusden
  Cc: Con Kolivas, Adrian Bunk, linux-kernel, vatsa, ck, tony,
	tuukka.tikkanen, george, Andrew Morton

Hi Folkert,

Yes, there are some utilities. You can use pmstats-0.2 (look for the
link in past messages) or timertop (sent some minutes ago in LKML).
Regards,
Daniel

On 8/8/05, Folkert van Heusden <folkert@vanheusden.com> wrote:
> Are there any tools for checking the current number of ticks?
> I currently do:
> #!/bin/sh
> 
> S1=`cat /proc/interrupts | grep "^  0: " | awk '{ print $2; }'`
> sleep 1
> S2=`cat /proc/interrupts | grep "^  0: " | awk '{ print $2; }'`
> echo $((S2-S1))
> 
> But that gives me output like this on a quiet system with only firefox,
> a couple of gnometerms and a bittorrent downloader values like:
> folkert@ehm:~$ for i in `seq 1 10` ; do ./ticks ; done
> 566
> 511
> 630
> 501
> 522
> 533
> 503
> 516
> 518
> 515
> which I find quiet high, aren't they?
> 
> 
> On Sun, Aug 07, 2005 at 03:12:21PM +1000, Con Kolivas wrote:
> > Respin of the dynamic ticks patch for i386 by Tony Lindgen and Tuukka Tikkanen
> > with further code cleanups. Are were there yet?
> >
> > Cheers,
> > Con
> > ---
> >
> >
> 
> 
> Folkert van Heusden
> 
> --
> Auto te koop, zie: http://www.vanheusden.com/daihatsu.php
> --------------------------------------------------------------------
> Get your PGP/GPG key signed at www.biglumber.com!
> --------------------------------------------------------------------
> Phone: +31-6-41278122, PGP-key: 1F28D8AE
> -
> 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/
> 


-- 
10LE - Linux
INdT - Manaus - Brazil

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

* Re: [PATCH] i386 No-Idle-Hz aka Dynamic-Ticks 3
  2005-08-08 14:54     ` Srivatsa Vaddagiri
@ 2005-08-08 15:20       ` Tony Lindgren
  2005-08-09 14:22         ` Zwane Mwaikambo
  0 siblings, 1 reply; 68+ messages in thread
From: Tony Lindgren @ 2005-08-08 15:20 UTC (permalink / raw)
  To: Srivatsa Vaddagiri
  Cc: Con Kolivas, linux-kernel, ck, tuukka.tikkanen, george,
	Andrew Morton

* Srivatsa Vaddagiri <vatsa@in.ibm.com> [050808 07:53]:
> On Mon, Aug 08, 2005 at 12:26:01AM -0700, Tony Lindgren wrote:
> > Good point, and it would be nice to have it resolved for systems that support
> > idling individual CPUs. The current setup was done because when I was tinkering
> > with the amd76x_pm patch a while a back, I noticed that idling the cpu
> > disconnects all cpus from the bus. (As far as I remember)
> > So this may need to be configured depending on the system.
> 
> What do you mean by "idling" a cpu? Is it reprogramming the timer source
> to skip ticks? Or putting the cpu actually in some low-power state?
> And what do you mean by "disconnect all CPUs from the bus"? Is it
> the system bus? And what happens if the CPUs are disconnected from
> the bus like this while it is executing?

As far as I remember enabling AMD stop grant disconnects all cpus. This
means the system won't be able to do any work until the dyntick timer
interrupt wakes up the system.

> Both requirements (idling all CPUs together vs individually) I think
> will make the patch more complex.  Are such systems (which require having to 
> idle all CPUs together) pretty common that we have to care about?!

Probably all AMD SMP based systems? Somebody with better knowledge should
verify this.

> > > - All CPUs seem to cut off the same number of ticks (dyn_tick->skip). Isn't
> > >   this wrong, considering that the timer list is per-CPU? This will cause
> > >   some timers to be serviced much later than usual.
> > 
> > Yes if it's done on per-CPU basis. In the current setup the first interrupt
> > will kick the system off the dyn-tick state and the timers get checked again.
> 
> But that may be too late on some CPUs. If dyn_tick->skip = 100, all
> CPUs skip 100 ticks. However some CPUs may have timers that need to be
> service much before that.

Not in the current case, as the system is completely idle until some
interrupt wakes up the system. Of course it would be different if you make
it per-CPU.

> > > - The fact that dyn_tick_state is global and accessed from all CPUs
> > >   is probably a scalability concern, especially if we allow the ticks
> > >   to be cut off on per-CPU basis.
> > 
> > >From idling devices point of view, we still need some global variable I
> > believe. How else would you be able to tell all devices that the whole
> > system does not have any timers for next 2 seconds?
> 
> Why would anyone want to know that? Moreover, when we enable this
> per-CPU, the no-timer-interval is also distributed across CPUs.

Well we need to be able to do various things in the idle loop depending on
the length of the estimated sleep. For example, if next_timer_interrupt is
2 jiffies away, we cannot do much. But if next_timer_interrupt is 2 seconds
away, we can idle pretty much all devices.

> > But in any case on P4 systems the APIC timer is not the bottleneck as
> > stopping or reprogramming PIT also kills APIC. (This does not happen on P3
> > systems). So the bottleneck most likely is the length of PIT.
> 
> On these systems, do you disabled APIC (dyntick=noapic)?

Yeah. It only seems to work on P3 systems.

> > HRT + VST depend on APIC only, and does not use next_timer_interrupt().
> 
> AFAIK, it supports pm timer too and yes it has its own implementation
> of next_timer_interrupt, which makes it more work for merging. 
> At this point, looks like dyn-tick is gaining more momentum and is 
> more likely a candidate for merging. I will send out my SMP-support
> changes to dynamic tick soon.

Cool :) Sounds like SMP and HPET are about the only things that still need
work. Or can somebody think of anything else?

> > You may also want to check out the ARM implementation as it does not have
> > the issues listed above, which are mostly x86 specific issues.
> 
> Thanks for the pointer. Will look at it.

OK

Tony

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

* Re: [PATCH] i386 No-Idle-Hz aka Dynamic-Ticks 3
  2005-08-08 15:20       ` Tony Lindgren
@ 2005-08-09 14:22         ` Zwane Mwaikambo
  2005-08-10  7:46           ` Tony Lindgren
  0 siblings, 1 reply; 68+ messages in thread
From: Zwane Mwaikambo @ 2005-08-09 14:22 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: Srivatsa Vaddagiri, Con Kolivas, linux-kernel, ck,
	tuukka.tikkanen, george, Andrew Morton

On Mon, 8 Aug 2005, Tony Lindgren wrote:

> As far as I remember enabling AMD stop grant disconnects all cpus. This
> means the system won't be able to do any work until the dyntick timer
> interrupt wakes up the system.
> 
> > Both requirements (idling all CPUs together vs individually) I think
> > will make the patch more complex.  Are such systems (which require having to 
> > idle all CPUs together) pretty common that we have to care about?!
> 
> Probably all AMD SMP based systems? Somebody with better knowledge should
> verify this.

It would be the K7 only.

> > But that may be too late on some CPUs. If dyn_tick->skip = 100, all
> > CPUs skip 100 ticks. However some CPUs may have timers that need to be
> > service much before that.
> 
> Not in the current case, as the system is completely idle until some
> interrupt wakes up the system. Of course it would be different if you make
> it per-CPU.

I once did a weekend version of this with SMP support and for the PIT, i 
had the last cpu to enter idle turn reprogram the PIT. Unfortunately this 
means waiting for all processors and isn't as effective as a result.

> Well we need to be able to do various things in the idle loop depending on
> the length of the estimated sleep. For example, if next_timer_interrupt is
> 2 jiffies away, we cannot do much. But if next_timer_interrupt is 2 seconds
> away, we can idle pretty much all devices.
> 
> > > But in any case on P4 systems the APIC timer is not the bottleneck as
> > > stopping or reprogramming PIT also kills APIC. (This does not happen on P3
> > > systems). So the bottleneck most likely is the length of PIT.
> > 
> > On these systems, do you disabled APIC (dyntick=noapic)?
> 
> Yeah. It only seems to work on P3 systems.

Odd, does reprogramming the APIC at that point get it going again?

	Zwane


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

* Re: [PATCH] i386 No-Idle-Hz aka Dynamic-Ticks 5
  2005-08-07 16:58           ` Srivatsa Vaddagiri
  2005-08-07 23:51             ` Con Kolivas
  2005-08-08  7:38             ` Tony Lindgren
@ 2005-08-09 19:36             ` George Anzinger
  2005-08-10 14:05               ` Srivatsa Vaddagiri
  2 siblings, 1 reply; 68+ messages in thread
From: George Anzinger @ 2005-08-09 19:36 UTC (permalink / raw)
  To: vatsa
  Cc: Con Kolivas, Adrian Bunk, linux-kernel, ck, tony, tuukka.tikkanen,
	Andrew Morton

Srivatsa Vaddagiri wrote:
> On Sun, Aug 07, 2005 at 03:12:21PM +1000, Con Kolivas wrote:
> 
>>Respin of the dynamic ticks patch for i386 by Tony Lindgen and Tuukka Tikkanen 
>>with further code cleanups. Are were there yet?
> 
> 
> Con,
> 	I am afraid until SMP correctness is resolved, then this is not
> in a position to go in (unless you want to enable it only for UP, which
> I think should not be our target). I am working on making this work 
> correctly on SMP systems. Hopefully I will post a patch soon.
> 
> Another observation I have made regarding dynamic tick patch is that PIT is 
> being reprogrammed whenever the CPUs are coming out of sleep state (because of 
> an interrupt say). This can happen at any arbitary time, not necessarily on 
> jiffy boundaries. As a result, there will be an offset between when jiffy 
> interrupts will now occur vs when they would have originally occured had PIT 
> never been stopped. Not sure if having this offset is good, but atleast one 
> necessary change that I foresee if zeroing delay_at_last_interrupt when 
> disabling dynamic tick.  For that matter, it may be easier to disable the PIT 
> timer by just masking PIT interrupts (instead of changing its mode).

IMNOHO, this is the ONLY way to keep proper time.  As soon as you 
reprogram the PIT you have lost track of the time.

My VST patch just turns masks the interrupt.
-- 
George Anzinger   george@mvista.com
HRT (High-res-timers):  http://sourceforge.net/projects/high-res-timers/

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

* Re: [PATCH] i386 No-Idle-Hz aka Dynamic-Ticks 3
  2005-08-08  7:26   ` [PATCH] i386 No-Idle-Hz aka Dynamic-Ticks 3 Tony Lindgren
  2005-08-08 14:54     ` Srivatsa Vaddagiri
@ 2005-08-09 20:05     ` George Anzinger
  2005-08-09 20:22       ` Daniel Petrini
  2005-08-10  8:02       ` Tony Lindgren
  1 sibling, 2 replies; 68+ messages in thread
From: George Anzinger @ 2005-08-09 20:05 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: Srivatsa Vaddagiri, Con Kolivas, linux-kernel, ck,
	tuukka.tikkanen, Andrew Morton

Tony Lindgren wrote:
> * Srivatsa Vaddagiri <vatsa@in.ibm.com> [050805 05:37]:
> 
>>On Wed, Aug 03, 2005 at 06:05:28AM +0000, Con Kolivas wrote:
>>
>>>This is the dynamic ticks patch for i386 as written by Tony Lindgen 
>>><tony@atomide.com> and Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>. 
>>>Patch for 2.6.13-rc5
>>>
>>>There were a couple of things that I wanted to change so here is an updated 
>>>version. This code should have stabilised enough for general testing now.
>>
>>Con,
>>	I have been looking at some of the requirement of tickless idle CPUs in
>>core kernel areas like scheduler and RCU. Basically, both power management and 
>>virtualization benefit if idle CPUs can cut off useless timer ticks. Especially 
>>from a virtualization standpoint, I think it makes sense that we enable this 
>>feature on a per-CPU basis i.e let individual CPUs cut off their ticks as and 
>>when they become idle. The benefit of this is more visible in platforms that 
>>host lot of (SMP) VMs on the same machine. Most of the time, these VMs may be 
>>partially idle (some CPUs in it are idle, some not) and it is good that we 
>>quiesce the timer ticks on the partial set of idle CPUs. Both S390 and Xen ports
>>of Linux kernel have this ability today (S390 has it in mainline already and 
>>Xen has it out of tree).
> 
> 
> Good point, and it would be nice to have it resolved for systems that support
> idling individual CPUs. The current setup was done because when I was tinkering
> with the amd76x_pm patch a while a back, I noticed that idling the cpu
> disconnects all cpus from the bus. (As far as I remember)
> 
> So this may need to be configured depending on the system.
> 
> 
>>From this viewpoint, I think the current implementation of dynamic tick
>>falls short of this requirement. It cuts of the timer ticks only when 
>>all CPUs go idle.
>>
>>Apart from this observation, I have some others about the current dynamic tick
>>patch:
>>
>>- All CPUs seem to cut off the same number of ticks (dyn_tick->skip). Isn't
>>  this wrong, considering that the timer list is per-CPU? This will cause
>>  some timers to be serviced much later than usual.
> 
> 
> Yes if it's done on per-CPU basis. In the current setup the first interrupt
> will kick the system off the dyn-tick state and the timers get checked again.
> 
> 
>>- The fact that dyn_tick_state is global and accessed from all CPUs
>>  is probably a scalability concern, especially if we allow the ticks
>>  to be cut off on per-CPU basis.
> 
> 
>>From idling devices point of view, we still need some global variable I
> believe. How else would you be able to tell all devices that the whole
> system does not have any timers for next 2 seconds?
> 
> 
>>- Again, when we allow this on a per-CPU basis, subsystems like
>>  RCU need to know the partial set of idle CPUs. RCU already does
>>  that thr' nohz_cpu_mask (which will need to replace dyn_cpu_map).
> 
> 
> Sounds like that could work for dyn-tick too.
> 
> 
>>- Looking at dyn_tick_timer_interrupt, would it be nice if we avoid calling 
>>  do_timer_interrupt so many times and instead update jiffies to
>>  (skipped_ticks - 1) and then call do_timer_interrupt once? I think
>>  VST does it that way.
> 
> 
> In the long run we would do the calculations in usecs and just emulate
> jiffies from the hw timer. But yes, optimizing updating the time would be
> great.
> 
> 
>>- dyn_tick->max_skip = 0xffffff / apic_timer_val;
>>	From my reading of Intel docs, APIC_TMICT is 32-bit. So why does the
>>  above calculation take only 24-bits into account? What am I missing here?
> 
> 
> Hmm, could be a bug here, needs to be checked. Maybe 32-bit APIC timer is
> optional support, or maybe I accidentally pulled the optional 24-bit support
> from the ACPI PM timer.
> 
> But in any case on P4 systems the APIC timer is not the bottleneck as
> stopping or reprogramming PIT also kills APIC. (This does not happen on P3
> systems). So the bottleneck most likely is the length of PIT.
> 
> 
>>I can take a shot at addressing these concerns in dynamic_tick patch, but it 
>>seems to me that VST has already addressed all these to a big extent. Had you 
>>considered VST before? The biggest bottleneck I see in VST going mainline is 
>>its dependency on HRT patch but IMO it should be possible to write a small patch
>>to support VST w/o HRT. 
>>
>>George, what do you think?
> 
> 
> HRT + VST depend on APIC only, and does not use next_timer_interrupt().

I convinced my self that the next_timer... code in timer.c misses timers 
(i.e. gives the wrong answer).  I did this (after wondering due to 
performance) by scanning the whole timer list after I had the 
next_timer... answer and finding a better answer, not always, but some 
times.  That code does not address the cascade list correctly.


-- 
George Anzinger   george@mvista.com
HRT (High-res-timers):  http://sourceforge.net/projects/high-res-timers/

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

* Re: [PATCH] i386 No-Idle-Hz aka Dynamic-Ticks 3
  2005-08-09 20:05     ` George Anzinger
@ 2005-08-09 20:22       ` Daniel Petrini
  2005-08-10  8:02       ` Tony Lindgren
  1 sibling, 0 replies; 68+ messages in thread
From: Daniel Petrini @ 2005-08-09 20:22 UTC (permalink / raw)
  To: george
  Cc: Tony Lindgren, Srivatsa Vaddagiri, Con Kolivas, linux-kernel, ck,
	tuukka.tikkanen, Andrew Morton

> I convinced my self that the next_timer... code in timer.c misses timers
> (i.e. gives the wrong answer).  I did this (after wondering due to
> performance) by scanning the whole timer list after I had the
> next_timer... answer and finding a better answer, not always, but some
> times.  That code does not address the cascade list correctly.

The timertop kernel patch accounts for all the scheduled timers. Try
to take a look at its output at /proc/top_info. Maybe it can help to
detect it.


Daniel Petrini
-- 
10LE - Linux
INdT - Manaus - Brazil

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

* Re: [PATCH] i386 No-Idle-Hz aka Dynamic-Ticks 3
  2005-08-09 14:22         ` Zwane Mwaikambo
@ 2005-08-10  7:46           ` Tony Lindgren
  0 siblings, 0 replies; 68+ messages in thread
From: Tony Lindgren @ 2005-08-10  7:46 UTC (permalink / raw)
  To: Zwane Mwaikambo
  Cc: Srivatsa Vaddagiri, Con Kolivas, linux-kernel, ck,
	tuukka.tikkanen, george, Andrew Morton

* Zwane Mwaikambo <zwane@arm.linux.org.uk> [050809 07:17]:
> On Mon, 8 Aug 2005, Tony Lindgren wrote:
> 
> > As far as I remember enabling AMD stop grant disconnects all cpus. This
> > means the system won't be able to do any work until the dyntick timer
> > interrupt wakes up the system.
> > 
> > > Both requirements (idling all CPUs together vs individually) I think
> > > will make the patch more complex.  Are such systems (which require having to 
> > > idle all CPUs together) pretty common that we have to care about?!
> > 
> > Probably all AMD SMP based systems? Somebody with better knowledge should
> > verify this.
> 
> It would be the K7 only.

OK, still quite a few systems.

> > > But that may be too late on some CPUs. If dyn_tick->skip = 100, all
> > > CPUs skip 100 ticks. However some CPUs may have timers that need to be
> > > service much before that.
> > 
> > Not in the current case, as the system is completely idle until some
> > interrupt wakes up the system. Of course it would be different if you make
> > it per-CPU.
> 
> I once did a weekend version of this with SMP support and for the PIT, i 
> had the last cpu to enter idle turn reprogram the PIT. Unfortunately this 
> means waiting for all processors and isn't as effective as a result.
> 
> > Well we need to be able to do various things in the idle loop depending on
> > the length of the estimated sleep. For example, if next_timer_interrupt is
> > 2 jiffies away, we cannot do much. But if next_timer_interrupt is 2 seconds
> > away, we can idle pretty much all devices.
> > 
> > > > But in any case on P4 systems the APIC timer is not the bottleneck as
> > > > stopping or reprogramming PIT also kills APIC. (This does not happen on P3
> > > > systems). So the bottleneck most likely is the length of PIT.
> > > 
> > > On these systems, do you disabled APIC (dyntick=noapic)?
> > 
> > Yeah. It only seems to work on P3 systems.
> 
> Odd, does reprogramming the APIC at that point get it going again?

Hmmm, might be worth trying.

Tony

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

* Re: [PATCH] i386 No-Idle-Hz aka Dynamic-Ticks 3
  2005-08-09 20:05     ` George Anzinger
  2005-08-09 20:22       ` Daniel Petrini
@ 2005-08-10  8:02       ` Tony Lindgren
  2005-08-10 22:40         ` George Anzinger
  1 sibling, 1 reply; 68+ messages in thread
From: Tony Lindgren @ 2005-08-10  8:02 UTC (permalink / raw)
  To: George Anzinger
  Cc: Srivatsa Vaddagiri, Con Kolivas, linux-kernel, ck,
	tuukka.tikkanen, Andrew Morton

* George Anzinger <george@mvista.com> [050809 13:07]:
>
> >>I can take a shot at addressing these concerns in dynamic_tick patch, but 
> >>it seems to me that VST has already addressed all these to a big extent. 
> >>Had you considered VST before? The biggest bottleneck I see in VST going 
> >>mainline is its dependency on HRT patch but IMO it should be possible to 
> >>write a small patch
> >>to support VST w/o HRT. 
> >>
> >>George, what do you think?
> >
> >
> >HRT + VST depend on APIC only, and does not use next_timer_interrupt().
> 
> I convinced my self that the next_timer... code in timer.c misses timers 
> (i.e. gives the wrong answer).  I did this (after wondering due to 
> performance) by scanning the whole timer list after I had the 
> next_timer... answer and finding a better answer, not always, but some 
> times.  That code does not address the cascade list correctly.

Do you have a patch around for improving next_timer_interrupt()?

Tony

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

* Re: [PATCH] i386 No-Idle-Hz aka Dynamic-Ticks 5
  2005-08-09 19:36             ` George Anzinger
@ 2005-08-10 14:05               ` Srivatsa Vaddagiri
  2005-08-10 22:37                 ` George Anzinger
  0 siblings, 1 reply; 68+ messages in thread
From: Srivatsa Vaddagiri @ 2005-08-10 14:05 UTC (permalink / raw)
  To: George Anzinger
  Cc: Con Kolivas, Adrian Bunk, linux-kernel, ck, tony, tuukka.tikkanen,
	Andrew Morton

On Tue, Aug 09, 2005 at 12:36:58PM -0700, George Anzinger wrote:
> IMNOHO, this is the ONLY way to keep proper time.  As soon as you 
> reprogram the PIT you have lost track of the time.

George,
	Can't TSC (or equivalent) serve as a backup while PIT is disabled,
especially considering that we disable PIT only for short duration 
in practice (few seconds maybe) _and_ that we don't have HRT support yet?

-- 


Thanks and Regards,
Srivatsa Vaddagiri,
Linux Technology Center,
IBM Software Labs,
Bangalore, INDIA - 560017

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

* Re: [PATCH] i386 No-Idle-Hz aka Dynamic-Ticks 3
  2005-08-04  6:59           ` Jim MacBaine
  2005-08-04  7:04             ` Con Kolivas
@ 2005-08-10 20:04             ` Bill Davidsen
  1 sibling, 0 replies; 68+ messages in thread
From: Bill Davidsen @ 2005-08-10 20:04 UTC (permalink / raw)
  To: Jim MacBaine; +Cc: ck, tony, tuukka.tikkanen, linux-kernel

Jim MacBaine wrote:
> I just borrowed a power meter to see (or not to see) real effects of
> dyntick. The difference between static 1000 HZ and dynamic HZ is much
> less than I expected, only a very little about noise.  With dyntick
> disabled at 1000 HZ my laptop needs 31,3 W.  With dyntick enabled I
> get 29.8 W, the pmstats-0.2 script shows me that the system is at
> 35-45 HZ when it is idle.
> 
> The power consumption difference between 250 HZ static and dyntick is
> below the noise, so maybe hardly worth all the struggle.

I think it's the other way round, we have the lower power without the 
higher latency. At least as I can measure...

Bravo to all concerned to get this to the testing stage!

-- 
    -bill davidsen (davidsen@tmr.com)
"The secret to procrastination is to put things off until the
  last possible moment - but no longer"  -me

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

* Re: [PATCH] i386 No-Idle-Hz aka Dynamic-Ticks 5
  2005-08-10 14:05               ` Srivatsa Vaddagiri
@ 2005-08-10 22:37                 ` George Anzinger
  2005-08-11 21:33                   ` Bill Davidsen
  0 siblings, 1 reply; 68+ messages in thread
From: George Anzinger @ 2005-08-10 22:37 UTC (permalink / raw)
  To: vatsa
  Cc: Con Kolivas, Adrian Bunk, linux-kernel, ck, tony, tuukka.tikkanen,
	Andrew Morton

Srivatsa Vaddagiri wrote:
> On Tue, Aug 09, 2005 at 12:36:58PM -0700, George Anzinger wrote:
> 
>>IMNOHO, this is the ONLY way to keep proper time.  As soon as you 
>>reprogram the PIT you have lost track of the time.
> 
> 
> George,
> 	Can't TSC (or equivalent) serve as a backup while PIT is disabled,
> especially considering that we disable PIT only for short duration 
> in practice (few seconds maybe) _and_ that we don't have HRT support yet?
> 
I think it really depends on what you want.  If you really want to keep 
good time, the only rock in town is the one connected to the PIT (and 
the pmtimer).  The problem is, if you want the jiffie edge to be stable, 
there is just now way to reprogram the PIT to get it back to where it was.

In an old version of HRT I did a trick of loading a short count (based 
on reading the TSC or pmtimer) and then put the LATCH count on top of 
it.  In a correctly performing PIT, it should count down the short 
count, interrupt, load the long count and continue from there.  Aside 
from the machines that had BAD PITs (they reset on the load instead of 
the expiry of the current count) there were other problems that, in the 
end, cause loss of time (too fast, too slow, take your pick).  I also 
found PITs that signaled that they had loaded the count (they set a 
status bit) prior to actually loading it.  All in all, I find the PIT is 
just an ugly beast to try to program.  On the other hand, if you want 
regular interrupts at some fixed period, it will do this forever (give 
or take a epoch or two;) with out touching anything after the initial 
program set up.

In the end, I concluded that, for the community kernel, it is really 
best to just interrupt the irq line and leave the PIT run.  Then you use 
the TSC or pmtimer to figure the gross loss of interrupts and leave the 
PIT interrupt again to define the jiffie edge.  If you have other, more 
pressing, concerns I suppose you can program the PIT, but don't expect 
your wall clock to be as stable as it is now.

-- 
George Anzinger   george@mvista.com
HRT (High-res-timers):  http://sourceforge.net/projects/high-res-timers/

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

* Re: [PATCH] i386 No-Idle-Hz aka Dynamic-Ticks 3
  2005-08-10  8:02       ` Tony Lindgren
@ 2005-08-10 22:40         ` George Anzinger
  0 siblings, 0 replies; 68+ messages in thread
From: George Anzinger @ 2005-08-10 22:40 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: Srivatsa Vaddagiri, Con Kolivas, linux-kernel, ck,
	tuukka.tikkanen, Andrew Morton

Tony Lindgren wrote:
~
> Do you have a patch around for improving next_timer_interrupt()?
> 
Well, sort of.  The code in the VST patch does the right thing.  Problem 
is it does a bit more than the timer.c code.  You can find that code on 
the HRT site CVS.
-- 
George Anzinger   george@mvista.com
HRT (High-res-timers):  http://sourceforge.net/projects/high-res-timers/

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

* Re: [PATCH] i386 No-Idle-Hz aka Dynamic-Ticks 5
  2005-08-10 22:37                 ` George Anzinger
@ 2005-08-11 21:33                   ` Bill Davidsen
  2005-08-12 15:13                     ` George Anzinger
  0 siblings, 1 reply; 68+ messages in thread
From: Bill Davidsen @ 2005-08-11 21:33 UTC (permalink / raw)
  To: george; +Cc: Andrew Morton, tony, linux-kernel, Adrian Bunk, ck,
	tuukka.tikkanen

George Anzinger wrote:
> Srivatsa Vaddagiri wrote:
> 
>> On Tue, Aug 09, 2005 at 12:36:58PM -0700, George Anzinger wrote:
>>
>>> IMNOHO, this is the ONLY way to keep proper time.  As soon as you 
>>> reprogram the PIT you have lost track of the time.
>>
>>
>>
>> George,
>>     Can't TSC (or equivalent) serve as a backup while PIT is disabled,
>> especially considering that we disable PIT only for short duration in 
>> practice (few seconds maybe) _and_ that we don't have HRT support yet?
>>
> I think it really depends on what you want.  If you really want to keep 
> good time, the only rock in town is the one connected to the PIT (and 
> the pmtimer).  The problem is, if you want the jiffie edge to be stable, 
> there is just now way to reprogram the PIT to get it back to where it was.
> 
> In an old version of HRT I did a trick of loading a short count (based 
> on reading the TSC or pmtimer) and then put the LATCH count on top of 
> it.  In a correctly performing PIT, it should count down the short 
> count, interrupt, load the long count and continue from there.  Aside 
> from the machines that had BAD PITs (they reset on the load instead of 
> the expiry of the current count) there were other problems that, in the 
> end, cause loss of time (too fast, too slow, take your pick).  I also 
> found PITs that signaled that they had loaded the count (they set a 
> status bit) prior to actually loading it.  All in all, I find the PIT is 
> just an ugly beast to try to program.  On the other hand, if you want 
> regular interrupts at some fixed period, it will do this forever (give 
> or take a epoch or two;) with out touching anything after the initial 
> program set up.
> 
> In the end, I concluded that, for the community kernel, it is really 
> best to just interrupt the irq line and leave the PIT run.  Then you use 
> the TSC or pmtimer to figure the gross loss of interrupts and leave the 
> PIT interrupt again to define the jiffie edge.  If you have other, more 
> pressing, concerns I suppose you can program the PIT, but don't expect 
> your wall clock to be as stable as it is now.
> 
What are the portability and scaling issues if it were done this way? It 
clearly looks practical on x86 uni, but if we want per-CPU non-tick, I'm 
less sure how it would work.

But when you go to non-x86 hardware, is there always going to be another 
source of wakeup available if the PIT is blocked instead of reset? I 
have to go back and look at how SPARC hardware works, I don't remember 
enough to be useful.

-- 
    -bill davidsen (davidsen@tmr.com)
"The secret to procrastination is to put things off until the
  last possible moment - but no longer"  -me

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

* Re: [PATCH] i386 No-Idle-Hz aka Dynamic-Ticks 5
  2005-08-11 21:33                   ` Bill Davidsen
@ 2005-08-12 15:13                     ` George Anzinger
  0 siblings, 0 replies; 68+ messages in thread
From: George Anzinger @ 2005-08-12 15:13 UTC (permalink / raw)
  To: Bill Davidsen
  Cc: Andrew Morton, tony, linux-kernel, Adrian Bunk, ck,
	tuukka.tikkanen

Bill Davidsen wrote:
> George Anzinger wrote:
> 
>> Srivatsa Vaddagiri wrote:
>>
>>> On Tue, Aug 09, 2005 at 12:36:58PM -0700, George Anzinger wrote:
>>>
>>>> IMNOHO, this is the ONLY way to keep proper time.  As soon as you 
>>>> reprogram the PIT you have lost track of the time.
>>>
>>>
>>>
>>>
>>> George,
>>>     Can't TSC (or equivalent) serve as a backup while PIT is disabled,
>>> especially considering that we disable PIT only for short duration in 
>>> practice (few seconds maybe) _and_ that we don't have HRT support yet?
>>>
>> I think it really depends on what you want.  If you really want to 
>> keep good time, the only rock in town is the one connected to the PIT 
>> (and the pmtimer).  The problem is, if you want the jiffie edge to be 
>> stable, there is just now way to reprogram the PIT to get it back to 
>> where it was.
>>
>> In an old version of HRT I did a trick of loading a short count (based 
>> on reading the TSC or pmtimer) and then put the LATCH count on top of 
>> it.  In a correctly performing PIT, it should count down the short 
>> count, interrupt, load the long count and continue from there.  Aside 
>> from the machines that had BAD PITs (they reset on the load instead of 
>> the expiry of the current count) there were other problems that, in 
>> the end, cause loss of time (too fast, too slow, take your pick).  I 
>> also found PITs that signaled that they had loaded the count (they set 
>> a status bit) prior to actually loading it.  All in all, I find the 
>> PIT is just an ugly beast to try to program.  On the other hand, if 
>> you want regular interrupts at some fixed period, it will do this 
>> forever (give or take a epoch or two;) with out touching anything 
>> after the initial program set up.
>>
>> In the end, I concluded that, for the community kernel, it is really 
>> best to just interrupt the irq line and leave the PIT run.  Then you 
>> use the TSC or pmtimer to figure the gross loss of interrupts and 
>> leave the PIT interrupt again to define the jiffie edge.  If you have 
>> other, more pressing, concerns I suppose you can program the PIT, but 
>> don't expect your wall clock to be as stable as it is now.
>>
> What are the portability and scaling issues if it were done this way? It 
> clearly looks practical on x86 uni, but if we want per-CPU non-tick, I'm 
> less sure how it would work.

I am not sure how much is involved.  For VST I disabled the tick 
generated NMI watchdog interrupt on a per cpu basis but stopped the PIT 
tick only when all cpus were idle.  The next step would be to mess with 
the interrupt steering logic to keep the tick away from idle cpus.  I 
did not get into this level in my work, being mainly interested in 
embedded systems.
> 
> But when you go to non-x86 hardware, is there always going to be another 
> source of wakeup available if the PIT is blocked instead of reset? I 
> have to go back and look at how SPARC hardware works, I don't remember 
> enough to be useful.

Most (all) other archs don't have PITs.  The x86 sucks big time when it 
comes to time keeping hardware.  The most common hardware is a counter 
that runs forever (much as the TSC but FIXED in frequency).  Interrupts 
are generated either by comparing a register to this or using companion 
counters that just count down to zero.  In either case you don't loose 
time because you can always precisely set up an interrupt.  To sleep, 
then, you just set your sleep time in the normal time base interrupt 
counter.  At the end, you know exactly what to set to get back to the 
regular tick.

These other platforms make VST and High Res Timers so easy...
-- 
George Anzinger   george@mvista.com
HRT (High-res-timers):  http://sourceforge.net/projects/high-res-timers/

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

* Re: [PATCH] i386 No-Idle-Hz aka Dynamic-Ticks 3
  2005-08-03 22:52       ` Con Kolivas
  2005-08-04  5:34         ` Jim MacBaine
@ 2005-08-14 19:47         ` Pavel Machek
  2005-08-15  1:43           ` Zwane Mwaikambo
  1 sibling, 1 reply; 68+ messages in thread
From: Pavel Machek @ 2005-08-14 19:47 UTC (permalink / raw)
  To: Con Kolivas; +Cc: Jim MacBaine, linux-kernel, ck, tony, tuukka.tikkanen

Hi!

> > > What happens when you disable it at runtime before suspending?
> > >
> > > echo 0 > /sys/devices/system/dyn_tick/dyn_tick0/enable
> >
> > This has no effect. The system stalls at exactly the same point. The
> > last lines on my screen are:
> 
> Ok perhaps on the resume side instead. When trying to resume can you try 
> booting with 'dyntick=disable'. Note this isn't meant to be a long term fix 
> but once we figure out where the problem is we should be able to code around 
> it.

Can you reproduce it using plain swsusp?

We probably need more carefull suspend/resume support on timer with dyntick
enabled.

With vanilla, timer just ticks on constant rate; no state to save.
With dyntick, however...
				Pavel
-- 
64 bytes from 195.113.31.123: icmp_seq=28 ttl=51 time=448769.1 ms         


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

* Re: [PATCH] i386 No-Idle-Hz aka Dynamic-Ticks 3
  2005-08-14 19:47         ` Pavel Machek
@ 2005-08-15  1:43           ` Zwane Mwaikambo
  2005-08-15 12:52             ` Con Kolivas
  0 siblings, 1 reply; 68+ messages in thread
From: Zwane Mwaikambo @ 2005-08-15  1:43 UTC (permalink / raw)
  To: Pavel Machek
  Cc: Con Kolivas, Jim MacBaine, linux-kernel, ck, tony,
	tuukka.tikkanen

On Sun, 14 Aug 2005, Pavel Machek wrote:

> > Ok perhaps on the resume side instead. When trying to resume can you try 
> > booting with 'dyntick=disable'. Note this isn't meant to be a long term fix 
> > but once we figure out where the problem is we should be able to code around 
> > it.
> 
> Can you reproduce it using plain swsusp?
> 
> We probably need more carefull suspend/resume support on timer with dyntick
> enabled.
> 
> With vanilla, timer just ticks on constant rate; no state to save.
> With dyntick, however...

Why not just set it to a fixed frequency, suspend and then on boot resume 
to a fixed frequency and let the timer tick code eventually switch back.

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

* Re: [PATCH] i386 No-Idle-Hz aka Dynamic-Ticks 3
  2005-08-15  1:43           ` Zwane Mwaikambo
@ 2005-08-15 12:52             ` Con Kolivas
  2005-08-15 15:39               ` Zwane Mwaikambo
  0 siblings, 1 reply; 68+ messages in thread
From: Con Kolivas @ 2005-08-15 12:52 UTC (permalink / raw)
  To: Zwane Mwaikambo
  Cc: Pavel Machek, Jim MacBaine, linux-kernel, ck, tony,
	tuukka.tikkanen

On Mon, 15 Aug 2005 11:43, Zwane Mwaikambo wrote:
> On Sun, 14 Aug 2005, Pavel Machek wrote:
> > > Ok perhaps on the resume side instead. When trying to resume can you
> > > try booting with 'dyntick=disable'. Note this isn't meant to be a long
> > > term fix but once we figure out where the problem is we should be able
> > > to code around it.
> >
> > Can you reproduce it using plain swsusp?
> >
> > We probably need more carefull suspend/resume support on timer with
> > dyntick enabled.
> >
> > With vanilla, timer just ticks on constant rate; no state to save.
> > With dyntick, however...
>
> Why not just set it to a fixed frequency, suspend and then on boot resume
> to a fixed frequency and let the timer tick code eventually switch back.

It's probably worth holding off further discussion on this point till the SMP 
scalable version is working well enough and see if/how the problem manifests 
there.

Cheers,
Con

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

* Re: [PATCH] i386 No-Idle-Hz aka Dynamic-Ticks 3
  2005-08-15 12:52             ` Con Kolivas
@ 2005-08-15 15:39               ` Zwane Mwaikambo
  0 siblings, 0 replies; 68+ messages in thread
From: Zwane Mwaikambo @ 2005-08-15 15:39 UTC (permalink / raw)
  To: Con Kolivas
  Cc: Pavel Machek, Jim MacBaine, linux-kernel, ck, tony,
	tuukka.tikkanen

On Mon, 15 Aug 2005, Con Kolivas wrote:

> > Why not just set it to a fixed frequency, suspend and then on boot resume
> > to a fixed frequency and let the timer tick code eventually switch back.
> 
> It's probably worth holding off further discussion on this point till the SMP 
> scalable version is working well enough and see if/how the problem manifests 
> there.

For suspend it'll manifest in the same way.

	Zwane


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

end of thread, other threads:[~2005-08-15 15:33 UTC | newest]

Thread overview: 68+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-08-03  5:59 [PATCH] i386 No-Idle-Hz aka Dynamic-Ticks 3 Con Kolivas
2005-08-03 11:54 ` Jan De Luyck
2005-08-03 12:14   ` Con Kolivas
2005-08-03 14:23     ` Jan De Luyck
2005-08-04 15:03       ` Vojtech Pavlik
2005-08-05  5:12         ` Con Kolivas
2005-08-03 19:20 ` Jim MacBaine
2005-08-03 21:16   ` Con Kolivas
2005-08-03 22:22     ` Jim MacBaine
2005-08-03 22:52       ` Con Kolivas
2005-08-04  5:34         ` Jim MacBaine
2005-08-04  6:59           ` Jim MacBaine
2005-08-04  7:04             ` Con Kolivas
2005-08-04  7:12               ` Con Kolivas
2005-08-04  7:29                 ` Tony Lindgren
2005-08-10 20:04             ` Bill Davidsen
2005-08-14 19:47         ` Pavel Machek
2005-08-15  1:43           ` Zwane Mwaikambo
2005-08-15 12:52             ` Con Kolivas
2005-08-15 15:39               ` Zwane Mwaikambo
2005-08-03 19:54 ` Jeffrey Hundstad
2005-08-03 20:07   ` Valdis.Kletnieks
2005-08-03 21:13   ` Con Kolivas
2005-08-03 23:22 ` Christian Leber
2005-08-04 16:25   ` Marc Ballarin
2005-08-04  5:09 ` Jan De Luyck
2005-08-04  5:07   ` Con Kolivas
2005-08-04  5:34     ` Jan De Luyck
2005-08-04 21:15 ` [PATCH] Timer Top was: " Daniel Petrini
2005-08-05  4:05   ` [PATCH] Timer Top tweaks Con Kolivas
2005-08-05  6:46   ` [ck] [PATCH] Timer Top was: i386 No-Idle-Hz aka Dynamic-Ticks 3 Jens Axboe
2005-08-05 12:39     ` Daniel Petrini
2005-08-05 13:55       ` Daniel Petrini
2005-08-04 21:44 ` [PATCH] " Adrian Bunk
2005-08-04 22:12 ` Marc Ballarin
2005-08-05  0:31   ` Con Kolivas
2005-08-05  1:30 ` Paul
2005-08-05  3:25   ` Con Kolivas
2005-08-05 12:37 ` Srivatsa Vaddagiri
2005-08-05 13:08   ` Con Kolivas
2005-08-05 16:39     ` [PATCH] i386 No-Idle-Hz aka Dynamic-Ticks 4 Con Kolivas
2005-08-06 17:47       ` Adrian Bunk
2005-08-07  5:12         ` [PATCH] i386 No-Idle-Hz aka Dynamic-Ticks 5 Con Kolivas
2005-08-07 16:58           ` Srivatsa Vaddagiri
2005-08-07 23:51             ` Con Kolivas
2005-08-08  1:20               ` Kyle Moffett
2005-08-08  1:30                 ` Con Kolivas
2005-08-08  1:45                   ` [ck] " Gabriel Devenyi
2005-08-08  2:44                   ` Srivatsa Vaddagiri
2005-08-08  7:05                     ` Nigel Cunningham
2005-08-08  7:38             ` Tony Lindgren
2005-08-08 15:06               ` Srivatsa Vaddagiri
2005-08-09 19:36             ` George Anzinger
2005-08-10 14:05               ` Srivatsa Vaddagiri
2005-08-10 22:37                 ` George Anzinger
2005-08-11 21:33                   ` Bill Davidsen
2005-08-12 15:13                     ` George Anzinger
2005-08-08 15:08           ` Folkert van Heusden
2005-08-08 15:16             ` Daniel Petrini
2005-08-08  7:26   ` [PATCH] i386 No-Idle-Hz aka Dynamic-Ticks 3 Tony Lindgren
2005-08-08 14:54     ` Srivatsa Vaddagiri
2005-08-08 15:20       ` Tony Lindgren
2005-08-09 14:22         ` Zwane Mwaikambo
2005-08-10  7:46           ` Tony Lindgren
2005-08-09 20:05     ` George Anzinger
2005-08-09 20:22       ` Daniel Petrini
2005-08-10  8:02       ` Tony Lindgren
2005-08-10 22:40         ` George Anzinger

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox