public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] optimize writer path in time_interpolator_get_counter()
@ 2005-08-01 15:52 Alex Williamson
  2005-08-01 16:06 ` Christoph Lameter
  0 siblings, 1 reply; 12+ messages in thread
From: Alex Williamson @ 2005-08-01 15:52 UTC (permalink / raw)
  To: linux-kernel; +Cc: akpm, tony.luck, clameter


   When using a time interpolator that is susceptible to jitter there's
potentially contention over a cmpxchg used to prevent time from going
backwards.  This is unnecessary when the caller holds the xtime write
seqlock as all readers will be blocked from returning until the write is
complete.  We can therefore allow writers to insert a new value and exit
rather than fight with CPUs who only hold a reader lock.

Signed-off-by: Alex Williamson <alex.williamson@hp.com>

diff -r cff8d3633e9c kernel/timer.c
--- a/kernel/timer.c	Fri Jul 29 22:01:15 2005
+++ b/kernel/timer.c	Mon Aug  1 08:39:44 2005
@@ -1428,7 +1428,7 @@
 	}
 }
 
-static inline u64 time_interpolator_get_counter(void)
+static inline u64 time_interpolator_get_counter(int writelock)
 {
 	unsigned int src = time_interpolator->source;
 
@@ -1436,6 +1436,20 @@
 	{
 		u64 lcycle;
 		u64 now;
+
+		if (writelock) {
+			lcycle = time_interpolator->last_cycle;
+			now = time_interpolator_get_cycles(src);
+			if (lcycle && time_after(lcycle, now))
+				return lcycle;
+
+			/* When holding the xtime write lock, there's no need
+			 * to add the overhead of the cmpxchg.  Readers are
+			 * force to retry until the write lock is released.
+			 */
+			time_interpolator->last_cycle = now;
+			return now;
+		}
 
 		do {
 			lcycle = time_interpolator->last_cycle;
@@ -1455,7 +1469,7 @@
 void time_interpolator_reset(void)
 {
 	time_interpolator->offset = 0;
-	time_interpolator->last_counter = time_interpolator_get_counter();
+	time_interpolator->last_counter = time_interpolator_get_counter(1);
 }
 
 #define GET_TI_NSECS(count,i) (((((count) - i->last_counter) & (i)->mask) * (i)->nsec_per_cyc) >> (i)->shift)
@@ -1467,7 +1481,7 @@
 		return 0;
 
 	return time_interpolator->offset +
-		GET_TI_NSECS(time_interpolator_get_counter(), time_interpolator);
+		GET_TI_NSECS(time_interpolator_get_counter(0), time_interpolator);
 }
 
 #define INTERPOLATOR_ADJUST 65536
@@ -1490,7 +1504,7 @@
 	 * and the tuning logic insures that.
          */
 
-	counter = time_interpolator_get_counter();
+	counter = time_interpolator_get_counter(1);
 	offset = time_interpolator->offset + GET_TI_NSECS(counter, time_interpolator);
 
 	if (delta_nsec < 0 || (unsigned long) delta_nsec < offset)



^ permalink raw reply	[flat|nested] 12+ messages in thread
* RE: [PATCH] optimize writer path in time_interpolator_get_counter()
@ 2005-08-02 21:50 Luck, Tony
  2005-08-02 22:09 ` Christoph Lameter
  0 siblings, 1 reply; 12+ messages in thread
From: Luck, Tony @ 2005-08-02 21:50 UTC (permalink / raw)
  To: Christoph Lameter; +Cc: Alex Williamson, linux-kernel, akpm

>> I'm still seeing the asymmetric behavior where cpu3 sees the really high times,
>> while cpu0,1,2 are seeing peaks of 170us, which is still not pretty.
>
>Is this an SMP system? Updates are performed by cpu0 and therefore the 
>cacheline is mostly exclusively owned by that processor and then later 
>forced to become shared by processors 1,2,3.

Yes this is an SMP system (Intel Tiger4).  Cpu0 is the boot cpu, and is
indeed the one that takes the write lock, and thus the fast-return from
the get_counter() code.  I'm just very confused as to why I only see these
10X worse outliers on cpu3.  There doesn't seem to be anything special
about it (/proc/interrupts shows similar stuff happening on each cpu).

>We can still switch on the nojitter by default if the ITC's are guaranteed 
>to be properly synchronized which will make all this ugliness go away. 

What do you mean by "properly synchronized"?  We can't get them
completely in step ... but we do know that they are very close.
Closer than the microsecond granularity that most users (gettimeofday)
are going to pass back to the caller.  But running with "nojitter" will
occasionally result in time (as seen on two different processors) sometimes
jumping back by a microsecond.  How bad is this in practice?  I can
see that a user that simply subtracts two times may sometimes see an
answer of minus one micro-second ... but does this hurt?

-Tony

^ permalink raw reply	[flat|nested] 12+ messages in thread
* RE: [PATCH] optimize writer path in time_interpolator_get_counter()
@ 2005-08-03 17:00 Luck, Tony
  0 siblings, 0 replies; 12+ messages in thread
From: Luck, Tony @ 2005-08-03 17:00 UTC (permalink / raw)
  To: Christoph Lameter, Alex Williamson; +Cc: linux-kernel, akpm


>Think about a threaded process that gets time on multiple processors 
>and then compares the times. This means that the time value obtained later 
>on one thread may indicate a time earlier than that obtained on another 
>thread. An essential requirement for time values is that they are 
>monotonically increasing. You are changing that basic nature.

But this comes down to how much time does it take for two threads
to perform some synchronization operation so that they know that one
thread made the call before the other[1]?  I think that it might be
possible to make the claim[2] that we have synchonized the ITC values
more closely than the fastest user synchronization method ... hence
a simplistic kernel implementation will be monotonic in practice.

-Tony

[1] It is pointless to expect one return value to be greater than
another unless we know that the calls were made in a particular sequence.

[2] Hands are waving so wildly here that it is a wonder that I can
even type.

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

end of thread, other threads:[~2005-08-03 20:49 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-08-01 15:52 [PATCH] optimize writer path in time_interpolator_get_counter() Alex Williamson
2005-08-01 16:06 ` Christoph Lameter
2005-08-01 16:10   ` Alex Williamson
2005-08-02 18:37   ` tony.luck
2005-08-02 21:19     ` Christoph Lameter
2005-08-03 14:42     ` Alex Williamson
2005-08-03 16:10       ` Christoph Lameter
2005-08-03 16:32         ` Alex Williamson
2005-08-03 20:49           ` Christoph Lameter
  -- strict thread matches above, loose matches on Subject: below --
2005-08-02 21:50 Luck, Tony
2005-08-02 22:09 ` Christoph Lameter
2005-08-03 17:00 Luck, Tony

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