summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_clocksource.c
diff options
context:
space:
mode:
authormav <mav@FreeBSD.org>2012-08-04 08:06:37 +0000
committermav <mav@FreeBSD.org>2012-08-04 08:06:37 +0000
commit6d37c6c863075ee08665b371b05f3cb68a371dd8 (patch)
tree54ba3b91ad5b3d3c28dd4b86191cf10013d98c7a /sys/kern/kern_clocksource.c
parent09a1e2c3bcb13b3e985de0481e9e456220ee1996 (diff)
downloadFreeBSD-src-6d37c6c863075ee08665b371b05f3cb68a371dd8.zip
FreeBSD-src-6d37c6c863075ee08665b371b05f3cb68a371dd8.tar.gz
Particlly MFcalloutng r238425 (by davide):
Fix an issue related to old periodic timers. The code in kern_clocksource.c uses interrupt to keep track of time, and this time may not match with binuptime(). In order to address such incoherency, switch periodic timers to binuptime(). Except further calloutng it is needed for already present cyclic subsystem.
Diffstat (limited to 'sys/kern/kern_clocksource.c')
-rw-r--r--sys/kern/kern_clocksource.c17
1 files changed, 6 insertions, 11 deletions
diff --git a/sys/kern/kern_clocksource.c b/sys/kern/kern_clocksource.c
index a622c32..a73536f 100644
--- a/sys/kern/kern_clocksource.c
+++ b/sys/kern/kern_clocksource.c
@@ -356,13 +356,12 @@ timercb(struct eventtimer *et, void *arg)
next = &state->nexttick;
} else
next = &nexttick;
- if (periodic) {
- now = *next; /* Ex-next tick time becomes present time. */
+ binuptime(&now);
+ if (periodic) {
+ *next = now;
bintime_addx(next, timerperiod.frac); /* Next tick in 1 period. */
- } else {
- binuptime(&now); /* Get present time from hardware. */
- next->sec = -1; /* Next tick is not scheduled yet. */
- }
+ } else
+ next->sec = -1; /* Next tick is not scheduled yet. */
state->now = now;
CTR4(KTR_SPARE2, "intr at %d: now %d.%08x%08x",
curcpu, (int)(now.sec), (u_int)(now.frac >> 32),
@@ -714,11 +713,7 @@ cpu_initclocks_ap(void)
state = DPCPU_PTR(timerstate);
binuptime(&now);
ET_HW_LOCK(state);
- if ((timer->et_flags & ET_FLAGS_PERCPU) == 0 && periodic) {
- state->now = nexttick;
- bintime_sub(&state->now, &timerperiod);
- } else
- state->now = now;
+ state->now = now;
hardclock_sync(curcpu);
handleevents(&state->now, 2);
if (timer->et_flags & ET_FLAGS_PERCPU)
OpenPOWER on IntegriCloud