svn commit: r214987 - head/sys/kern
Alexander Motin
mav at FreeBSD.org
Mon Nov 8 15:25:12 UTC 2010
Author: mav
Date: Mon Nov 8 15:25:12 2010
New Revision: 214987
URL: http://svn.freebsd.org/changeset/base/214987
Log:
On APs startup skip hard-/statclock events, which time passed before CPU
was lauched. Few seconds event burst, accumulated during long startup,
reported to cause panic in SCHED_ULE priority calculation logic.
Modified:
head/sys/kern/kern_clocksource.c
Modified: head/sys/kern/kern_clocksource.c
==============================================================================
--- head/sys/kern/kern_clocksource.c Mon Nov 8 15:22:20 2010 (r214986)
+++ head/sys/kern/kern_clocksource.c Mon Nov 8 15:25:12 2010 (r214987)
@@ -208,12 +208,13 @@ handleevents(struct bintime *now, int fa
bintime_add(&state->nexthard, &hardperiod);
runs++;
}
- if (runs) {
+ if (runs && fake < 2) {
hardclock_anycpu(runs, usermode);
done = 1;
}
while (bintime_cmp(now, &state->nextstat, >=)) {
- statclock(usermode);
+ if (fake < 2)
+ statclock(usermode);
bintime_add(&state->nextstat, &statperiod);
done = 1;
}
@@ -227,6 +228,10 @@ handleevents(struct bintime *now, int fa
} else
state->nextprof = state->nextstat;
getnextcpuevent(&t, 0);
+ if (fake == 2) {
+ state->nextevent = t;
+ return (done);
+ }
ET_HW_LOCK(state);
if (!busy) {
state->idle = 0;
@@ -383,6 +388,11 @@ loadtimer(struct bintime *now, int start
uint64_t tmp;
int eq;
+ if (timer->et_flags & ET_FLAGS_PERCPU) {
+ state = DPCPU_PTR(timerstate);
+ next = &state->nexttick;
+ } else
+ next = &nexttick;
if (periodic) {
if (start) {
/*
@@ -391,20 +401,18 @@ loadtimer(struct bintime *now, int start
*/
tmp = ((uint64_t)now->sec << 36) + (now->frac >> 28);
tmp = (tmp % (timerperiod.frac >> 28)) << 28;
- tmp = timerperiod.frac - tmp;
- new = timerperiod;
- bintime_addx(&new, tmp);
+ new.sec = 0;
+ new.frac = timerperiod.frac - tmp;
+ if (new.frac < tmp) /* Left less then passed. */
+ bintime_add(&new, &timerperiod);
CTR5(KTR_SPARE2, "load p at %d: now %d.%08x first in %d.%08x",
curcpu, now->sec, (unsigned int)(now->frac >> 32),
new.sec, (unsigned int)(new.frac >> 32));
+ *next = new;
+ bintime_add(next, now);
et_start(timer, &new, &timerperiod);
}
} else {
- if (timer->et_flags & ET_FLAGS_PERCPU) {
- state = DPCPU_PTR(timerstate);
- next = &state->nexttick;
- } else
- next = &nexttick;
getnextevent(&new);
eq = bintime_cmp(&new, next, ==);
CTR5(KTR_SPARE2, "load at %d: next %d.%08x%08x eq %d",
@@ -669,13 +677,19 @@ cpu_initclocks_ap(void)
struct bintime now;
struct pcpu_state *state;
- if (timer->et_flags & ET_FLAGS_PERCPU) {
- state = DPCPU_PTR(timerstate);
- binuptime(&now);
- ET_HW_LOCK(state);
+ 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;
+ hardclock_sync(curcpu);
+ handleevents(&state->now, 2);
+ if (timer->et_flags & ET_FLAGS_PERCPU)
loadtimer(&now, 1);
- ET_HW_UNLOCK(state);
- }
+ ET_HW_UNLOCK(state);
}
/*
More information about the svn-src-head
mailing list