Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 27922b4260f65d317aabda37e42bbbff > files > 1532

kernel-2.6.18-238.el5.src.rpm

From: Prarit Bhargava <prarit@redhat.com>
Date: Tue, 24 Feb 2009 14:59:00 -0500
Subject: [ia64] use current_kernel_time/xtime in hrtimer_start()
Message-id: 20090224195859.12415.45173.sendpatchset@prarit.bos.redhat.com
O-Subject: [RHEL5 PATCH]: ia64: Use current_kernel_time()/xtime in hrtimer_start()
Bugzilla: 485323
RH-Acked-by: Pete Zaitcev <zaitcev@redhat.com>

Fujitsu noticed an issue with leap seconds and ia64 using the following test:

	usleep(100000); /* sleep for .1 seconds */
	gettimeofday(&ts);
	// output gettimeofday

After inserting a leap second using adjtimex(), it was noticed that the test
no longer slept .1 seconds and was now sleeping 1.1 seconds (an additional 1
second every usleep).

ie)

gettimeofday: 1234051199.616500
gettimeofday: 1234051199.717501
gettimeofday: 1234051199.818504
gettimeofday: 1234051199.919500
gettimeofday: 1234051200.020499 << inserted a leap second
gettimeofday: 1234051201.121438
gettimeofday: 1234051202.222380
gettimeofday: 1234051203.323316
gettimeofday: 1234051204.424255

I have verified that the leap second was inserted by examining the console and
looking for "Clock: inserting leap second 23:59:60 UTC".

A trivial patch was suggested by Fujitsu to fix this issue but I rejected it
because I think it is likely a performance hit (the original patch would
call gettimeofday() for *every* timer interrupt).

This solution (also from Fujitsu) is better:  Use current_kernel_time(),
ie) xtime only, in hrtimer_start().  IMO, this is a lightweight fix.

Successfully compiled and tested on a few ia64 systems by me.

Resolves BZ 485323.

diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c
index 71ac1d3..8479e6f 100644
--- a/kernel/hrtimer.c
+++ b/kernel/hrtimer.c
@@ -63,7 +63,11 @@ static ktime_t ktime_get_real(void)
 {
 	struct timespec now;
 
+#ifdef CONFIG_TIME_INTERPOLATION
+	now = current_kernel_time();
+#else
 	getnstimeofday(&now);
+#endif
 
 	return timespec_to_ktime(now);
 }
@@ -111,7 +115,11 @@ void ktime_get_ts(struct timespec *ts)
 
 	do {
 		seq = read_seqbegin(&xtime_lock);
+#ifdef CONFIG_TIME_INTERPOLATION
+		*ts = xtime;
+#else
 		getnstimeofday(ts);
+#endif
 		tomono = wall_to_monotonic;
 
 	} while (read_seqretry(&xtime_lock, seq));