Re: 2.6.17-mm2 hrtimer code wedges at boot?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

On Fri, 30 Jun 2006, [email protected] wrote:

> *AHA* I *found* the bugger, I think.
> 
> In kernel/timer.c, we have:
> 
> static void clocksource_adjust(struct clocksource *clock, s64 offset)
> (s64 used for offset in multiple places).
> 
> However, in other places, offset is a 'cycle_t', which is:
> 
> include/linux/clocksource.h:typedef u64 cycle_t;
> 
> So it looks like a signed/unsigned screwage.

It's a possibility, but the signed/unsigned usage is pretty much 
intentional. The assumptation is that time only goes forward so nothing 
there should become negative, only adjustments happen in both directions.
It's really weird why it's getting completely so out of control early 
during boot. It would be great if you could also test the patch below, it 
should trigger closer to when it goes wrong and help to analyze the 
problem (or at least rule out a number of possibilities).

bye, Roman

---
 kernel/timer.c |   14 ++++++++++++++
 1 file changed, 14 insertions(+)

Index: linux-2.6-mm/kernel/timer.c
===================================================================
--- linux-2.6-mm.orig/kernel/timer.c
+++ linux-2.6-mm/kernel/timer.c
@@ -1078,6 +1078,7 @@ static __always_inline int clocksource_b
  */
 static void clocksource_adjust(struct clocksource *clock, s64 offset)
 {
+	static int cnt = 16;
 	s64 error, interval = clock->cycle_interval;
 	int adj;
 
@@ -1091,6 +1092,13 @@ static void clocksource_adjust(struct cl
 	} else
 		return;
 
+	if ((adj > 10 || adj < -10 || (s32)clock->mult <= -adj) && cnt > 0) {
+		cnt--;
+		printk("big adj at %ld (%Lu,%d,%Ld,%Ld)\n", jiffies, current_tick_length(),
+			adj, interval, offset);
+		printk_clock_info();
+	}
+
 	clock->mult += adj;
 	clock->xtime_interval += interval;
 	clock->xtime_nsec -= offset;
@@ -1149,9 +1157,15 @@ static void update_wall_time(void)
 
 	/* check to see if there is a new clocksource to use */
 	if (change_clocksource()) {
+		static int cnt = 16;
 		clock->error = 0;
 		clock->xtime_nsec = 0;
 		clocksource_calculate_interval(clock, tick_nsec);
+		if (cnt > 0) {
+			cnt--;
+			printk("clock changed at %ld (%Lu)\n", jiffies, current_tick_length());
+			printk_clock_info();
+		}
 	}
 }
 
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux