DragonFly bugs List (threaded) for 2004-11
[
Date Prev][
Date Next]
[
Thread Prev][
Thread Next]
[
Date Index][
Thread Index]
Re: Core dumps...
:> :[ adamk@sorrow - ~ ]: gnome-terminal
:> :Fatal error 'gc cannot wait for a signal' at line ? in file /usr/src/lib/libc_r/uthread/uthread_gc.c (errno = ?)
:> :Abort trap (core dumped)
:> :
:> :Same for mozilla, thunderbird, firefox, etc..
:> :
:> :I left my machine, brushed my teeth, came back, and suddenly it's working again. Any ideas what happened?
:> :
:> :Adam
:>
:>...
:
:I'm seeing this too when my laptop resumed from suspended state, and my
:workaround is to adjust your system clock (with ntpdate for instance)
:a few times. You'll get "Invalid argument" error from ntpdate, but just ignore
:it and try a few times.
Well, they say a fresh look always helps, and it looks like that
is true. In about 5 seconds I found an overflow in the
'cputimer_freq64_nsec * delta' calculations in kern_clock.c.
It turns out that cputimer_freq_nsec is such a large number that
it doesn't take a delta much larger then cputimer_freq to overflow
it, and the delta calculation can certainly exceed cputimer_freq
due to all sorts of reasons... interrupt latency, blockages, and other
things. laptop resumption only being one of them.
So I would like both of you to please try this patch and tell me what
happens.
-Matt
Matthew Dillon
<dillon@xxxxxxxxxxxxx>
Index: kern_clock.c
===================================================================
RCS file: /cvs/src/sys/kern/kern_clock.c,v
retrieving revision 1.24
diff -u -r1.24 kern_clock.c
--- kern_clock.c 17 Sep 2004 00:18:09 -0000 1.24
+++ kern_clock.c 11 Nov 2004 19:53:13 -0000
@@ -279,10 +279,14 @@
* stay in synch.
*
* Note that we never allow info->time (aka gd->gd_hardclock.time)
- * to reverse index gd_cpuclock_base.
+ * to reverse index gd_cpuclock_base, but that it is possible for
+ * it to temporarily get behind in the seconds if something in the
+ * system locks interrupts for a long period of time. Since periodic
+ * timers count events, though everything should resynch again
+ * immediately.
*/
cputicks = info->time - gd->gd_cpuclock_base;
- if (cputicks > cputimer_freq) {
+ if (cputicks >= cputimer_freq) {
++gd->gd_time_seconds;
gd->gd_cpuclock_base += cputimer_freq;
}
@@ -676,6 +680,12 @@
* Each cpu independantly maintains the current time of day, so all
* we need to do to protect ourselves from changes is to do a loop
* check on the seconds field changing out from under us.
+ *
+ * The system timer maintains a 32 bit count and due to various issues
+ * it is possible for the calculated delta to occassionally exceed
+ * cputimer_freq. If this occurs the cputimer_freq64_nsec multiplication
+ * can easily overflow, so we deal with the case. For uniformity we deal
+ * with the case in the usec case too.
*/
void
getmicrouptime(struct timeval *tvp)
@@ -687,6 +697,11 @@
tvp->tv_sec = gd->gd_time_seconds;
delta = gd->gd_hardclock.time - gd->gd_cpuclock_base;
} while (tvp->tv_sec != gd->gd_time_seconds);
+
+ if (delta >= cputimer_freq) {
+ tvp->tv_sec += delta / cputimer_freq;
+ delta %= cputimer_freq;
+ }
tvp->tv_usec = (cputimer_freq64_usec * delta) >> 32;
if (tvp->tv_usec >= 1000000) {
tvp->tv_usec -= 1000000;
@@ -704,11 +719,12 @@
tsp->tv_sec = gd->gd_time_seconds;
delta = gd->gd_hardclock.time - gd->gd_cpuclock_base;
} while (tsp->tv_sec != gd->gd_time_seconds);
- tsp->tv_nsec = (cputimer_freq64_nsec * delta) >> 32;
- if (tsp->tv_nsec >= 1000000000) {
- tsp->tv_nsec -= 1000000000;
- ++tsp->tv_sec;
+
+ if (delta >= cputimer_freq) {
+ tsp->tv_sec += delta / cputimer_freq;
+ delta %= cputimer_freq;
}
+ tsp->tv_nsec = (cputimer_freq64_nsec * delta) >> 32;
}
void
@@ -721,11 +737,12 @@
tvp->tv_sec = gd->gd_time_seconds;
delta = cputimer_count() - gd->gd_cpuclock_base;
} while (tvp->tv_sec != gd->gd_time_seconds);
- tvp->tv_usec = (cputimer_freq64_usec * delta) >> 32;
- if (tvp->tv_usec >= 1000000) {
- tvp->tv_usec -= 1000000;
- ++tvp->tv_sec;
+
+ if (delta >= cputimer_freq) {
+ tvp->tv_sec += delta / cputimer_freq;
+ delta %= cputimer_freq;
}
+ tvp->tv_usec = (cputimer_freq64_usec * delta) >> 32;
}
void
@@ -738,11 +755,12 @@
tsp->tv_sec = gd->gd_time_seconds;
delta = cputimer_count() - gd->gd_cpuclock_base;
} while (tsp->tv_sec != gd->gd_time_seconds);
- tsp->tv_nsec = (cputimer_freq64_nsec * delta) >> 32;
- if (tsp->tv_nsec >= 1000000000) {
- tsp->tv_nsec -= 1000000000;
- ++tsp->tv_sec;
+
+ if (delta >= cputimer_freq) {
+ tsp->tv_sec += delta / cputimer_freq;
+ delta %= cputimer_freq;
}
+ tsp->tv_nsec = (cputimer_freq64_nsec * delta) >> 32;
}
/*
@@ -759,6 +777,11 @@
tvp->tv_sec = gd->gd_time_seconds;
delta = gd->gd_hardclock.time - gd->gd_cpuclock_base;
} while (tvp->tv_sec != gd->gd_time_seconds);
+
+ if (delta >= cputimer_freq) {
+ tvp->tv_sec += delta / cputimer_freq;
+ delta %= cputimer_freq;
+ }
tvp->tv_usec = (cputimer_freq64_usec * delta) >> 32;
tvp->tv_sec += basetime.tv_sec;
@@ -779,6 +802,11 @@
tsp->tv_sec = gd->gd_time_seconds;
delta = gd->gd_hardclock.time - gd->gd_cpuclock_base;
} while (tsp->tv_sec != gd->gd_time_seconds);
+
+ if (delta >= cputimer_freq) {
+ tsp->tv_sec += delta / cputimer_freq;
+ delta %= cputimer_freq;
+ }
tsp->tv_nsec = (cputimer_freq64_nsec * delta) >> 32;
tsp->tv_sec += basetime.tv_sec;
@@ -799,6 +827,11 @@
tvp->tv_sec = gd->gd_time_seconds;
delta = cputimer_count() - gd->gd_cpuclock_base;
} while (tvp->tv_sec != gd->gd_time_seconds);
+
+ if (delta >= cputimer_freq) {
+ tvp->tv_sec += delta / cputimer_freq;
+ delta %= cputimer_freq;
+ }
tvp->tv_usec = (cputimer_freq64_usec * delta) >> 32;
tvp->tv_sec += basetime.tv_sec;
@@ -819,6 +852,11 @@
tsp->tv_sec = gd->gd_time_seconds;
delta = cputimer_count() - gd->gd_cpuclock_base;
} while (tsp->tv_sec != gd->gd_time_seconds);
+
+ if (delta >= cputimer_freq) {
+ tsp->tv_sec += delta / cputimer_freq;
+ delta %= cputimer_freq;
+ }
tsp->tv_nsec = (cputimer_freq64_nsec * delta) >> 32;
tsp->tv_sec += basetime.tv_sec;
@@ -941,7 +979,8 @@
ts.tv_sec = gd->gd_time_seconds;
delta = count - gd->gd_cpuclock_base;
} while (ts.tv_sec != gd->gd_time_seconds);
- if (delta > cputimer_freq) {
+
+ if (delta >= cputimer_freq) {
ts.tv_sec += delta / cputimer_freq;
delta %= cputimer_freq;
}
@@ -968,7 +1007,13 @@
/* magic, at its best... */
tcount = count - pps->ppscount[2];
pps->ppscount[2] = count;
- delta = (cputimer_freq64_nsec * tcount) >> 32;
+ if (tcount >= cputimer_freq) {
+ delta = 1000000000 * (tcount / cputimer_freq) +
+ (cputimer_freq64_nsec *
+ (tcount % cputimer_freq)) >> 32;
+ } else {
+ delta = (cputimer_freq64_nsec * tcount) >> 32;
+ }
hardpps(tsp, delta);
}
#endif
[
Date Prev][
Date Next]
[
Thread Prev][
Thread Next]
[
Date Index][
Thread Index]