Skip to contentSkip to conversation

new timeofday core subsystem (v. B2)

PATCH In review john stultz 5 participants 17 messages Jun 9, 2005 – Jun 15, 2005

Subsystems (7)
lore
Share & tools
lore
#0 lore raw

PATCH 1/4 new timeofday core subsystem (v. B2)

Hey Everyone,
I'm heading out on vacation until Monday, so I'm just re-spinning my
current tree for testing. If there's no major issues on Monday, I'll re- diff against Andrew's tree and re-submit the patches for inclusion.

Included below is timeofday.c (which includes all the time of day management and accessor functions), ntp.c (which includes the ntp adjustment code, leapsecond processing, and ntp kernel state machine code), timesource.c (for timesource specific management functions), interface definition .h files, the example jiffies timesource (lowest common denominator time source, mainly for use as example code) and minimal hooks into arch independent code.

The patch does not function without minimal architecture specific hooks, and it should be able to be applied to a tree without affecting the existing code.

New in this version:
o Add kernel-parameters documentation for timesource= option
o Deprecate the clock= option
o Added clock= backwards compatibility w/ deprecation warning.
o Added documentation as a guide for assigning timesource priority values

Items still on the TODO list:
o Continued Testing
o Re-diff against -mm

thanks
-john

linux-2.6.12-rc6-git_timeofday-core_B2.patch
============================================

Documentation/kernel-parameters.txt (mode:100644) +6 -1
Index: Documentation/kernel-parameters.txt
===================================================================
@@ -52,6 +52,7 @@
 	MTD	MTD support is enabled.
 	NET	Appropriate network support is enabled.
 	NUMA	NUMA support is enabled.
+	NEW_TOD The new timeofday code is enabled.
 	NFS	Appropriate NFS support is enabled.
 	OSS	OSS sound support is enabled.
 	PARIDE	The ParIDE subsystem is enabled.
@@ -309,7 +310,7 @@
 			Default value is set via a kernel config option.
 			Value can be changed at runtime via /selinux/checkreqprot.
  
- 	clock=		[BUGS=IA-32, HW] gettimeofday timesource override. 
+ 	clock=		[BUGS=IA-32, HW] gettimeofday timesource override. [Deprecated]
 			Forces specified timesource (if avaliable) to be used
 			when calculating gettimeofday(). If specicified timesource
 			is not avalible, it defaults to PIT. 
@@ -1413,6 +1414,10 @@
 
 	time		Show timing data prefixed to each printk message line
 
+	timesource=		[NEW_TOD] Override the default timesource
+			Override the default timesource and use the timesource
+			with the name specified.
+
 	tipar.timeout=	[HW,PPT]
 			Set communications timeout in tenths of a second
 			(default 15).
drivers/Makefile (mode:100644) +1 -0
Index: drivers/Makefile
===================================================================
@@ -64,3 +64,4 @@
 obj-$(CONFIG_BLK_DEV_SGIIOC4)	+= sn/
 obj-y				+= firmware/
 obj-$(CONFIG_CRYPTO)		+= crypto/
+obj-$(CONFIG_NEWTOD)		+= timesource/
drivers/char/hangcheck-timer.c (mode:100644) +5 -0
Index: drivers/char/hangcheck-timer.c
===================================================================
@@ -49,6 +49,7 @@
 #include <linux/delay.h>
 #include <asm/uaccess.h>
 #include <linux/sysrq.h>
+#include <linux/timeofday.h>
 
 
 #define VERSION_STR "0.9.0"
@@ -130,8 +131,12 @@
 #endif
 
 #ifdef HAVE_MONOTONIC
+#ifndef CONFIG_NEWTOD
 extern unsigned long long monotonic_clock(void);
 #else
+#define monotonic_clock() do_monotonic_clock()
+#endif
+#else
 static inline unsigned long long monotonic_clock(void)
 {
 # ifdef __s390__
drivers/timesource/Makefile (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +1 -0
Index: drivers/timesource/Makefile
===================================================================
@@ -0,0 +1 @@
+obj-y += jiffies.o
drivers/timesource/jiffies.c (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +69 -0

69 lines not on this page · raw message

include/asm-generic/timeofday.h (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +26 -0
Index: include/asm-generic/timeofday.h
===================================================================
@@ -0,0 +1,26 @@
+/*  linux/include/asm-generic/timeofday.h
+ *
+ *  This file contains the asm-generic interface
+ *  to the arch specific calls used by the time of day subsystem
+ */
+#ifndef _ASM_GENERIC_TIMEOFDAY_H
+#define _ASM_GENERIC_TIMEOFDAY_H
+#include <linux/types.h>
+#include <linux/time.h>
+#include <linux/timex.h>
+#include <asm/div64.h>
+#ifdef CONFIG_NEWTOD
+
+/* Required externs */
+extern nsec_t read_persistent_clock(void);
+extern void sync_persistent_clock(struct timespec ts);
+
+#ifdef CONFIG_NEWTOD_VSYSCALL
+extern void arch_update_vsyscall_gtod(nsec_t wall_time, cycle_t offset_base,
+				struct timesource_t* timesource, int ntp_adj);
+#else
+#define arch_update_vsyscall_gtod(x,y,z,w) {}
+#endif
+
+#endif /* CONFIG_NEWTOD */
+#endif
include/linux/ntp.h (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +19 -0
Index: include/linux/ntp.h
===================================================================
@@ -0,0 +1,19 @@
+/*  linux/include/linux/ntp.h
+ *
+ *  This file NTP state machine accessor functions.
+ */
+
+#ifndef _LINUX_NTP_H
+#define _LINUX_NTP_H
+#include <linux/types.h>
+#include <linux/time.h>
+#include <linux/timex.h>
+
+/* NTP state machine interfaces */
+int ntp_advance(nsec_t value);
+int ntp_adjtimex(struct timex*);
+int ntp_leapsecond(struct timespec now);
+void ntp_clear(void);
+int get_ntp_status(void);
+
+#endif
include/linux/time.h (mode:100644) +4 -0
Index: include/linux/time.h
===================================================================
@@ -27,6 +27,10 @@
 
 #ifdef __KERNEL__
 
+/* timeofday base types */
+typedef u64 nsec_t;
+typedef u64 cycle_t;
+
 /* Parameters used to convert the timespec values */
 #ifndef USEC_PER_SEC
 #define USEC_PER_SEC (1000000L)
include/linux/timeofday.h (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +59 -0

59 lines not on this page · raw message

include/linux/timesource.h (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +171 -0

171 lines not on this page · raw message

include/linux/timex.h (mode:100644) +2 -0
Index: include/linux/timex.h
===================================================================
@@ -228,6 +228,7 @@
 extern unsigned long tick_nsec;		/* ACTHZ          period (nsec) */
 extern int tickadj;			/* amount of adjustment per tick */
 
+#ifndef CONFIG_NEWTOD
 /*
  * phase-lock loop variables
  */
@@ -314,6 +315,7 @@
 }
 
 #endif /* !CONFIG_TIME_INTERPOLATION */
+#endif /* !CONFIG_NEWTOD */
 
 #endif /* KERNEL */
 
init/main.c (mode:100644) +2 -0
Index: init/main.c
===================================================================
@@ -47,6 +47,7 @@
 #include <linux/rmap.h>
 #include <linux/mempolicy.h>
 #include <linux/key.h>
+#include <linux/timeofday.h>
 
 #include <asm/io.h>
 #include <asm/bugs.h>
@@ -467,6 +468,7 @@
 	pidhash_init();
 	init_timers();
 	softirq_init();
+	timeofday_init();
 	time_init();
 
 	/*
kernel/Makefile (mode:100644) +1 -0
Index: kernel/Makefile
===================================================================
@@ -9,6 +9,7 @@
 	    rcupdate.o intermodule.o extable.o params.o posix-timers.o \
 	    kthread.o wait.o kfifo.o sys_ni.o posix-cpu-timers.o
 
+obj-$(CONFIG_NEWTOD) += timeofday.o timesource.o ntp.o
 obj-$(CONFIG_FUTEX) += futex.o
 obj-$(CONFIG_GENERIC_ISA_DMA) += dma.o
 obj-$(CONFIG_SMP) += cpu.o spinlock.o
kernel/ntp.c (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +519 -0

519 lines not on this page · raw message

kernel/time.c (mode:100644) +18 -0
Index: kernel/time.c
===================================================================
@@ -38,6 +38,7 @@
 
 #include <asm/uaccess.h>
 #include <asm/unistd.h>
+#include <linux/timeofday.h>
 
 /* 
  * The timezone where the local system is located.  Used as a default by some
@@ -128,6 +129,7 @@
  * as real UNIX machines always do it. This avoids all headaches about
  * daylight saving times and warping kernel clocks.
  */
+#ifndef CONFIG_NEWTOD
 inline static void warp_clock(void)
 {
 	write_seqlock_irq(&xtime_lock);
@@ -137,6 +139,18 @@
 	write_sequnlock_irq(&xtime_lock);
 	clock_was_set();
 }
+#else /* !CONFIG_NEWTOD */
+/* XXX - this is somewhat cracked out and should
+         be checked  [email protected]
+*/
+inline static void warp_clock(void)
+{
+	struct timespec ts;
+	getnstimeofday(&ts);
+	ts.tv_sec += sys_tz.tz_minuteswest * 60;
+	do_settimeofday(&ts);
+}
+#endif /* !CONFIG_NEWTOD */
 
 /*
  * In case for some reason the CMOS clock has not already been running
@@ -227,6 +241,7 @@
 /* adjtimex mainly allows reading (and writing, if superuser) of
  * kernel time-keeping variables. used by xntpd.
  */
+#ifndef CONFIG_NEWTOD
 int do_adjtimex(struct timex *txc)
 {
         long ltemp, mtemp, save_adjust;
@@ -410,6 +425,7 @@
 	notify_arch_cmos_timer();
 	return(result);
 }
+#endif /* !CONFIG_NEWTOD */
 
 asmlinkage long sys_adjtimex(struct timex __user *txc_p)
 {
@@ -558,6 +574,7 @@
 
 
 #else
+#ifndef CONFIG_NEWTOD
 /*
  * Simulate gettimeofday using do_gettimeofday which only allows a timeval
  * and therefore only yields usec accuracy
@@ -570,6 +587,7 @@
 	tv->tv_sec = x.tv_sec;
 	tv->tv_nsec = x.tv_usec * NSEC_PER_USEC;
 }
+#endif /* !CONFIG_NEWTOD */
 #endif
 
 #if (BITS_PER_LONG < 64)
kernel/timeofday.c (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +607 -0

607 lines not on this page · raw message

kernel/timer.c (mode:100644) +4 -0
Index: kernel/timer.c
===================================================================
@@ -577,6 +577,7 @@
 int tickadj = 500/HZ ? : 1;		/* microsecs */
 
 
+#ifndef CONFIG_NEWTOD
 /*
  * phase-lock loop variables
  */
@@ -807,6 +808,9 @@
 		}
 	} while (ticks);
 }
+#else /* !CONFIG_NEWTOD */
+#define update_wall_time(x)
+#endif /* !CONFIG_NEWTOD */
 
 /*
  * Called from the timer interrupt handler to charge one tick to the current 
kernel/timesource.c (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +253 -0

253 lines not on this page · raw message

#1 lore raw

PATCH 2/4 new timeofday i386 arch specific changes (v. B2)

Hey Everyone,
I'm heading out on vacation until Monday, so I'm just re-spinning my
current tree for testing. If there's no major issues on Monday, I'll re- diff against Andrew's tree and re-submit the patches for inclusion.

This patch converts the i386 arch to use the new timeofday infrastructure. It applies on top of my timeofday-core_B2 patch. This is a full conversion, so most of this patch is subtractions removing the existing arch specific time keeping code. This patch does not provide any i386 timesources, so using this patch alone ontop of the timeofday- core patch will only give you the jiffies timesource. To get full replacements for the code being removed here, the following timeofday- timesources-i386 patch will need to be applied.

New in this version:
o Bit of infrastructure so we can get a better idea of how usable the TSC is
o Attempts to imrpove sched_clock() output in the printks
o Kill HZ assumptions in cpu_khz calibration code
o Merged with cpufreq changes in Linus' tree.

Items still on the TODO list:
o Continued Testing
o Re-diff against -mm

thanks
-john

linux-2.6.12-rc6-git_timeofday-arch-i386_B2.patch
=================================================

arch/i386/Kconfig (mode:100644) +4 -0
Index: arch/i386/Kconfig
===================================================================
@@ -14,6 +14,10 @@
 	  486, 586, Pentiums, and various instruction-set-compatible chips by
 	  AMD, Cyrix, and others.
 
+config NEWTOD
+	bool
+	default y
+
 config MMU
 	bool
 	default y
arch/i386/kernel/Makefile (mode:100644) +1 -2
Index: arch/i386/kernel/Makefile
===================================================================
@@ -7,10 +7,9 @@
 obj-y	:= process.o semaphore.o signal.o entry.o traps.o irq.o vm86.o \
 		ptrace.o time.o ioport.o ldt.o setup.o i8259.o sys_i386.o \
 		pci-dma.o i386_ksyms.o i387.o dmi_scan.o bootflag.o \
-		doublefault.o quirks.o
+		doublefault.o quirks.o tsc.o
 
 obj-y				+= cpu/
-obj-y				+= timers/
 obj-$(CONFIG_ACPI_BOOT)		+= acpi/
 obj-$(CONFIG_X86_BIOS_REBOOT)	+= reboot.o
 obj-$(CONFIG_MCA)		+= mca.o
arch/i386/kernel/acpi/boot.c (mode:100644) +6 -5
Index: arch/i386/kernel/acpi/boot.c
===================================================================
@@ -590,7 +590,8 @@
 #endif
 
 #ifdef CONFIG_X86_PM_TIMER
-extern u32 pmtmr_ioport;
+u32 acpi_pmtmr_ioport;
+int acpi_pmtmr_buggy;
 #endif
 
 static int __init acpi_parse_fadt(unsigned long phys, unsigned long size)
@@ -621,13 +622,13 @@
 		if (fadt->xpm_tmr_blk.address_space_id != ACPI_ADR_SPACE_SYSTEM_IO)
 			return 0;
 
-		pmtmr_ioport = fadt->xpm_tmr_blk.address;
+		acpi_pmtmr_ioport = fadt->xpm_tmr_blk.address;
 	} else {
 		/* FADT rev. 1 */
-		pmtmr_ioport = fadt->V1_pm_tmr_blk;
+		acpi_pmtmr_ioport = fadt->V1_pm_tmr_blk;
 	}
-	if (pmtmr_ioport)
-		printk(KERN_INFO PREFIX "PM-Timer IO Port: %#x\n", pmtmr_ioport);
+	if (acpi_pmtmr_ioport)
+		printk(KERN_INFO PREFIX "PM-Timer IO Port: %#x\n", acpi_pmtmr_ioport);
 #endif
 	return 0;
 }
arch/i386/kernel/i8259.c (mode:100644) +42 -0

48 lines not on this page · raw message

arch/i386/kernel/setup.c (mode:100644) +1 -0
Index: arch/i386/kernel/setup.c
===================================================================
@@ -1525,6 +1525,7 @@
 	conswitchp = &dummy_con;
 #endif
 #endif
+	tsc_init();
 }
 
 #include "setup_arch_post.h"
arch/i386/kernel/time.c (mode:100644) +34 -180

307 lines not on this page · raw message

dev/null (tree:19907869238c31316d8a80ab0b9f0e0e45a344a2) renamed from arch/i386/kernel/timers/Makefile (mode:100644) +0 -9
Index: arch/i386/kernel/timers/Makefile
===================================================================
@@ -1,9 +0,0 @@
-#
-# Makefile for x86 timers
-#
-
-obj-y := timer.o timer_none.o timer_tsc.o timer_pit.o common.o
-
-obj-$(CONFIG_X86_CYCLONE_TIMER)	+= timer_cyclone.o
-obj-$(CONFIG_HPET_TIMER)	+= timer_hpet.o
-obj-$(CONFIG_X86_PM_TIMER)	+= timer_pm.o
dev/null (tree:19907869238c31316d8a80ab0b9f0e0e45a344a2) renamed from arch/i386/kernel/timers/common.c (mode:100644) +0 -162

162 lines not on this page · raw message

dev/null (tree:19907869238c31316d8a80ab0b9f0e0e45a344a2) renamed from arch/i386/kernel/timers/timer.c (mode:100644) +0 -66

66 lines not on this page · raw message

dev/null (tree:19907869238c31316d8a80ab0b9f0e0e45a344a2) renamed from arch/i386/kernel/timers/timer_cyclone.c (mode:100644) +0 -259

259 lines not on this page · raw message

dev/null (tree:19907869238c31316d8a80ab0b9f0e0e45a344a2) renamed from arch/i386/kernel/timers/timer_hpet.c (mode:100644) +0 -194

194 lines not on this page · raw message

dev/null (tree:19907869238c31316d8a80ab0b9f0e0e45a344a2) renamed from arch/i386/kernel/timers/timer_none.c (mode:100644) +0 -39
Index: arch/i386/kernel/timers/timer_none.c
===================================================================
@@ -1,39 +0,0 @@
-#include <linux/init.h>
-#include <asm/timer.h>
-
-static void mark_offset_none(void)
-{
-	/* nothing needed */
-}
-
-static unsigned long get_offset_none(void)
-{
-	return 0;
-}
-
-static unsigned long long monotonic_clock_none(void)
-{
-	return 0;
-}
-
-static void delay_none(unsigned long loops)
-{
-	int d0;
-	__asm__ __volatile__(
-		"\tjmp 1f\n"
-		".align 16\n"
-		"1:\tjmp 2f\n"
-		".align 16\n"
-		"2:\tdecl %0\n\tjns 2b"
-		:"=&a" (d0)
-		:"0" (loops));
-}
-
-/* none timer_opts struct */
-struct timer_opts timer_none = {
-	.name = 	"none",
-	.mark_offset =	mark_offset_none, 
-	.get_offset =	get_offset_none,
-	.monotonic_clock =	monotonic_clock_none,
-	.delay = delay_none,
-};
dev/null (tree:19907869238c31316d8a80ab0b9f0e0e45a344a2) renamed from arch/i386/kernel/timers/timer_pit.c (mode:100644) +0 -206

206 lines not on this page · raw message

dev/null (tree:19907869238c31316d8a80ab0b9f0e0e45a344a2) renamed from arch/i386/kernel/timers/timer_pm.c (mode:100644) +0 -258

258 lines not on this page · raw message

dev/null (tree:19907869238c31316d8a80ab0b9f0e0e45a344a2) renamed from arch/i386/kernel/timers/timer_tsc.c (mode:100644) +0 -580

580 lines not on this page · raw message

arch/i386/kernel/tsc.c (mode:100644) renamed from dev/null (tree:00e808a96ae388482e12d64053b45f880799cb67) +220 -0

220 lines not on this page · raw message

arch/i386/lib/delay.c (mode:100644) +13 -3
Index: arch/i386/lib/delay.c
===================================================================
@@ -13,6 +13,7 @@
 #include <linux/config.h>
 #include <linux/sched.h>
 #include <linux/delay.h>
+#include <linux/timeofday.h>
 #include <asm/processor.h>
 #include <asm/delay.h>
 #include <asm/timer.h>
@@ -21,11 +22,20 @@
 #include <asm/smp.h>
 #endif
 
-extern struct timer_opts* timer;
-
+/* XXX - For now just use a simple loop delay
+ *  This has cpufreq issues, but so did the old method.
+ */
 void __delay(unsigned long loops)
 {
-	cur_timer->delay(loops);
+	int d0;
+	__asm__ __volatile__(
+		"\tjmp 1f\n"
+		".align 16\n"
+		"1:\tjmp 2f\n"
+		".align 16\n"
+		"2:\tdecl %0\n\tjns 2b"
+		:"=&a" (d0)
+		:"0" (loops));
 }
 
 inline void __const_udelay(unsigned long xloops)
include/asm-generic/timeofday.h (mode:100644) +1 -1
Index: include/asm-generic/timeofday.h
===================================================================
@@ -20,7 +20,7 @@
 				struct timesource_t* timesource, int ntp_adj);
 #else
 #define arch_update_vsyscall_gtod(x,y,z,w) {}
-#endif
+#endif /* CONFIG_NEWTOD_VSYSCALL */
 
 #endif /* CONFIG_NEWTOD */
 #endif
include/asm-i386/mach-default/mach_timer.h (mode:100644) +5 -1
Index: include/asm-i386/mach-default/mach_timer.h
===================================================================
@@ -14,8 +14,12 @@
  */
 #ifndef _MACH_TIMER_H
 #define _MACH_TIMER_H
+#include <linux/jiffies.h>
+#include <asm/io.h>
 
-#define CALIBRATE_LATCH	(5 * LATCH)
+#define CALIBRATE_TIME_MSEC 30 /* 30 msecs */
+#define CALIBRATE_LATCH	\
+	((CLOCK_TICK_RATE * CALIBRATE_TIME_MSEC + 1000/2)/1000)
 
 static inline void mach_prepare_counter(void)
 {
include/asm-i386/mach-summit/mach_mpparse.h (mode:100644) +2 -0
Index: include/asm-i386/mach-summit/mach_mpparse.h
===================================================================
@@ -30,6 +30,7 @@
 			(!strncmp(productid, "VIGIL SMP", 9) 
 			 || !strncmp(productid, "EXA", 3)
 			 || !strncmp(productid, "RUTHLESS SMP", 12))){
+		mark_tsc_unstable();
 		use_cyclone = 1; /*enable cyclone-timer*/
 		setup_summit();
 		usb_early_handoff = 1;
@@ -44,6 +45,7 @@
 	if (!strncmp(oem_id, "IBM", 3) &&
 	    (!strncmp(oem_table_id, "SERVIGIL", 8)
 	     || !strncmp(oem_table_id, "EXA", 3))){
+		mark_tsc_unstable();
 		use_cyclone = 1; /*enable cyclone-timer*/
 		setup_summit();
 		usb_early_handoff = 1;
include/asm-i386/timeofday.h (mode:100644) renamed from dev/null (tree:00e808a96ae388482e12d64053b45f880799cb67) +4 -0
Index: include/asm-i386/timeofday.h
===================================================================
@@ -0,0 +1,4 @@
+#ifndef _ASM_I386_TIMEOFDAY_H
+#define _ASM_I386_TIMEOFDAY_H
+#include <asm-generic/timeofday.h>
+#endif
include/asm-i386/timer.h (mode:100644) +0 -53

64 lines not on this page · raw message

include/asm-i386/timex.h (mode:100644) +5 -1
Index: include/asm-i386/timex.h
===================================================================
@@ -16,6 +16,8 @@
 #endif
 
 
+/* XXX - All of this should likely move elsewhere [email protected]*/
+
 /*
  * Standard way to access the cycle counter on i586+ CPUs.
  * Currently only used on SMP.
@@ -48,5 +50,7 @@
 }
 
 extern unsigned long cpu_khz;
-
+extern void tsc_init(void);
+extern int check_tsc_unstable(void);
+extern void mark_tsc_unstable(void);
 #endif
#2 lore raw

PATCH 3/4 new timeofday x86-64 arch specific changes (v. B2)

Hey Everyone,
I'm heading out on vacation until Monday, so I'm just re-spinning my
current tree for testing. If there's no major issues on Monday, I'll re- diff against Andrew's tree and re-submit the patches for inclusion.

This patch converts the x86-64 arch to use the new timeofday infrastructure. It applies on top of my timeofday-core_B2 patch. This is a full conversion, so most of this patch is subtractions removing the existing arch specific time keeping code.

This patch does not provide any x86-64 timesources, so using this patch alone on top of the timeofday-core patch will only give you the jiffies timesource. To get full replacements for the code being removed here, the following timeofday-timesources-i386 patch (x86-64 shares the same timesources as i386) will need to be applied.

I haven't had a chance to test this patch on an x86-64 system, but little has changed and I did verify that it builds. I apologize if you run into trouble.

New in this version:
o Minor changes to support the TSC auto-demotion code.

Todo Items:
o Continued Testing
o vsyscall cleanups
o Review and ACK from Andi
o Re-diff against -mm

thanks
-john

linux-2.6.12-rc6-git_timeofday-arch-x86-64_B2.patch
===================================================

arch/i386/kernel/acpi/boot.c (mode:100644) +3 -9
Index: arch/i386/kernel/acpi/boot.c
===================================================================
@@ -547,7 +547,7 @@
 
 
 #ifdef CONFIG_HPET_TIMER
-
+#include <asm/hpet.h>
 static int __init acpi_parse_hpet(unsigned long phys, unsigned long size)
 {
 	struct acpi_table_hpet *hpet_tbl;
@@ -570,18 +570,12 @@
 #ifdef	CONFIG_X86_64
         vxtime.hpet_address = hpet_tbl->addr.addrl |
                 ((long) hpet_tbl->addr.addrh << 32);
-
-        printk(KERN_INFO PREFIX "HPET id: %#x base: %#lx\n",
-               hpet_tbl->id, vxtime.hpet_address);
+	hpet_address = vxtime.hpet_address;
 #else	/* X86 */
-	{
-		extern unsigned long hpet_address;
-
 		hpet_address = hpet_tbl->addr.addrl;
+#endif	/* X86 */
 		printk(KERN_INFO PREFIX "HPET id: %#x base: %#lx\n",
 			hpet_tbl->id, hpet_address);
-	}
-#endif	/* X86 */
 
 	return 0;
 }
arch/x86_64/Kconfig (mode:100644) +8 -0
Index: arch/x86_64/Kconfig
===================================================================
@@ -24,6 +24,14 @@
 	bool
 	default y
 
+config NEWTOD
+       bool
+       default y
+
+config NEWTOD_VSYSCALL
+       bool
+       default y
+
 config MMU
 	bool
 	default y
arch/x86_64/kernel/Makefile (mode:100644) +0 -1
Index: arch/x86_64/kernel/Makefile
===================================================================
@@ -28,7 +28,6 @@
 obj-$(CONFIG_DUMMY_IOMMU)	+= pci-nommu.o pci-dma.o
 obj-$(CONFIG_SWIOTLB)		+= swiotlb.o
 obj-$(CONFIG_KPROBES)		+= kprobes.o
-obj-$(CONFIG_X86_PM_TIMER)	+= pmtimer.o
 
 obj-$(CONFIG_MODULES)		+= module.o
 
dev/null (tree:568737ffc050110f45cd3c8c3936ad5b100ae6aa) renamed from arch/x86_64/kernel/pmtimer.c (mode:100644) +0 -101

101 lines not on this page · raw message

arch/x86_64/kernel/time.c (mode:100644) +28 -313

434 lines not on this page · raw message

arch/x86_64/kernel/vmlinux.lds.S (mode:100644) +7 -0
Index: arch/x86_64/kernel/vmlinux.lds.S
===================================================================
@@ -71,6 +71,13 @@
   . = ALIGN(CONFIG_X86_L1_CACHE_BYTES);
   .jiffies : AT CACHE_ALIGN(AFTER(.xtime)) { *(.jiffies) }
   jiffies = LOADADDR(.jiffies);
+
+  .vsyscall_gtod_data : AT AFTER(.jiffies) { *(.vsyscall_gtod_data) }
+  vsyscall_gtod_data = LOADADDR(.vsyscall_gtod_data);
+  .vsyscall_gtod_lock : AT AFTER(.vsyscall_gtod_data) { *(.vsyscall_gtod_lock) }
+  vsyscall_gtod_lock = LOADADDR(.vsyscall_gtod_lock);
+
+
   .vsyscall_1 ADDR(.vsyscall_0) + 1024: AT (LOADADDR(.vsyscall_0) + 1024) { *(.vsyscall_1) }
   . = LOADADDR(.vsyscall_0) + 4096;
 
arch/x86_64/kernel/vsyscall.c (mode:100644) +104 -30

183 lines not on this page · raw message

include/asm-generic/div64.h (mode:100644) +9 -0
Index: include/asm-generic/div64.h
===================================================================
@@ -55,4 +55,13 @@
 
 #endif /* BITS_PER_LONG */
 
+#ifndef div_long_long_rem
+#define div_long_long_rem(dividend,divisor,remainder) \
+({							\
+	u64 result = dividend;				\
+	*remainder = do_div(result,divisor);		\
+	result;						\
+})
+#endif
+
 #endif /* _ASM_GENERIC_DIV64_H */
include/asm-x86_64/hpet.h (mode:100644) +2 -1
Index: include/asm-x86_64/hpet.h
===================================================================
@@ -1,6 +1,6 @@
 #ifndef _ASM_X8664_HPET_H
 #define _ASM_X8664_HPET_H 1
-
+#include <asm/fixmap.h>
 /*
  * Documentation on HPET can be found at:
  *      http://www.intel.com/ial/home/sp/pcmmspec.htm
@@ -44,6 +44,7 @@
 #define HPET_TN_SETVAL		0x040
 #define HPET_TN_32BIT		0x100
 
+extern unsigned long hpet_address;	/* hpet memory map physical address */
 extern int is_hpet_enabled(void);
 extern int hpet_rtc_timer_init(void);
 extern int oem_force_hpet_timer(void);
include/asm-x86_64/timeofday.h (mode:100644) renamed from dev/null (tree:00e808a96ae388482e12d64053b45f880799cb67) +4 -0
Index: include/asm-x86_64/timeofday.h
===================================================================
@@ -0,0 +1,4 @@
+#ifndef _ASM_X86_64_TIMEOFDAY_H
+#define _ASM_X86_64_TIMEOFDAY_H
+#include <asm-generic/timeofday.h>
+#endif
include/asm-x86_64/timex.h (mode:100644) +1 -0
Index: include/asm-x86_64/timex.h
===================================================================
@@ -25,6 +25,7 @@
 }
 
 extern unsigned int cpu_khz;
+extern int check_tsc_unstable(void);
 
 extern struct vxtime_data vxtime;
 
include/asm-x86_64/vsyscall.h (mode:100644) +2 -0
Index: include/asm-x86_64/vsyscall.h
===================================================================
@@ -22,6 +22,8 @@
 #define __section_sysctl_vsyscall __attribute__ ((unused, __section__ (".sysctl_vsyscall"), aligned(16)))
 #define __section_xtime __attribute__ ((unused, __section__ (".xtime"), aligned(16)))
 #define __section_xtime_lock __attribute__ ((unused, __section__ (".xtime_lock"), aligned(16)))
+#define __section_vsyscall_gtod_data __attribute__ ((unused, __section__ (".vsyscall_gtod_data"),aligned(16)))
+#define __section_vsyscall_gtod_lock __attribute__ ((unused, __section__ (".vsyscall_gtod_lock"),aligned(16)))
 
 #define VXTIME_TSC	1
 #define VXTIME_HPET	2
#3 lore raw

PATCH 4/4 new timeofday i386/x86-64 timesources (v. B2)

All,
I'm heading out on vacation until Monday, so I'm just re-spinning my
current tree for testing. If there's no major issues on Monday, I'll re- diff against Andrew's tree and re-submit the patches for inclusion.

This patch implements the time sources shared between i386 and x86-64 (acpi_pm, cyclone, hpet, pit, tsc and tsc-interp). The patch should apply ontop of either of the timeofday-arch-*_B2.patches. The patch is fairly straight forward, only adding the new timesources.

New in this release:
o Raise the TSC's default priority value
o TSC auto-demotion code
o ACPI PM uses single read only, and fall back to triple read if necessary
o Infrastructure to blacklist single read ACPI PM for buggy chipsets

Todo Items:
o Continued Testing
o Re-diff against -mm

thanks
-john

drivers/acpi/processor_idle.c (mode:100644) +5 -0
Index: drivers/acpi/processor_idle.c
===================================================================
@@ -162,6 +162,7 @@
 	return;
 }
 
+extern void tsc_c3_compensate(unsigned long usecs);
 
 static void acpi_processor_idle (void)
 {
@@ -309,6 +310,10 @@
 		t2 = inl(acpi_fadt.xpm_tmr_blk.address);
 		/* Enable bus master arbitration */
 		acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0, ACPI_MTX_DO_NOT_LOCK);
+
+		/* compensate for TSC pause */
+		tsc_c3_compensate((((t2-t1)&0xFFFFFF)*286)>>10);
+
 		/* Re-enable interrupts */
 		local_irq_enable();
 		/* Compute time (ticks) that we were actually asleep */
drivers/timesource/Makefile (mode:100644) +7 -0
Index: drivers/timesource/Makefile
===================================================================
@@ -1 +1,8 @@
 obj-y += jiffies.o
+
+obj-$(CONFIG_X86) += tsc.o
+obj-$(CONFIG_X86) += i386_pit.o
+obj-$(CONFIG_X86) += tsc-interp.o
+obj-$(CONFIG_X86_CYCLONE_TIMER) += cyclone.o
+obj-$(CONFIG_X86_PM_TIMER) += acpi_pm.o
+obj-$(CONFIG_HPET_TIMER) += hpet.o
drivers/timesource/acpi_pm.c (mode:100644) renamed from dev/null (tree:19907869238c31316d8a80ab0b9f0e0e45a344a2) +153 -0

153 lines not on this page · raw message

drivers/timesource/cyclone.c (mode:100644) renamed from dev/null (tree:19907869238c31316d8a80ab0b9f0e0e45a344a2) +138 -0

138 lines not on this page · raw message

drivers/timesource/hpet.c (mode:100644) renamed from dev/null (tree:19907869238c31316d8a80ab0b9f0e0e45a344a2) +59 -0

59 lines not on this page · raw message

drivers/timesource/i386_pit.c (mode:100644) renamed from dev/null (tree:19907869238c31316d8a80ab0b9f0e0e45a344a2) +64 -0

64 lines not on this page · raw message

drivers/timesource/tsc-interp.c (mode:100644) renamed from dev/null (tree:19907869238c31316d8a80ab0b9f0e0e45a344a2) +115 -0

115 lines not on this page · raw message

drivers/timesource/tsc.c (mode:100644) renamed from dev/null (tree:19907869238c31316d8a80ab0b9f0e0e45a344a2) +102 -0

102 lines not on this page · raw message

#4 lore raw
In reply to john stultz

Hi John,

Some coding style comments below.

Pekka

Quoted 5 lines · john stultz

Index: include/linux/timesource.h
===================================================================

include/linux/timesource.h (mode:100644) line 9

Quoted 9 lines
include/linux/timesource.h (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +9 -0
@@ -0,0 +1,171 @@
+/*  linux/include/linux/timesource.h
+ *
+ *  This file contains the structure definitions for timesources.
+ *
+ *  If you are not a timesource, or the time of day code, you should
+ *  not be including this file!
+ */
+#ifndef _LINUX_TIMESORUCE_H
+#define _LINUX_TIMESORUCE_H

Typo.

Quoted 9 lines
include/linux/timesource.h (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +8 -0
+++ 00e808a96ae388482e12d64053b45f880799cb67/kernel/ntp.c  (mode:100644)
@@ -0,0 +1,519 @@
+/********************************************************************
+* linux/kernel/ntp.c
+*
+* Revision History:
+* 2004-09-02:  A0
+*   o First pass sent to lkml for review.
+* 2004-12-07:  A1

include/linux/timesource.h (mode:100644) line 17

Quoted 10 lines
include/linux/timesource.h (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +10 -0
+*   o No changes, sent to lkml for review.
+* 2005-03-11:  A3
+*   o yanked ntp_scale(), ntp adjustments are done in cyc2ns
+* 2005-04-29:  A4
+*   o Added conditional debug info
+* 2005-05-12:  A5
+*   o comment cleanups
+* 2005-05-31:  B0
+*   o comment cleanups
+*	o Improved rounding

Please drop this (useless) revision history.

Quoted 16 lines
include/linux/timesource.h (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +16 -0
+/* NTP scaling code
+ * Functions:
+ * ----------
+ * nsec_t ntp_scale(nsec_t value):
+ *      Scales the nsec_t vale using ntp kernel state
+ * void ntp_advance(nsec_t interval):
+ *      Increments the NTP state machine by interval time
+ * static int ntp_hardupdate(long offset, struct timeval tv)
+ *      ntp_adjtimex helper function
+ * int ntp_adjtimex(struct timex* tx):
+ *      Interface to adjust NTP state machine
+ * int ntp_leapsecond(struct timespec now)
+ *      Does NTP leapsecond processing. Returns number of
+ *      seconds current time should be adjusted by.
+ * void ntp_clear(void):
+ *      Clears the ntp kernel state

include/linux/timesource.h (mode:100644) line 43

Quoted 10 lines
include/linux/timesource.h (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +10 -0
+ * int get_ntp_status(void):
+ *      returns ntp_status value
+ *
+ * Variables:
+ * ----------
+ * ntp kernel state variables:
+ *      See below for full list.
+ * ntp_lock:
+ *      Protects ntp kernel state variables
+ */

Please drop the above ToC as it is not even up to date anymore (at least ntp_scale is gone).

include/linux/timesource.h (mode:100644) line 51

Quoted 8 lines
include/linux/timesource.h (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +8 -0
+int ntp_advance(nsec_t interval)
+{
+	static u64 interval_sum = 0;
+	static long ss_adj = 0;
+	unsigned long flags;
+	long ppm_sum;
+
+	/* inc interval sum */

Please drop this redundant comment.

include/linux/timesource.h (mode:100644) line 56

Quoted 5 lines
include/linux/timesource.h (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +5 -0
+	interval_sum += interval;
+
+	write_seqlock_irqsave(&ntp_lock, flags);
+
+	/* decrement singleshot offset interval */

Ditto.

include/linux/timesource.h (mode:100644) line 58

Quoted 2 lines
include/linux/timesource.h (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +2 -0
+	ss_offset_len -= interval;
+	if(ss_offset_len < 0) /* make sure it doesn't go negative */

Ditto.

include/linux/timesource.h (mode:100644) line 61

Quoted 3 lines
include/linux/timesource.h (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +3 -0
+		ss_offset_len = 0;
+
+	/* Do second overflow code */

Highly confusing comment. Preferred fix is to drop it.

include/linux/timesource.h (mode:100644) line 69

Quoted 8 lines
include/linux/timesource.h (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +8 -0
+	while (interval_sum > NSEC_PER_SEC) {
+		/* XXX - I'd prefer to smoothly apply this math
+		 * at each call to ntp_advance() rather then each
+		 * second.
+		 */
+		long tmp;
+
+		/* Bump maxerror by ntp_tolerance */

Drop redundant comment.

include/linux/timesource.h (mode:100644) line 76

Quoted 7 lines
include/linux/timesource.h (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +7 -0
+		ntp_maxerror += shiftR(ntp_tolerance, SHIFT_USEC);
+		if (ntp_maxerror > NTP_PHASE_LIMIT) {
+			ntp_maxerror = NTP_PHASE_LIMIT;
+			ntp_status |= STA_UNSYNC;
+		}
+
+		/* Calculate offset_adj for the next second */

Ditto.

include/linux/timesource.h (mode:100644) line 77

Quoted 1 line
include/linux/timesource.h (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +1 -0
+		tmp = ntp_offset;

tmp could use a more descriptive name.

include/linux/timesource.h (mode:100644) line 81

Quoted 4 lines
include/linux/timesource.h (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +4 -0
+		if (!(ntp_status & STA_FLL))
+		    tmp = shiftR(tmp, SHIFT_KG + ntp_constant);
+
+		/* bound the adjustment to MAXPHASE/MINSEC */

Redundant comment.

include/linux/timesource.h (mode:100644) line 90

Quoted 9 lines
include/linux/timesource.h (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +9 -0
+		tmp = min(tmp, (MAXPHASE / MINSEC) << SHIFT_UPDATE);
+		tmp = max(tmp, -(MAXPHASE / MINSEC) << SHIFT_UPDATE);
+
+		offset_adj = shiftR(tmp, SHIFT_UPDATE); /* (usec/sec) = ppm */
+		ntp_offset -= tmp;
+
+		interval_sum -= NSEC_PER_SEC;
+
+		/* calculate singleshot aproximation ppm for the next second */

Ditto.

include/linux/timesource.h (mode:100644) line 96

Quoted 6 lines
include/linux/timesource.h (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +6 -0
+/**
+ * ntp_hardupdate - Calculates the offset and freq values
+ * offset: current offset
+ * tv: timeval holding the current time
+ *
+ * Private function, called only by ntp_adjtimex while holding ntp_lock

All static functions are private so why duplicate that in the comment?

Quoted 5 lines
include/linux/timesource.h (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +5 -0
+ *
+ * This function is called when an offset adjustment is requested.
+ * It calculates the offset adjustment and manipulates the
+ * frequency adjustement accordingly.
+ */

include/linux/timesource.h (mode:100644) line 111

Quoted 10 lines
include/linux/timesource.h (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +10 -0
+static int ntp_hardupdate(long offset, struct timeval tv)
+{
+	int ret;
+	long tmp, interval;
+
+	ret = 0;
+	if (!(ntp_status & STA_PLL))
+		return ret;
+
+	tmp = offset;

tmp could use a better name. new_offset?

include/linux/timesource.h (mode:100644) line 112

Quoted 1 line
include/linux/timesource.h (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +1 -0
+	/* Make sure offset is bounded by MAXPHASE */

Redundant comment.

include/linux/timesource.h (mode:100644) line 121

Quoted 9 lines
include/linux/timesource.h (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +9 -0
+	tmp = min(tmp, MAXPHASE);
+	tmp = max(tmp, -MAXPHASE);
+
+	ntp_offset = tmp << SHIFT_UPDATE;
+
+	if ((ntp_status & STA_FREQHOLD) || (ntp_reftime == 0))
+		ntp_reftime = tv.tv_sec;
+
+	/* calculate seconds since last call to hardupdate */

Ditto.

include/linux/timesource.h (mode:100644) line 127

Quoted 6 lines
include/linux/timesource.h (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +6 -0
+	interval = tv.tv_sec - ntp_reftime;
+	ntp_reftime = tv.tv_sec;
+
+	if ((ntp_status & STA_FLL) && (interval >= MINSEC)) {
+		long damping;
+		/* calculate frequency for this interval */

Redundant comment. tmp could use a better name. Introduce a new variable.

include/linux/timesource.h (mode:100644) line 130

Quoted 3 lines
include/linux/timesource.h (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +3 -0
+		tmp = (offset + interval/2) / interval; /* ppm (usec/sec)*/
+
+		/* calculate damping factor */

Redundant comment.

include/linux/timesource.h (mode:100644) line 133

Quoted 3 lines
include/linux/timesource.h (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +3 -0
+		damping = SHIFT_KH - SHIFT_USEC;
+
+		/* convert to shifted ppm, then apply damping factor */

Redundant comment.

include/linux/timesource.h (mode:100644) line 141

Quoted 8 lines
include/linux/timesource.h (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +8 -0
+		ntp_freq += shiftR(tmp,damping);
+#if NTP_DEBUG
+		printk("ntp->freq change: %ld\n",shiftR(tmp,damping));
+#endif
+
+	} else if ((ntp_status & STA_PLL) && (interval < MAXSEC)) {
+		long damping;
+		tmp = offset * interval;

tmp could use a better name. Introduce a new variable.

include/linux/timesource.h (mode:100644) line 143

Quoted 2 lines
include/linux/timesource.h (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +2 -0
+
+		/* calculate damping factor */

Redundant comment.

include/linux/timesource.h (mode:100644) line 146

Quoted 3 lines
include/linux/timesource.h (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +3 -0
+		damping = (2 * ntp_constant) + SHIFT_KF - SHIFT_USEC;
+
+		/* apply damping factor */

Redundant comment.

include/linux/timesource.h (mode:100644) line 152

Quoted 6 lines
include/linux/timesource.h (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +6 -0
+		ntp_freq += shiftR(tmp,damping);
+
+#if NTP_DEBUG
+		printk("ntp->freq change: %ld\n", shiftR(tmp,damping));
+#endif
+	} else { /* interval out of bounds */

Redundant comment.

include/linux/timesource.h (mode:100644) line 157

Quoted 5 lines
include/linux/timesource.h (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +5 -0
+#if NTP_DEBUG
+		printk("ntp_hardupdate(): interval out of bounds: %ld status: 0x%x\n",
+				interval, ntp_status);
+#endif
+		ret = -1; /* TIME_ERROR */

Use constant instead of comment.

include/linux/timesource.h (mode:100644) line 160

Quoted 3 lines
include/linux/timesource.h (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +3 -0
+	}
+
+	/* bound ntp_freq */

Redundant comment.

Quoted 11 lines
include/linux/timesource.h (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +11 -0
+	if (ntp_freq > ntp_tolerance)
+		ntp_freq = ntp_tolerance;
+	if (ntp_freq < -ntp_tolerance)
+		ntp_freq = -ntp_tolerance;
+
+	return ret;
+}
+
+/**
+ * ntp_adjtimex - Interface to change NTP state machine
+ * @tx: timex value passed to the kernel to be used

include/linux/timesource.h (mode:100644) line 181

Quoted 10 lines
include/linux/timesource.h (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +10 -0
+ */
+int ntp_adjtimex(struct timex* tx)
+{
+	long save_offset;
+	int result;
+	unsigned long flags;
+
+/* Sanity checking
+ */
+	/* frequency adjustment limited to +/- MAXFREQ */

Redundant comment.

include/linux/timesource.h (mode:100644) line 183

Quoted 2 lines
include/linux/timesource.h (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +2 -0
+	if ((tx->modes & ADJ_FREQUENCY)
+			&& (abs(tx->freq) > MAXFREQ))

Spurious parenthesis.

Quoted 25 lines
include/linux/timesource.h (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +25 -0
+		return -EINVAL;
+
+	/* maxerror adjustment limited to NTP_PHASE_LIMIT */
+	if ((tx->modes & ADJ_MAXERROR)
+			&& (tx->maxerror < 0
+				|| tx->maxerror >= NTP_PHASE_LIMIT))
+		return -EINVAL;
+
+	/* esterror adjustment limited to NTP_PHASE_LIMIT */
+	if ((tx->modes & ADJ_ESTERROR)
+			&& (tx->esterror < 0
+				|| tx->esterror >= NTP_PHASE_LIMIT))
+		return -EINVAL;
+
+	/* constant adjustment must be positive */
+	if ((tx->modes & ADJ_TIMECONST)
+			&& (tx->constant < 0))
+		return -EINVAL;
+
+	/* Single shot mode can only be used by itself */
+	if (((tx->modes & ADJ_OFFSET_SINGLESHOT) == ADJ_OFFSET_SINGLESHOT)
+			&& (tx->modes != ADJ_OFFSET_SINGLESHOT))
+		return -EINVAL;
+
+	/* offset adjustment limited to +/- MAXPHASE */

include/linux/timesource.h (mode:100644) line 218

Quoted 10 lines
include/linux/timesource.h (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +10 -0
+	if ((tx->modes != ADJ_OFFSET_SINGLESHOT)
+			&& (tx->modes & ADJ_OFFSET)
+			&& (abs(tx->offset)>= MAXPHASE))
+		return -EINVAL;
+
+	/* tick adjustment limited to 10% */
+	if ((tx->modes & ADJ_TICK)
+			&& ((tx->tick < 900000/USER_HZ)
+				||(tx->tick > 11000000/USER_HZ)))
+		return -EINVAL;

Ditto for all the above if statements.

include/linux/timesource.h (mode:100644) line 228

Quoted 10 lines
include/linux/timesource.h (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +10 -0
+
+#if NTP_DEBUG
+	if(tx->modes) {
+		printk("adjtimex: tx->offset: %ld    tx->freq: %ld\n",
+				tx->offset, tx->freq);
+	}
+#endif
+
+/* Kernel input bits
+ */

Strange comment. Extract function rather than introduce 'place holder' comments such as the above.

include/linux/timesource.h (mode:100644) line 236

Quoted 8 lines
include/linux/timesource.h (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +8 -0
+	write_seqlock_irqsave(&ntp_lock, flags);
+
+	result = ntp_state;
+
+	/* For ADJ_OFFSET_SINGLESHOT we must return the old offset */
+	save_offset = shiftR(ntp_offset, SHIFT_UPDATE);
+
+	/* Process input parameters */

Redundant comment.

Quoted 9 lines
include/linux/timesource.h (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +9 -0
+	if (tx->modes & ADJ_STATUS) {
+		ntp_status &=  STA_RONLY;
+		ntp_status |= tx->status & ~STA_RONLY;
+	}
+
+	if (tx->modes & ADJ_FREQUENCY)
+		ntp_freq = tx->freq;
+
+	if (tx->modes & ADJ_MAXERROR)

include/linux/timesource.h (mode:100644) line 255

Quoted 10 lines
include/linux/timesource.h (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +10 -0
+		ntp_maxerror = tx->maxerror;
+
+	if (tx->modes & ADJ_ESTERROR)
+		ntp_esterror = tx->esterror;
+
+	if (tx->modes & ADJ_TIMECONST)
+		ntp_constant = tx->constant;
+
+	if (tx->modes & ADJ_OFFSET) {
+		/* check if we're doing a singleshot adjustment */

Redundant comment.

include/linux/timesource.h (mode:100644) line 258

Quoted 3 lines
include/linux/timesource.h (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +3 -0
+		if (tx->modes == ADJ_OFFSET_SINGLESHOT)
+				singleshot_adj = tx->offset;
+		/* otherwise, call hardupdate() */

Ditto.

include/linux/timesource.h (mode:100644) line 264

Quoted 6 lines
include/linux/timesource.h (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +6 -0
+		else if (ntp_hardupdate(tx->offset, tx->time))
+			result = TIME_ERROR;
+	}
+
+	if (tx->modes & ADJ_TICK) {
+		/* first calculate usec/user_tick offset */

Ditto.

include/linux/timesource.h (mode:100644) line 266

Quoted 2 lines
include/linux/timesource.h (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +2 -0
+		tick_adj = ((USEC_PER_SEC + USER_HZ/2)/USER_HZ) - tx->tick;
+		/* multiply by user_hz to get usec/sec => ppm */

Ditto.

include/linux/timesource.h (mode:100644) line 268

Quoted 2 lines
include/linux/timesource.h (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +2 -0
+		tick_adj *= USER_HZ;
+		/* save tx->tick for future calls to adjtimex */

Ditto.

include/linux/timesource.h (mode:100644) line 277

Quoted 9 lines
include/linux/timesource.h (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +9 -0
+		ntp_tick = tx->tick;
+	}
+
+	if ((ntp_status & (STA_UNSYNC|STA_CLOCKERR)) != 0 )
+		result = TIME_ERROR;
+
+/* Kernel output bits
+ */
+	/* write kernel state to user timex values*/

Ditto.

Quoted 12 lines
include/linux/timesource.h (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +12 -0
+	if ((tx->modes & ADJ_OFFSET_SINGLESHOT) == ADJ_OFFSET_SINGLESHOT)
+		tx->offset = save_offset;
+	else
+		tx->offset = shiftR(ntp_offset, SHIFT_UPDATE);
+
+	tx->freq = ntp_freq;
+	tx->maxerror = ntp_maxerror;
+	tx->esterror = ntp_esterror;
+	tx->status = ntp_status;
+	tx->constant = ntp_constant;
+	tx->precision = ntp_precision;
+	tx->tolerance = ntp_tolerance;

include/linux/timesource.h (mode:100644) line 299

Quoted 10 lines
include/linux/timesource.h (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +10 -0
+
+	/* PPS is not implemented, so these are zero */
+	tx->ppsfreq	= /*XXX - Not Implemented!*/ 0;
+	tx->jitter	= /*XXX - Not Implemented!*/ 0;
+	tx->shift	= /*XXX - Not Implemented!*/ 0;
+	tx->stabil	= /*XXX - Not Implemented!*/ 0;
+	tx->jitcnt	= /*XXX - Not Implemented!*/ 0;
+	tx->calcnt	= /*XXX - Not Implemented!*/ 0;
+	tx->errcnt	= /*XXX - Not Implemented!*/ 0;
+	tx->stbcnt	= /*XXX - Not Implemented!*/ 0;

One comment is enough.

Quoted 28 lines
include/linux/timesource.h (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +28 -0
+
+	write_sequnlock_irqrestore(&ntp_lock, flags);
+
+	return result;
+}
+
+
+/**
+ * ntp_leapsecond - NTP leapsecond processing code.
+ * now: the current time
+ *
+ * Returns the number of seconds (-1, 0, or 1) that
+ * should be added to the current time to properly
+ * adjust for leapseconds.
+ */
+int ntp_leapsecond(struct timespec now)
+{
+	/*
+	 * Leap second processing. If in leap-insert state at
+	 * the end of the day, the system clock is set back one
+	 * second; if in leap-delete state, the system clock is
+	 * set ahead one second.
+	 */
+	static time_t leaptime = 0;
+
+	switch (ntp_state) {
+	case TIME_OK:
+		if (ntp_status & STA_INS) {

include/linux/timesource.h (mode:100644) line 337

Quoted 10 lines
include/linux/timesource.h (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +10 -0
+			ntp_state = TIME_INS;
+			/* calculate end of today (23:59:59)*/
+			leaptime = now.tv_sec + SEC_PER_DAY -
+					(now.tv_sec % SEC_PER_DAY) - 1;
+		}
+		else if (ntp_status & STA_DEL) {
+			ntp_state = TIME_DEL;
+			/* calculate end of today (23:59:59)*/
+			leaptime = now.tv_sec + SEC_PER_DAY -
+					(now.tv_sec % SEC_PER_DAY) - 1;

Duplicate code. Please introduce ntp_end_of_today().

include/linux/timesource.h (mode:100644) line 343

Quoted 6 lines
include/linux/timesource.h (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +6 -0
+void ntp_clear(void)
+{
+	unsigned long flags;
+	write_seqlock_irqsave(&ntp_lock, flags);
+
+	/* clear everything */

Redundant comment.

Quoted 26 lines

Index: kernel/timeofday.c
===================================================================

kernel/timeofday.c (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +21 -0
@@ -0,0 +1,607 @@
+/*********************************************************************
+* linux/kernel/timeofday.c
+*
+* Revision History:
+* 2004-09-02:   A0
+*   o First pass sent to lkml for review.
+* 2004-12-07:   A1
+*   o Rework of timesource structure
+*   o Sent to lkml for review
+* 2005-01-24:   A2
+*   o write_seqlock_irq -> writeseqlock_irqsave
+*   o arch generic interface for for get_cmos_time() equivalents
+*   o suspend/resume hooks for sleep/hibernate (lightly tested)
+*   o timesource adjust_callback hook
+*   o Sent to lkml for review
+* 2005-03-11:   A3
+*   o periodic_hook (formerly interrupt_hook) now calle by softtimer
+*   o yanked ntp_scale(), ntp adjustments are done in cyc2ns now
+*   o sent to lkml for review
+* 2005-04-29:   A4
+*   o Improved the cyc2ns remainder handling

kernel/timeofday.c (mode:100644) line 31

Quoted 10 lines
kernel/timeofday.c (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +10 -0
+*   o Added getnstimeofday
+*   o Cleanups from Nish Aravamudan
+* 2005-05-12:   A5
+*   o Added clock_was_set hooks
+*   o Added suspend/resume sysfs hooks
+*   o Minor code cleanups
+*   o First attempt at docbook comments
+* 2005-05-31:   B0
+*  o Comment cleanups
+*  o Rounding fixes

Please drop this useless revision history.

kernel/timeofday.c (mode:100644) line 148

Quoted 8 lines
kernel/timeofday.c (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +8 -0
+nsec_t get_lowres_timestamp(void)
+{
+	nsec_t ret;
+	unsigned long seq;
+	do {
+		seq = read_seqbegin(&system_time_lock);
+
+		/* quickly grab system_time*/

Redundant comment.

kernel/timeofday.c (mode:100644) line 170

Quoted 8 lines
kernel/timeofday.c (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +8 -0
+nsec_t get_lowres_timeofday(void)
+{
+	nsec_t ret;
+	unsigned long seq;
+	do {
+		seq = read_seqbegin(&system_time_lock);
+
+		/* quickly calculate low-res time of day */

Redundant comment.

kernel/timeofday.c (mode:100644) line 211

Quoted 6 lines
kernel/timeofday.c (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +6 -0
+static inline nsec_t __monotonic_clock(void)
+{
+	nsec_t ret, ns_offset;
+	cycle_t now, cycle_delta;
+
+	/* read timesource */

Redundant comment.

kernel/timeofday.c (mode:100644) line 214

Quoted 3 lines
kernel/timeofday.c (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +3 -0
+	now = read_timesource(timesource);
+
+	/* calculate the delta since the last timeofday_periodic_hook */

Ditto.

kernel/timeofday.c (mode:100644) line 217

Quoted 3 lines
kernel/timeofday.c (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +3 -0
+	cycle_delta = (now - offset_base) & timesource->mask;
+
+	/* convert to nanoseconds */

Ditto.

kernel/timeofday.c (mode:100644) line 220

Quoted 3 lines
kernel/timeofday.c (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +3 -0
+	ns_offset = cyc2ns(timesource, ntp_adj, cycle_delta);
+
+	/* add result to system time */

Ditto.

kernel/timeofday.c (mode:100644) line 339

Quoted 3 lines
kernel/timeofday.c (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +3 -0
+int do_adjtimex(struct timex *tx)
+{
+ 	/* Check capabilities if we're trying to modify something */

Redundant comment.

kernel/timeofday.c (mode:100644) line 348

Quoted 9 lines
kernel/timeofday.c (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +9 -0
+	if (tx->modes && !capable(CAP_SYS_TIME))
+		return -EPERM;
+
+	/* Note: We set tx->time first,
+	 * because ntp_adjtimex uses it
+	 */
+	do_gettimeofday(&tx->time);
+
+	/* call out to NTP code */

Redundant comment.

kernel/timeofday.c (mode:100644) line 370

Quoted 7 lines
kernel/timeofday.c (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +7 -0
+static int timeofday_suspend_hook(struct sys_device *dev, u32 state)
+{
+	unsigned long flags;
+
+	write_seqlock_irqsave(&system_time_lock, flags);
+
+	/* Make sure time_suspend_state is sane */

Redundant comment.

kernel/timeofday.c (mode:100644) line 382

Quoted 12 lines
kernel/timeofday.c (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +12 -0
+	BUG_ON(time_suspend_state != TIME_RUNNING);
+
+	/* First off, save suspend start time
+	 * then quickly call __monotonic_clock.
+	 * These two calls hopefully occur quickly
+	 * because the difference between reads will
+	 * accumulate as time drift on resume.
+	 */
+	suspend_start = read_persistent_clock();
+	system_time = __monotonic_clock();
+
+	/* switch states */

Redundant comment.

Quoted 12 lines
kernel/timeofday.c (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +12 -0
+	time_suspend_state = TIME_SUSPENDED;
+
+	write_sequnlock_irqrestore(&system_time_lock, flags);
+	return 0;
+}
+
+
+/**
+ * timeofday_resume_hook - Resumes the timeofday subsystem.
+ * @dev: unused
+ *
+ * This function resumes the timeofday subsystem

kernel/timeofday.c (mode:100644) line 404

Quoted 10 lines
kernel/timeofday.c (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +10 -0
+ * from a previous call to timeofday_suspend_hook.
+ */
+static int timeofday_resume_hook(struct sys_device *dev)
+{
+	nsec_t now, suspend_time;
+	unsigned long flags;
+
+	write_seqlock_irqsave(&system_time_lock, flags);
+
+	/* Make sure time_suspend_state is sane */

Redundant comment.

kernel/timeofday.c (mode:100644) line 417

Quoted 13 lines
kernel/timeofday.c (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +13 -0
+	BUG_ON(time_suspend_state != TIME_SUSPENDED);
+
+	/* Read persistent clock to mark the end of
+	 * the suspend interval then rebase the
+	 * offset_base to current timesource value.
+	 * Again, time between these two calls will
+	 * not be accounted for and will show up as
+	 * time drift.
+	 */
+	now = read_persistent_clock();
+	offset_base = read_timesource(timesource);
+
+	/* calculate how long we were out for */

Ditto

kernel/timeofday.c (mode:100644) line 420

Quoted 3 lines
kernel/timeofday.c (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +3 -0
+	suspend_time = now - suspend_start;
+
+	/* update system_time */

Ditto

kernel/timeofday.c (mode:100644) line 425

Quoted 5 lines
kernel/timeofday.c (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +5 -0
+	system_time += suspend_time;
+
+	ntp_clear();
+
+	/* Set us back to running */

Ditto

kernel/timeofday.c (mode:100644) line 428

Quoted 3 lines
kernel/timeofday.c (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +3 -0
+	time_suspend_state = TIME_RUNNING;
+
+	/* finally, update legacy time values */

Ditto

kernel/timeofday.c (mode:100644) line 323

Quoted 5 lines
kernel/timeofday.c (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +5 -0
+	update_legacy_time_values();
+
+	write_sequnlock_irqrestore(&system_time_lock, flags);
+
+	/* signal posix-timers about time change */

Ditto

Quoted 5 lines
kernel/timeofday.c (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +5 -0
+static void timeofday_periodic_hook(unsigned long unused)
+{
+	cycle_t now, cycle_delta;
+	static u64 remainder;
+	nsec_t ns, ns_ntp;

kernel/timeofday.c (mode:100644) line 481

Quoted 10 lines
kernel/timeofday.c (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +10 -0
+	long leapsecond;
+	struct timesource_t* next;
+	unsigned long flags;
+	u64 tmp;
+	int ppm;
+
+	write_seqlock_irqsave(&system_time_lock, flags);
+
+	/* read time source & calc time since last call*/
+	now = read_timesource(timesource);

Redundant comment.

kernel/timeofday.c (mode:100644) line 484

Quoted 3 lines
kernel/timeofday.c (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +3 -0
+	cycle_delta = (now - offset_base) & timesource->mask;
+
+	/* convert cycles to ntp adjusted ns and save remainder */

ditto

kernel/timeofday.c (mode:100644) line 487

Quoted 3 lines
kernel/timeofday.c (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +3 -0
+	ns_ntp = cyc2ns_rem(timesource, ntp_adj, cycle_delta, &remainder);
+
+	/* convert cycles to raw ns for ntp advance */

ditto

Quoted 4 lines
kernel/timeofday.c (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +4 -0
+	ns = cyc2ns(timesource, 0, cycle_delta);
+
+#if TIME_DBG
+	static int dbg=0;

kernel/timeofday.c (mode:100644) line 501

Quoted 10 lines
kernel/timeofday.c (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +10 -0
+	if(!(dbg++%TIME_DBG_FREQ)){
+		printk(KERN_INFO "now: %lluc - then: %lluc = delta: %lluc -> %llu ns + %llu shift_ns (ntp_adj: %i)\n",
+			(unsigned long long)now, (unsigned long long)offset_base,
+			(unsigned long long)cycle_delta, (unsigned long long)ns,
+			(unsigned long long)remainder, ntp_adj);
+	}
+}
+#endif
+
+	/* update system_time */

ditto

kernel/timeofday.c (mode:100644) line 504

Quoted 3 lines
kernel/timeofday.c (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +3 -0
+	system_time += ns_ntp;
+
+	/* reset the offset_base */

ditto

kernel/timeofday.c (mode:100644) line 507

Quoted 3 lines
kernel/timeofday.c (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +3 -0
+	offset_base = now;
+
+	/* advance the ntp state machine by ns interval*/

ditto

kernel/timeofday.c (mode:100644) line 510

Quoted 3 lines
kernel/timeofday.c (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +3 -0
+	ppm = ntp_advance(ns);
+
+	/* do ntp leap second processing*/

ditto

kernel/timeofday.c (mode:100644) line 514

Quoted 4 lines
kernel/timeofday.c (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +4 -0
+	leapsecond = ntp_leapsecond(ns_to_timespec(system_time+wall_time_offset));
+	wall_time_offset += leapsecond * NSEC_PER_SEC;
+
+	/* sync the persistent clock */

ditto

kernel/timeofday.c (mode:100644) line 518

Quoted 4 lines
kernel/timeofday.c (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +4 -0
+	if (!(get_ntp_status() & STA_UNSYNC))
+		sync_persistent_clock(ns_to_timespec(system_time + wall_time_offset));
+
+	/* if necessary, switch timesources */

ditto

kernel/timeofday.c (mode:100644) line 521

Quoted 3 lines
kernel/timeofday.c (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +3 -0
+	next = get_next_timesource();
+	if (next != timesource) {
+		/* immediately set new offset_base */

ditto

kernel/timeofday.c (mode:100644) line 523

Quoted 2 lines
kernel/timeofday.c (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +2 -0
+		offset_base = read_timesource(next);
+		/* swap timesources */

ditto

Quoted 6 lines
kernel/timeofday.c (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +6 -0
+		timesource = next;
+		printk(KERN_INFO "Time: %s timesource has been installed.\n",
+					timesource->name);
+		ntp_clear();
+		ntp_adj = 0;
+		remainder = 0;

kernel/timeofday.c (mode:100644) line 539

Quoted 10 lines
kernel/timeofday.c (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +10 -0
+	}
+
+	/* now is a safe time, so allow timesource to adjust
+	 * itself (for example: to make cpufreq changes).
+	 */
+	if(timesource->update_callback)
+		timesource->update_callback();
+
+
+	/* Convert the signed ppm to timesource multiplier adjustment */

ditto

kernel/timeofday.c (mode:100644) line 540

Quoted 1 line
kernel/timeofday.c (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +1 -0
+	tmp = abs(ppm);

tmp wants better name

kernel/timeofday.c (mode:100644) line 549

Quoted 9 lines
kernel/timeofday.c (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +9 -0
+	tmp = tmp * timesource->mult;
+	tmp += 1000000/2; /* round for div*/
+	do_div(tmp, 1000000);
+	if (ppm < 0)
+		ntp_adj = -(int)tmp;
+	else
+		ntp_adj = (int)tmp;
+
+	/* sync legacy values */

redundant comment

Quoted 18 lines
kernel/timeofday.c (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +18 -0
+	update_legacy_time_values();
+
+	arch_update_vsyscall_gtod(system_time + wall_time_offset, offset_base,
+							timesource, ntp_adj);
+
+	write_sequnlock_irqrestore(&system_time_lock, flags);
+
+	/* XXX - Do we need to call clock_was_set() here? */
+
+	/* Set us up to go off on the next interval */
+	mod_timer(&timeofday_timer,
+				jiffies + msecs_to_jiffies(PERIODIC_INTERVAL_MS));
+}
+
+
+/**
+ * timeofday_init - Initializes time variables
+ *

kernel/timeofday.c (mode:100644) line 577

Quoted 10 lines
kernel/timeofday.c (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +10 -0
+ */
+void __init timeofday_init(void)
+{
+	unsigned long flags;
+#if TIME_DBG
+	printk(KERN_INFO "timeofday_init: Starting up!\n");
+#endif
+	write_seqlock_irqsave(&system_time_lock, flags);
+
+	/* initialize the timesource variable */

redundant comment

kernel/timeofday.c (mode:100644) line 580

Quoted 3 lines
kernel/timeofday.c (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +3 -0
+	timesource = get_next_timesource();
+
+	/* clear and initialize offsets*/

ditto

kernel/timeofday.c (mode:100644) line 584

Quoted 4 lines
kernel/timeofday.c (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +4 -0
+	offset_base = read_timesource(timesource);
+	wall_time_offset = read_persistent_clock();
+
+	/* clear NTP scaling factor & state machine */

ditto

kernel/timeofday.c (mode:100644) line 591

Quoted 7 lines
kernel/timeofday.c (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +7 -0
+	ntp_adj = 0;
+	ntp_clear();
+
+	arch_update_vsyscall_gtod(system_time + wall_time_offset, offset_base,
+							timesource, ntp_adj);
+
+	/* initialize legacy time values */

ditto

kernel/timeofday.c (mode:100644) line 596

Quoted 5 lines
kernel/timeofday.c (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +5 -0
+	update_legacy_time_values();
+
+	write_sequnlock_irqrestore(&system_time_lock, flags);
+
+	/* Install timeofday_periodic_hook timer */

ditto

Quoted 9 lines

Index: kernel/timesource.c
===================================================================

kernel/timesource.c (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +4 -0
@@ -0,0 +1,253 @@
+/*********************************************************************
+* linux/kernel/timesource.c
+*
+* This file contains the functions which manage timesource drivers.

kernel/timesource.c (mode:100644) line 14

Quoted 10 lines
kernel/timesource.c (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +10 -0
+*
+* Revision History:
+* 2004-12-07:   A1
+*   o Rework of timesource structure
+*   o Sent to lkml for review
+* 2005-04-29:   A4
+*   o Keep track of all registered timesources
+*   o Add sysfs interface for overriding default selection
+* 2005-05-12:   A5
+*   o Add boot-time timesource= option for timesource overrides

Please drop this useless revision history.

kernel/timesource.c (mode:100644) line 96

Quoted 7 lines
kernel/timesource.c (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +7 -0
+static struct timesource_t* select_timesource(void)
+{
+	struct timesource_t* best = timesource_list[0];
+	int i;
+
+	for (i=0; i < timesource_list_counter; i++) {
+		/* Check for override */

Redundant comment.

kernel/timesource.c (mode:100644) line 105

Quoted 9 lines
kernel/timesource.c (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +9 -0
+		if ((override_name[0] != 0) &&
+			(strlen(override_name)
+				== strlen(timesource_list[i]->name)) &&
+			(!strncmp(timesource_list[i]->name, override_name,
+				 strlen(override_name)))) {
+			best = timesource_list[i];
+			break;
+		}
+		/* Pick the highest priority */

ditto

Quoted 8 lines
kernel/timesource.c (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +8 -0
+		if (timesource_list[i]->priority > best->priority)
+		 	best = timesource_list[i];
+	}
+	return best;
+}
+
+/**
+ * register_timesource - Used to install new timesources

kernel/timesource.c (mode:100644) line 123

Quoted 10 lines
kernel/timesource.c (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +10 -0
+ * @t: timesource to be registered
+ *
+ */
+void register_timesource(struct timesource_t* t)
+{
+	char* error_msg = 0;
+	int i;
+	write_seqlock(&timesource_lock);
+
+	/* check if timesource is already registered */

Redundant comment.

kernel/timesource.c (mode:100644) line 130

Quoted 7 lines
kernel/timesource.c (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +7 -0
+	for (i=0; i < timesource_list_counter; i++)
+		if (!strncmp(timesource_list[i]->name, t->name, strlen(t->name))){
+			error_msg = "Already registered!";
+			break;
+		}
+
+	/* check that the list isn't full */

ditto

kernel/timesource.c (mode:100644) line 140

Quoted 10 lines
kernel/timesource.c (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +10 -0
+	if (timesource_list_counter >= MAX_TIMESOURCES)
+		error_msg = "Too many timesources!";
+
+	if(!error_msg)
+		timesource_list[timesource_list_counter++] = t;
+	else
+		printk("register_timesource: Cannot register %s. %s\n",
+					t->name, error_msg);
+
+	/* select next timesource */

ditto

Quoted 10 lines
kernel/timesource.c (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +10 -0
+	next_timesource = select_timesource();
+
+	write_sequnlock(&timesource_lock);
+}
+EXPORT_SYMBOL(register_timesource);
+
+/**
+ * sysfs_show_timesources - sysfs interface for listing timesource
+ * @dev: unused
+ * @buf: char buffer to be filled with timesource list

kernel/timesource.c (mode:100644) line 160

Quoted 10 lines
kernel/timesource.c (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +10 -0
+ *
+ * Provides sysfs interface for listing registered timesources
+ */
+static ssize_t sysfs_show_timesources(struct sys_device *dev, char *buf)
+{
+	int i;
+	char* curr = buf;
+	write_seqlock(&timesource_lock);
+	for(i=0; i < timesource_list_counter; i++) {
+		/* Mark current timesource w/ a star */

ditto

Quoted 19 lines
kernel/timesource.c (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +19 -0
+		if (timesource_list[i] == curr_timesource)
+			curr += sprintf(curr, "*");
+		curr += sprintf(curr, "%s ",timesource_list[i]->name);
+	}
+	write_sequnlock(&timesource_lock);
+
+	curr += sprintf(curr, "\n");
+	return curr - buf;
+}
+
+/**
+ * sysfs_override_timesource - interface for manually overriding timesource
+ * @dev: unused
+ * @buf: name of override timesource
+ *
+ *
+ *     Takes input from sysfs interface for manually overriding
+ *     the default timesource selction
+ */

kernel/timesource.c (mode:100644) line 189

Quoted 10 lines
kernel/timesource.c (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +10 -0
+static ssize_t sysfs_override_timesource(struct sys_device *dev,
+			const char *buf, size_t count)
+{
+	/* check to avoid underflow later */
+	if (strlen(buf) == 0)
+		return count;
+
+	write_seqlock(&timesource_lock);
+
+	/* copy the name given */

redundant comment

kernel/timesource.c (mode:100644) line 193

Quoted 4 lines
kernel/timesource.c (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +4 -0
+	strncpy(override_name, buf, strlen(buf)-1);
+	override_name[strlen(buf)-1] = 0;
+
+	/* see if we can find it */

ditto

#5 lore raw
Quoted 3 lines · Pekka Enberg

Hi John,

Some coding style comments below.

[snip]

Quoted 35 lines

Please drop this redundant comment.

kernel/ntp.c (mode:100644) line 148

Quoted 5 lines
kernel/ntp.c (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +5 -0
+	interval_sum += interval;
+
+	write_seqlock_irqsave(&ntp_lock, flags);
+
+	/* decrement singleshot offset interval */

Ditto.

kernel/ntp.c (mode:100644) line 150

Quoted 2 lines
kernel/ntp.c (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +2 -0
+	ss_offset_len -= interval;
+	if(ss_offset_len < 0) /* make sure it doesn't go negative */

Ditto.

kernel/ntp.c (mode:100644) line 153

Quoted 3 lines
kernel/ntp.c (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +3 -0
+		ss_offset_len = 0;
+
+	/* Do second overflow code */

Drop redundant comment.

kernel/ntp.c (mode:100644) line 168

Quoted 7 lines
kernel/ntp.c (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +7 -0
+		ntp_maxerror += shiftR(ntp_tolerance, SHIFT_USEC);
+		if (ntp_maxerror > NTP_PHASE_LIMIT) {
+			ntp_maxerror = NTP_PHASE_LIMIT;
+			ntp_status |= STA_UNSYNC;
+		}
+
+		/* Calculate offset_adj for the next second */

Ditto.

kernel/ntp.c (mode:100644) line 169

Quoted 1 line
kernel/ntp.c (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +1 -0
+		tmp = ntp_offset;

tmp could use a more descriptive name.

Quoted 6 lines

kernel/ntp.c (mode:100644) line 173

Quoted 4 lines
kernel/ntp.c (mode:100644) renamed from dev/null (tree:9b72b650285720c17d0aa0a3795c30fe492700b3) +4 -0
+		if (!(ntp_status & STA_FLL))
+		    tmp = shiftR(tmp, SHIFT_KG + ntp_constant);
+
+		/* bound the adjustment to MAXPHASE/MINSEC */

Redundant comment.

Thanks for the uh, redundant redundant-comment comments ;)

Much is from the transition from psudo-code to actual code, so I appreciate you pointing it out. There are a few spots where I feel there is still value in the comments, so I've left them, but overall I think you'll see an improvement.

thanks again for the feedback!
-john

#6 lore raw
In reply to john stultz

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Quoted 4 lines · john stultz

Hey Everyone,
I'm heading out on vacation until Monday, so I'm just re-spinning my
current tree for testing. If there's no major issues on Monday, I'll re- diff against Andrew's tree and re-submit the patches for inclusion.

John,

I'm not sure what change caused this, but it seems that keyboard and mouse interrupts are firing more than once when I'm using the c3tsc timesource. It manifests itself as multiple keypresses and odd mouse tapping. The problem seems to appear only in X, and it's definitely confined to c3tsc (jiffies, pit, tsc-interp, and acpi_pm all seem to work fine [1]).

[1] Note: Don't try to force-load the hpet timesource if you don't have one, or if you aren't certain of the address :)

Frank
- --
Frank Sorenson - KD7TZK
Systems Manager, Computer Science Department
Brigham Young University
[email protected]
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.6 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org

iD8DBQFCrkU7aI0dwg4A47wRAmfPAKCumk2XAILQ8tPEBWoawfmEmpUjTgCgz1k6 N50mf7Fnoha2nJmLOJ38Qt0=
=4bj2
-----END PGP SIGNATURE-----

#7 lore raw
Quoted 9 lines · Frank Sorenson

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Quoted 4 lines · john stultz

Hey Everyone,
I'm heading out on vacation until Monday, so I'm just re-spinning my
current tree for testing. If there's no major issues on Monday, I'll re- diff against Andrew's tree and re-submit the patches for inclusion.

Quoted 6 lines

I'm not sure what change caused this, but it seems that keyboard and mouse interrupts are firing more than once when I'm using the c3tsc timesource. It manifests itself as multiple keypresses and odd mouse tapping. The problem seems to appear only in X, and it's definitely confined to c3tsc (jiffies, pit, tsc-interp, and acpi_pm all seem to work fine [1]).

Can you confirm that this is a new issue?

Also can you run the following:

while true
do
ntpdate -uq <some ntp server>
sleep 60
done

To make sure its not clock-drift related?

thanks
-john

#8 lore raw

cover new timeofday-based soft-timer subsystem

In reply to john stultz
Quoted 4 lines · john stultz

Hey Everyone,
I'm heading out on vacation until Monday, so I'm just re-spinning my
current tree for testing. If there's no major issues on Monday, I'll re- diff against Andrew's tree and re-submit the patches for inclusion.

Here is an update of my soft-timer rework to John's latest patches. I have made some major changes in this revision. I would still greatly appreciate any comments.

Changes:

The timerinterval value of the soft-timer's expires is never stored. Instead, we store the nanosecond request in a new member of struct timer_list, expires_nsecs. This does make the structure 64 bits larger, but also means expires is deprecated along with the expires-style interfaces (add_timer(), mod_timer()) and thus the long term addition is 32 bits. Whenever we need the timerinterval value, we calculate it via the shift/and operation, which should be pretty quick.

Notes / Blocking Issues:

No non-NEWTOD support yet, which means this patch isn't appropriate for any mainline inclusion yet. It should be a small patch to timeofday.h to emulate do_monotonic_clock() [the only soft-timer dependence on the timeofday code] with jiffies_to_nsecs(jiffies - INITIAL_JIFFIES). But I ran into some build issues with that change; I'll try to get a patch out soon, though. I was able to test my patch with this emulation by moving do_monotonic_clock() in ppc64, which is where I got the ppc64 benchmark numbers below.

NUMA-Q is definitely broken with my patch, but not NUMA itself. Honestly not sure why, but timeofday seems to also be broken on NUMA-Q -- it sets up the TSC as the timesource, even though it shouldn't be (booting with notsc on NUMA-Qs seems to fix the problem for John's patches, at least).

Some design points:

1) The patches are small but do a lot.
a) Renames timer_jiffies to last_timer_time (now that we are not jiffies-based).
b) Converts the soft-timer time-vector's/bucket's entries to timerinterval (a new unit) width, instead of jiffy width.
c) Defines timerintervals to be the current time as reported by the new timeofday-subsystem shifted down by TIMERINTERVAL_BITS bits. Thus, various pseudo-'human time' units can be emulated. The default value for TIMERINTERVAL_BITS is 19.
d) Uses do_monotonic_clock() (converted to timerintervals) as the basis for addition and expiration of timers instead of jiffies.
e) Adds some new helper functions for dealing with nanosecond values.

2) The reason for the re-work? Many people complain about all of the adding of 1 jiffy here or there to fix bugs. This new systems is fundamentally human-time oriented and deals with those issues correctly and, more importantly, sanely :)

The code is reasonably well commented, but does expect readers to understand the current soft-timer subsystem.

This is still an early working of this patch, so I expect criticism, and am happy to make changes.

Benchmark differentials follow in this mail [1].

Overview:

1/4: Converts the soft-timer subsystem to use timerinterval as the units of addition and expiration.

2/4: Converts, as an example, sys_nanosleep() to use the new interfaces provided by patch 2. Example latency values are also below [2], demonstrating improvements in the min, max and average latency for sys_nanosleep() (which uses schedule_timeout_nsecs() internally with my patch).

Thanks,
Nish

[1] Benchmark Differentials on various machines

x86_64, 4-way 1.7 GHz Opteron, 8GB RAM
Elapsed User System CPU
2.6.12-rc6 100% 100% 100% 100%
2.6.12-rc6-tod 99.67% 99.77% 99.44% 99.79%
2.6.12-rc6-tod-timer 99.8% 99.97% 99.73% 99.79%

non-numaq big x86, 16-way 1.4 GHz Xeon, 15GB RAM
Elapsed User System CPU
2.6.12-rc6 100% 100% 100% 100%
2.6.12-rc6-tod 99.95% 99.75% 99.51% 99.76%
2.6.12-rc6-tod-timer 100.88% 100.04% 99.55% 99.11%

small x86, 1-way 2.66 GHz P4, 512MB RAM
Elapsed User System CPU
2.6.12-rc6 100% 100% 100% 100%
2.6.12-rc6-tod 99.4% 102.87% 95.72% 100%
2.6.12-rc6-tod-timer 99.33% 102.69% 97.33% 100%

ppc64, 8-way 1.2GHz Power4, 12GB RAM
Elapsed User System CPU
2.6.12-rc6 100% 100% 100% 100%
2.6.12-rc6-tod 95.59% 100.04% 101.28% 104.81%
2.6.12-rc6-tod-timer 97.26% 100.04% 100.58% 102.91%

[2] Latency measured via sys_nanosleep(), 1,000,000 calls

latencies in us, min/max/avg
Request stock tod tod-timer
1000 us 2017/4004/3001 2011/4024/3001 1020/2531/1771
100 us 1022/3001/2000 1028/2995/2001 111/1619/866
1 us 1021/3004/2000 1032/3000/1997 11/1524/764

#9 lore raw

PATCH 1/4 convert soft-timer subsystem to timerintervals

Quoted 9 lines · Nishanth Aravamudan
Quoted 4 lines · john stultz

Hey Everyone,
I'm heading out on vacation until Monday, so I'm just re-spinning my
current tree for testing. If there's no major issues on Monday, I'll re- diff against Andrew's tree and re-submit the patches for inclusion.

Here is an update of my soft-timer rework to John's latest patches. I have made some major changes in this revision. I would still greatly appreciate any comments.

<snip>

Description: Rework the soft-timer subsytem to use timerintervals (a new unit) instead of jiffies for expiration and addition. timerintervals are nothing more than the nanosecond time returned by the new timeofday-subsystem shifted down a certain number of bits (thus determining the precision of the soft-timer subsystem at compile-time).

include/linux/jiffies.h +31 -2
diff -urpN 2.6.12-rc6-tod-timer-base/include/linux/jiffies.h 2.6.12-rc6-tod-timer-dev/include/linux/jiffies.h
@@ -263,7 +263,7 @@ static inline unsigned int jiffies_to_ms
 #endif
 }
 
-static inline unsigned int jiffies_to_usecs(const unsigned long j)
+static inline unsigned long jiffies_to_usecs(const unsigned long j)
 {
 #if HZ <= 1000000 && !(1000000 % HZ)
 	return (1000000 / HZ) * j;
@@ -274,6 +274,17 @@ static inline unsigned int jiffies_to_us
 #endif
 }
 
+static inline nsec_t jiffies_to_nsecs(const unsigned long j)
+{
+#if HZ <= NSEC_PER_SEC && !(NSEC_PER_SEC % HZ)
+	return (NSEC_PER_SEC / HZ) * (nsec_t)j;
+#elif HZ > NSEC_PER_SEC && !(HZ % NSEC_PER_SEC)
+	return ((nsec_t)j + (HZ / NSEC_PER_SEC) - 1)/(HZ / NSEC_PER_SEC);
+#else
+	return ((nsec_t)j * NSEC_PER_SEC) / HZ;
+#endif
+}
+
 static inline unsigned long msecs_to_jiffies(const unsigned int m)
 {
 	if (m > jiffies_to_msecs(MAX_JIFFY_OFFSET))
@@ -287,7 +298,7 @@ static inline unsigned long msecs_to_jif
 #endif
 }
 
-static inline unsigned long usecs_to_jiffies(const unsigned int u)
+static inline unsigned long usecs_to_jiffies(const unsigned long u)
 {
 	if (u > jiffies_to_usecs(MAX_JIFFY_OFFSET))
 		return MAX_JIFFY_OFFSET;
@@ -300,6 +311,24 @@ static inline unsigned long usecs_to_jif
 #endif
 }
 
+static inline unsigned long nsecs_to_jiffies(const nsec_t n)
+{
+	nsec_t temp;
+	if (n > jiffies_to_nsecs(MAX_JIFFY_OFFSET))
+		return MAX_JIFFY_OFFSET;
+#if HZ <= NSEC_PER_SEC && !(NSEC_PER_SEC % HZ)
+	temp = n + (NSEC_PER_SEC / HZ) - 1;
+	do_div(temp, (NSEC_PER_SEC / HZ));
+	return (unsigned long)temp;
+#elif HZ > NSEC_PER_SEC && !(HZ % NSEC_PER_SEC)
+	return n * (HZ / NSEC_PER_SEC);
+#else
+	temp = n * HZ + NSEC_PER_SEC - 1;
+	do_div(temp, NSEC_PER_SEC);
+	return (unsigned long)temp;
+#endif
+}
+
 /*
  * The TICK_NSEC - 1 rounds up the value to the next resolution.  Note
  * that a remainder subtract here would not do the right thing as the
include/linux/sched.h +6 -0
diff -urpN 2.6.12-rc6-tod-timer-base/include/linux/sched.h 2.6.12-rc6-tod-timer-dev/include/linux/sched.h
@@ -182,7 +182,13 @@ extern void scheduler_tick(void);
 extern int in_sched_functions(unsigned long addr);
 
 #define	MAX_SCHEDULE_TIMEOUT	LONG_MAX
+#define	MAX_SCHEDULE_TIMEOUT_NSECS	((nsec_t)(-1))
+#define	MAX_SCHEDULE_TIMEOUT_USECS	ULONG_MAX
+#define	MAX_SCHEDULE_TIMEOUT_MSECS	UINT_MAX
 extern signed long FASTCALL(schedule_timeout(signed long timeout));
+extern nsec_t FASTCALL(schedule_timeout_nsecs(nsec_t timeout_nsecs));
+extern unsigned long FASTCALL(schedule_timeout_usecs(unsigned long timeout_usecs));
+extern unsigned int FASTCALL(schedule_timeout_msecs(unsigned int timeout_msesc));
 asmlinkage void schedule(void);
 
 struct namespace;
include/linux/time.h +4 -0
diff -urpN 2.6.12-rc6-tod-timer-base/include/linux/time.h 2.6.12-rc6-tod-timer-dev/include/linux/time.h
@@ -40,6 +40,10 @@ typedef u64 cycle_t;
 #define NSEC_PER_SEC (1000000000L)
 #endif
 
+#ifndef NSEC_PER_MSEC
+#define NSEC_PER_MSEC (1000000L)
+#endif
+
 #ifndef NSEC_PER_USEC
 #define NSEC_PER_USEC (1000L)
 #endif
include/linux/timer.h +8 -19
diff -urpN 2.6.12-rc6-tod-timer-base/include/linux/timer.h 2.6.12-rc6-tod-timer-dev/include/linux/timer.h
@@ -5,12 +5,14 @@
 #include <linux/list.h>
 #include <linux/spinlock.h>
 #include <linux/stddef.h>
+#include <linux/timeofday.h>
 
 struct tvec_t_base_s;
 
 struct timer_list {
 	struct list_head entry;
 	unsigned long expires;
+	nsec_t expires_nsecs;
 
 	spinlock_t lock;
 	unsigned long magic;
@@ -26,6 +28,7 @@ struct timer_list {
 #define TIMER_INITIALIZER(_function, _expires, _data) {		\
 		.function = (_function),			\
 		.expires = (_expires),				\
+		.expires_nsecs = 0,				\
 		.data = (_data),				\
 		.base = NULL,					\
 		.magic = TIMER_MAGIC,				\
@@ -63,29 +66,15 @@ static inline int timer_pending(const st
 
 extern void add_timer_on(struct timer_list *timer, int cpu);
 extern int del_timer(struct timer_list * timer);
-extern int __mod_timer(struct timer_list *timer, unsigned long expires);
+extern int __mod_timer(struct timer_list *timer);
 extern int mod_timer(struct timer_list *timer, unsigned long expires);
+extern void add_timer(struct timer_list *timer);
+extern int set_timer_nsecs(struct timer_list *timer, nsec_t expires_nsecs);
+extern void set_timer_on_nsecs(struct timer_list *timer, nsec_t expires_nsecs,
+								int cpu);
 
 extern unsigned long next_timer_interrupt(void);
 
-/***
- * add_timer - start a timer
- * @timer: the timer to be added
- *
- * The kernel will do a ->function(->data) callback from the
- * timer interrupt at the ->expired point in the future. The
- * current time is 'jiffies'.
- *
- * The timer's ->expired, ->function (and if the handler uses it, ->data)
- * fields must be set prior calling this function.
- *
- * Timers with an ->expired field in the past will be executed in the next
- * timer tick.
- */
-static inline void add_timer(struct timer_list * timer)
-{
-	__mod_timer(timer, timer->expires);
-}
 
 #ifdef CONFIG_SMP
   extern int del_timer_sync(struct timer_list *timer);
kernel/timer.c +367 -20

542 lines not on this page · raw message

#10 lore raw

PATCH 2/4 [PATCH 2/4]

In reply to Nishanth Aravamudan
Quoted 9 lines · Nishanth Aravamudan
Quoted 4 lines · john stultz

Hey Everyone,
I'm heading out on vacation until Monday, so I'm just re-spinning my
current tree for testing. If there's no major issues on Monday, I'll re- diff against Andrew's tree and re-submit the patches for inclusion.

Here is an update of my soft-timer rework to John's latest patches. I have made some major changes in this revision. I would still greatly appreciate any comments.

Description: Convert sys_nanosleep() to use the new timerinterval-based soft-timer interfaces.

kernel/timer.c +11 -11
diff -urpN 2.6.12-rc6-tod-timer-base/kernel/timer.c 2.6.12-rc6-tod-timer-dev/kernel/timer.c
@@ -1484,21 +1484,21 @@ asmlinkage long sys_gettid(void)
 
 static long __sched nanosleep_restart(struct restart_block *restart)
 {
-	unsigned long expire = restart->arg0, now = jiffies;
+	nsec_t expire = restart->arg0, now = do_monotonic_clock();
 	struct timespec __user *rmtp = (struct timespec __user *) restart->arg1;
 	long ret;
 
 	/* Did it expire while we handled signals? */
-	if (!time_after(expire, now))
+	if (now > expire)
 		return 0;
 
-	current->state = TASK_INTERRUPTIBLE;
-	expire = schedule_timeout(expire - now);
+	set_current_state(TASK_INTERRUPTIBLE);
+	expire = schedule_timeout_nsecs(expire - now);
 
 	ret = 0;
 	if (expire) {
 		struct timespec t;
-		jiffies_to_timespec(expire, &t);
+		t = ns_to_timespec(expire);
 
 		ret = -ERESTART_RESTARTBLOCK;
 		if (rmtp && copy_to_user(rmtp, &t, sizeof(t)))
@@ -1511,7 +1511,7 @@ static long __sched nanosleep_restart(st
 asmlinkage long sys_nanosleep(struct timespec __user *rqtp, struct timespec __user *rmtp)
 {
 	struct timespec t;
-	unsigned long expire;
+	nsec_t expire;
 	long ret;
 
 	if (copy_from_user(&t, rqtp, sizeof(t)))
@@ -1520,20 +1520,20 @@ asmlinkage long sys_nanosleep(struct tim
 	if ((t.tv_nsec >= 1000000000L) || (t.tv_nsec < 0) || (t.tv_sec < 0))
 		return -EINVAL;
 
-	expire = timespec_to_jiffies(&t) + (t.tv_sec || t.tv_nsec);
-	current->state = TASK_INTERRUPTIBLE;
-	expire = schedule_timeout(expire);
+	expire = timespec_to_ns(&t);
+	set_current_state(TASK_INTERRUPTIBLE);
+	expire = schedule_timeout_nsecs(expire);
 
 	ret = 0;
 	if (expire) {
 		struct restart_block *restart;
-		jiffies_to_timespec(expire, &t);
+		t = ns_to_timespec(expire);
 		if (rmtp && copy_to_user(rmtp, &t, sizeof(t)))
 			return -EFAULT;
 
 		restart = &current_thread_info()->restart_block;
 		restart->fn = nanosleep_restart;
-		restart->arg0 = jiffies + expire;
+		restart->arg0 = do_monotonic_clock() + expire;
 		restart->arg1 = (unsigned long) rmtp;
 		ret = -ERESTART_RESTARTBLOCK;
 	}
#11 lore raw

PATCH 2/4 convert sys_nanosleep() to use new soft-timer subsystem

In reply to Nishanth Aravamudan
Quoted 9 lines · Nishanth Aravamudan
Quoted 4 lines · john stultz

Hey Everyone,
I'm heading out on vacation until Monday, so I'm just re-spinning my
current tree for testing. If there's no major issues on Monday, I'll re- diff against Andrew's tree and re-submit the patches for inclusion.

Here is an update of my soft-timer rework to John's latest patches. I have made some major changes in this revision. I would still greatly appreciate any comments.

Sorry, the mail got sent without a subject :(

Description: Convert sys_nanosleep() to use the new timerinterval-based soft-timer interfaces.

kernel/timer.c +11 -11
diff -urpN 2.6.12-rc6-tod-timer-base/kernel/timer.c 2.6.12-rc6-tod-timer-dev/kernel/timer.c
@@ -1484,21 +1484,21 @@ asmlinkage long sys_gettid(void)
 
 static long __sched nanosleep_restart(struct restart_block *restart)
 {
-	unsigned long expire = restart->arg0, now = jiffies;
+	nsec_t expire = restart->arg0, now = do_monotonic_clock();
 	struct timespec __user *rmtp = (struct timespec __user *) restart->arg1;
 	long ret;
 
 	/* Did it expire while we handled signals? */
-	if (!time_after(expire, now))
+	if (now > expire)
 		return 0;
 
-	current->state = TASK_INTERRUPTIBLE;
-	expire = schedule_timeout(expire - now);
+	set_current_state(TASK_INTERRUPTIBLE);
+	expire = schedule_timeout_nsecs(expire - now);
 
 	ret = 0;
 	if (expire) {
 		struct timespec t;
-		jiffies_to_timespec(expire, &t);
+		t = ns_to_timespec(expire);
 
 		ret = -ERESTART_RESTARTBLOCK;
 		if (rmtp && copy_to_user(rmtp, &t, sizeof(t)))
@@ -1511,7 +1511,7 @@ static long __sched nanosleep_restart(st
 asmlinkage long sys_nanosleep(struct timespec __user *rqtp, struct timespec __user *rmtp)
 {
 	struct timespec t;
-	unsigned long expire;
+	nsec_t expire;
 	long ret;
 
 	if (copy_from_user(&t, rqtp, sizeof(t)))
@@ -1520,20 +1520,20 @@ asmlinkage long sys_nanosleep(struct tim
 	if ((t.tv_nsec >= 1000000000L) || (t.tv_nsec < 0) || (t.tv_sec < 0))
 		return -EINVAL;
 
-	expire = timespec_to_jiffies(&t) + (t.tv_sec || t.tv_nsec);
-	current->state = TASK_INTERRUPTIBLE;
-	expire = schedule_timeout(expire);
+	expire = timespec_to_ns(&t);
+	set_current_state(TASK_INTERRUPTIBLE);
+	expire = schedule_timeout_nsecs(expire);
 
 	ret = 0;
 	if (expire) {
 		struct restart_block *restart;
-		jiffies_to_timespec(expire, &t);
+		t = ns_to_timespec(expire);
 		if (rmtp && copy_to_user(rmtp, &t, sizeof(t)))
 			return -EFAULT;
 
 		restart = &current_thread_info()->restart_block;
 		restart->fn = nanosleep_restart;
-		restart->arg0 = jiffies + expire;
+		restart->arg0 = do_monotonic_clock() + expire;
 		restart->arg1 = (unsigned long) rmtp;
 		ret = -ERESTART_RESTARTBLOCK;
 	}
#12 lore raw

Re: [PATCH 0/4] new timeofday-based soft-timer subsystem

In reply to Nishanth Aravamudan
Quoted 9 lines · Nishanth Aravamudan
Quoted 4 lines · john stultz

Hey Everyone,
I'm heading out on vacation until Monday, so I'm just re-spinning my
current tree for testing. If there's no major issues on Monday, I'll re- diff against Andrew's tree and re-submit the patches for inclusion.

Here is an update of my soft-timer rework to John's latest patches. I have made some major changes in this revision. I would still greatly appreciate any comments.

<snip>

Quoted 1 line

Notes / Blocking Issues:

<snip>

Quoted 5 lines

NUMA-Q is definitely broken with my patch, but not NUMA itself. Honestly not sure why, but timeofday seems to also be broken on NUMA-Q -- it sets up the TSC as the timesource, even though it shouldn't be (booting with notsc on NUMA-Qs seems to fix the problem for John's patches, at least).

Hrm, I just tried the same emulation on NUMA-Q that I did for ppc64:

inline do_monotonic_clock()

{
	return jiffies_to_nsecs(jiffies - INITIAL_JIFFIES);
}

and kernbench ran ok with just my patches on top of 2.6.12-rc6-git5. So, I think -- not positive, admittedly, the problem may be with John's patches on NUMA-Q, maybe even just some of the timesources.

Thanks,
Nish

#13 lore raw

Re: [PATCH 0/4] new timeofday-based soft-timer subsystem

In reply to Nishanth Aravamudan
Quoted 9 lines · Nishanth Aravamudan
Quoted 4 lines · john stultz

Hey Everyone,
I'm heading out on vacation until Monday, so I'm just re-spinning my
current tree for testing. If there's no major issues on Monday, I'll re- diff against Andrew's tree and re-submit the patches for inclusion.

Here is an update of my soft-timer rework to John's latest patches. I have made some major changes in this revision. I would still greatly appreciate any comments.

First, one consideration I forgot:

Would it be beneficial to encapsulate the timer_list structure? That way if the units change underneath and we eventually move to timer_fsecs (for femtoseconds), we don't need to change all the callers of set_timer_nsecs() again?

I'm envisioning something along the lines of:

init_and_set_timer_nsecs((void *)(function), unsigned long data, nsec_t

				expires_nsecs);

I guess the trick then, is that a pointer to the created timer_list in init_and_set_timer_nsecs() needs to be handed back to the caller, to guarantee they can delete the timer if needed. Maybe that won't work :/

Just a thought, which might make this the hard transition, but should make extensibility easier to handle.

<snip>

Also, some updates:

Quoted 1 line

[1] Benchmark Differentials on various machines

There was a bug in my ppc64 emulation (was just using jiffies not (jiffies - INITIAL_JIFFIES)), here's is the update value for tod-timer:

Quoted 4 lines

ppc64, 8-way 1.2GHz Power4, 12GB RAM
Elapsed User System CPU
2.6.12-rc6 100% 100% 100% 100%
2.6.12-rc6-tod 95.59% 100.04% 101.28% 104.81%

2.6.12-rc6-tod-timer 97.53% 100.18% 100.75% 102.81%

Also, here are the differentials between 2.6.12-rc6 and 2.6.12-rc6-tod-timer with emulation of do_monotonic_clock() on NUMA-Q.

numaq, 16-way 700 MHz, PIII, 16GB RAM
Elapsed User System CPU
2.6.12-rc6 100% 100% 100% 100%
2.6.12-rc6-tod-timer 100.99% 98.1% 99.13% 98.02%

Thanks,
Nish

#14 lore raw

Re: [PATCH 0/4] new timeofday-based soft-timer subsystem

On 14 Jun 2005 at 11:11, Nishanth Aravamudan wrote:

[...]

Quoted 4 lines

Would it be beneficial to encapsulate the timer_list structure? That way if the units change underneath and we eventually move to timer_fsecs (for femtoseconds), we don't need to change all the callers of set_timer_nsecs() again?

[...]

I don't think that we'll see a global clock with reliable femtosecond resolution (not to talk about accuracy) in the foreseeable computer generations. Even plain gigahertz RAM is quite some time away. So how would you distribute such high resolution time across CPUs? As long as a syscall takes significantly longer than 1ns, or has a jitter of more than 1ns, a higher resolution clock would be just a source of additional noise bits.

Regards,
Ulrich Windl

#15 lore raw

Re: [PATCH 0/4] new timeofday-based soft-timer subsystem

Quoted 9 lines · Ulrich Windl

On 14 Jun 2005 at 11:11, Nishanth Aravamudan wrote:

[...]

Quoted 4 lines

Would it be beneficial to encapsulate the timer_list structure? That way if the units change underneath and we eventually move to timer_fsecs (for femtoseconds), we don't need to change all the callers of set_timer_nsecs() again?

[...]

Quoted 7 lines

I don't think that we'll see a global clock with reliable femtosecond resolution (not to talk about accuracy) in the foreseeable computer generations. Even plain gigahertz RAM is quite some time away. So how would you distribute such high resolution time across CPUs? As long as a syscall takes significantly longer than 1ns, or has a jitter of more than 1ns, a higher resolution clock would be just a source of additional noise bits.

Thank you for your feedback, Ulrich. You are probably right that such a hardware timesource probably is not going to be common any time soon. My thoughts for encapsulation were just a possibility, and certainly not a requirement for my patch.

I did not consider the problems of distributing that value, either. So, I guess, I can leave encapsulation out of the current efforts :)

Thanks,
Nish

#16 lore raw

Re: [PATCH 0/4] new timeofday-based soft-timer subsystem

In reply to Nishanth Aravamudan
Quoted 9 lines · Nishanth Aravamudan
Quoted 4 lines · john stultz

Hey Everyone,
I'm heading out on vacation until Monday, so I'm just re-spinning my
current tree for testing. If there's no major issues on Monday, I'll re- diff against Andrew's tree and re-submit the patches for inclusion.

Here is an update of my soft-timer rework to John's latest patches. I have made some major changes in this revision. I would still greatly appreciate any comments.

<snip>

Quoted 4 lines

Overview:

1/4: Converts the soft-timer subsystem to use timerinterval as the units of addition and expiration.

Sorry for the noise, but this patchset is only 2 patches long, not 4. That's what I get for trying to re-use text :/

Thanks,
Nish