Messages in this thread Patch in this message | | | Date | Mon, 3 Jul 2006 03:13:39 +0200 (CEST) | From | Roman Zippel <> | Subject | Re: 2.6.17-mm2 hrtimer code wedges at boot? |
| |
Hi,
On Fri, 30 Jun 2006, Valdis.Kletnieks@vt.edu 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 majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| |