Make timecounters more resistant to badly behaved SW/HW which locks
out interrupts for too long. If you still see the "calcru: negative time..." message you can increase NTIMECOUNTER (see LINT). Sideeffect is that a timecounter is required to not wrap around in less than (1 + delta) seconds instead of the (1/hz + delta) required until now. Many thanks to: msmith, wpaul, wosch & bde
This commit is contained in:
parent
ba9fb96ddb
commit
1ca888b5fd
@ -2,7 +2,7 @@
|
||||
# LINT -- config file for checking all the sources, tries to pull in
|
||||
# as much of the source tree as it can.
|
||||
#
|
||||
# $Id: LINT,v 1.503 1998/11/11 21:29:09 msmith Exp $
|
||||
# $Id: LINT,v 1.504 1998/11/15 20:08:49 eivind Exp $
|
||||
#
|
||||
# NB: You probably don't want to try running a kernel built from this
|
||||
# file. Instead, you should start from GENERIC, and add options from
|
||||
@ -792,6 +792,14 @@ options "TUNE_1542"
|
||||
|
||||
options PPS_SYNC
|
||||
|
||||
# If you see the "calcru: negative time of %ld usec for pid %d (%s)\n"
|
||||
# message you probably have some broken sw/hw which disables interrupts
|
||||
# for too long. You can make the system more resistant to this by
|
||||
# choosing a high value for NTIMECOUNTER. The default is 5, there
|
||||
# is no upper limit but more than a couple of hundred are not productive.
|
||||
|
||||
options "NTIMECOUNTER=20"
|
||||
|
||||
# Enable PnP support in the kernel. This allows you to automaticly
|
||||
# attach to PnP cards for drivers that support it and allows you to
|
||||
# configure cards from USERCONFIG. See pnp(4) for more info.
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $Id: options,v 1.106 1998/10/28 08:37:10 dfr Exp $
|
||||
# $Id: options,v 1.107 1998/11/05 14:28:17 dg Exp $
|
||||
#
|
||||
# On the handling of kernel options
|
||||
#
|
||||
@ -54,6 +54,7 @@ KTRACE
|
||||
MD5
|
||||
MFS_ROOT opt_mfs.h
|
||||
MFS_ROOT_SIZE opt_mfs.h
|
||||
NTIMECOUNTER opt_ntp.h
|
||||
EXPORTMFS opt_mfs.h
|
||||
NO_LKM
|
||||
NSWAPDEV opt_swap.h
|
||||
|
@ -2,7 +2,7 @@
|
||||
# LINT -- config file for checking all the sources, tries to pull in
|
||||
# as much of the source tree as it can.
|
||||
#
|
||||
# $Id: LINT,v 1.503 1998/11/11 21:29:09 msmith Exp $
|
||||
# $Id: LINT,v 1.504 1998/11/15 20:08:49 eivind Exp $
|
||||
#
|
||||
# NB: You probably don't want to try running a kernel built from this
|
||||
# file. Instead, you should start from GENERIC, and add options from
|
||||
@ -792,6 +792,14 @@ options "TUNE_1542"
|
||||
|
||||
options PPS_SYNC
|
||||
|
||||
# If you see the "calcru: negative time of %ld usec for pid %d (%s)\n"
|
||||
# message you probably have some broken sw/hw which disables interrupts
|
||||
# for too long. You can make the system more resistant to this by
|
||||
# choosing a high value for NTIMECOUNTER. The default is 5, there
|
||||
# is no upper limit but more than a couple of hundred are not productive.
|
||||
|
||||
options "NTIMECOUNTER=20"
|
||||
|
||||
# Enable PnP support in the kernel. This allows you to automaticly
|
||||
# attach to PnP cards for drivers that support it and allows you to
|
||||
# configure cards from USERCONFIG. See pnp(4) for more info.
|
||||
|
@ -2,7 +2,7 @@
|
||||
# LINT -- config file for checking all the sources, tries to pull in
|
||||
# as much of the source tree as it can.
|
||||
#
|
||||
# $Id: LINT,v 1.503 1998/11/11 21:29:09 msmith Exp $
|
||||
# $Id: LINT,v 1.504 1998/11/15 20:08:49 eivind Exp $
|
||||
#
|
||||
# NB: You probably don't want to try running a kernel built from this
|
||||
# file. Instead, you should start from GENERIC, and add options from
|
||||
@ -792,6 +792,14 @@ options "TUNE_1542"
|
||||
|
||||
options PPS_SYNC
|
||||
|
||||
# If you see the "calcru: negative time of %ld usec for pid %d (%s)\n"
|
||||
# message you probably have some broken sw/hw which disables interrupts
|
||||
# for too long. You can make the system more resistant to this by
|
||||
# choosing a high value for NTIMECOUNTER. The default is 5, there
|
||||
# is no upper limit but more than a couple of hundred are not productive.
|
||||
|
||||
options "NTIMECOUNTER=20"
|
||||
|
||||
# Enable PnP support in the kernel. This allows you to automaticly
|
||||
# attach to PnP cards for drivers that support it and allows you to
|
||||
# configure cards from USERCONFIG. See pnp(4) for more info.
|
||||
|
@ -37,7 +37,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)kern_clock.c 8.5 (Berkeley) 1/21/94
|
||||
* $Id: kern_clock.c,v 1.83 1998/10/26 06:13:18 bde Exp $
|
||||
* $Id: kern_clock.c,v 1.84 1998/11/23 09:34:19 sos Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -67,11 +67,14 @@
|
||||
#include <machine/smp.h>
|
||||
#endif
|
||||
|
||||
/* This is where the NTIMECOUNTER option hangs out */
|
||||
#include "opt_ntp.h"
|
||||
|
||||
/*
|
||||
* Number of timecounters used to implement stable storage
|
||||
*/
|
||||
#ifndef NTIMECOUNTER
|
||||
#define NTIMECOUNTER 2
|
||||
#define NTIMECOUNTER 5
|
||||
#endif
|
||||
|
||||
static MALLOC_DEFINE(M_TIMECOUNTER, "timecounter",
|
||||
@ -80,7 +83,7 @@ static MALLOC_DEFINE(M_TIMECOUNTER, "timecounter",
|
||||
static void initclocks __P((void *dummy));
|
||||
SYSINIT(clocks, SI_SUB_CLOCKS, SI_ORDER_FIRST, initclocks, NULL)
|
||||
|
||||
static void tco_forward __P((void));
|
||||
static void tco_forward __P((int force));
|
||||
static void tco_setscales __P((struct timecounter *tc));
|
||||
static __inline unsigned tco_delta __P((struct timecounter *tc));
|
||||
|
||||
@ -222,7 +225,7 @@ hardclock(frame)
|
||||
if (stathz == 0)
|
||||
statclock(frame);
|
||||
|
||||
tco_forward();
|
||||
tco_forward(0);
|
||||
ticks++;
|
||||
|
||||
/*
|
||||
@ -624,14 +627,14 @@ microuptime(struct timeval *tv)
|
||||
}
|
||||
|
||||
void
|
||||
nanouptime(struct timespec *tv)
|
||||
nanouptime(struct timespec *ts)
|
||||
{
|
||||
unsigned count;
|
||||
u_int64_t delta;
|
||||
struct timecounter *tc;
|
||||
|
||||
tc = (struct timecounter *)timecounter;
|
||||
tv->tv_sec = tc->tc_offset_sec;
|
||||
ts->tv_sec = tc->tc_offset_sec;
|
||||
count = tco_delta(tc);
|
||||
delta = tc->tc_offset_nano;
|
||||
delta += ((u_int64_t)count * tc->tc_scale_nano_f);
|
||||
@ -639,9 +642,9 @@ nanouptime(struct timespec *tv)
|
||||
delta += ((u_int64_t)count * tc->tc_scale_nano_i);
|
||||
if (delta >= 1000000000) {
|
||||
delta -= 1000000000;
|
||||
tv->tv_sec++;
|
||||
ts->tv_sec++;
|
||||
}
|
||||
tv->tv_nsec = delta;
|
||||
ts->tv_nsec = delta;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -709,7 +712,7 @@ set_timecounter(struct timespec *ts)
|
||||
boottime.tv_sec--;
|
||||
}
|
||||
/* fiddle all the little crinkly bits around the fiords... */
|
||||
tco_forward();
|
||||
tco_forward(1);
|
||||
}
|
||||
|
||||
|
||||
@ -757,7 +760,7 @@ sync_other_counter(void)
|
||||
}
|
||||
|
||||
static void
|
||||
tco_forward(void)
|
||||
tco_forward(int force)
|
||||
{
|
||||
struct timecounter *tc, *tco;
|
||||
|
||||
@ -777,6 +780,7 @@ tco_forward(void)
|
||||
if (timedelta != 0) {
|
||||
tc->tc_offset_nano += (u_int64_t)(tickdelta * 1000) << 32;
|
||||
timedelta -= tickdelta;
|
||||
force++;
|
||||
}
|
||||
|
||||
while (tc->tc_offset_nano >= 1000000000ULL << 32) {
|
||||
@ -786,8 +790,12 @@ tco_forward(void)
|
||||
tc->tc_adjustment = tc->tc_tweak->tc_adjustment;
|
||||
ntp_update_second(tc); /* XXX only needed if xntpd runs */
|
||||
tco_setscales(tc);
|
||||
force++;
|
||||
}
|
||||
|
||||
if (!force)
|
||||
return;
|
||||
|
||||
tc->tc_offset_micro = (tc->tc_offset_nano / 1000) >> 32;
|
||||
|
||||
/* Figure out the wall-clock time */
|
||||
|
@ -37,7 +37,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)kern_clock.c 8.5 (Berkeley) 1/21/94
|
||||
* $Id: kern_clock.c,v 1.83 1998/10/26 06:13:18 bde Exp $
|
||||
* $Id: kern_clock.c,v 1.84 1998/11/23 09:34:19 sos Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -67,11 +67,14 @@
|
||||
#include <machine/smp.h>
|
||||
#endif
|
||||
|
||||
/* This is where the NTIMECOUNTER option hangs out */
|
||||
#include "opt_ntp.h"
|
||||
|
||||
/*
|
||||
* Number of timecounters used to implement stable storage
|
||||
*/
|
||||
#ifndef NTIMECOUNTER
|
||||
#define NTIMECOUNTER 2
|
||||
#define NTIMECOUNTER 5
|
||||
#endif
|
||||
|
||||
static MALLOC_DEFINE(M_TIMECOUNTER, "timecounter",
|
||||
@ -80,7 +83,7 @@ static MALLOC_DEFINE(M_TIMECOUNTER, "timecounter",
|
||||
static void initclocks __P((void *dummy));
|
||||
SYSINIT(clocks, SI_SUB_CLOCKS, SI_ORDER_FIRST, initclocks, NULL)
|
||||
|
||||
static void tco_forward __P((void));
|
||||
static void tco_forward __P((int force));
|
||||
static void tco_setscales __P((struct timecounter *tc));
|
||||
static __inline unsigned tco_delta __P((struct timecounter *tc));
|
||||
|
||||
@ -222,7 +225,7 @@ hardclock(frame)
|
||||
if (stathz == 0)
|
||||
statclock(frame);
|
||||
|
||||
tco_forward();
|
||||
tco_forward(0);
|
||||
ticks++;
|
||||
|
||||
/*
|
||||
@ -624,14 +627,14 @@ microuptime(struct timeval *tv)
|
||||
}
|
||||
|
||||
void
|
||||
nanouptime(struct timespec *tv)
|
||||
nanouptime(struct timespec *ts)
|
||||
{
|
||||
unsigned count;
|
||||
u_int64_t delta;
|
||||
struct timecounter *tc;
|
||||
|
||||
tc = (struct timecounter *)timecounter;
|
||||
tv->tv_sec = tc->tc_offset_sec;
|
||||
ts->tv_sec = tc->tc_offset_sec;
|
||||
count = tco_delta(tc);
|
||||
delta = tc->tc_offset_nano;
|
||||
delta += ((u_int64_t)count * tc->tc_scale_nano_f);
|
||||
@ -639,9 +642,9 @@ nanouptime(struct timespec *tv)
|
||||
delta += ((u_int64_t)count * tc->tc_scale_nano_i);
|
||||
if (delta >= 1000000000) {
|
||||
delta -= 1000000000;
|
||||
tv->tv_sec++;
|
||||
ts->tv_sec++;
|
||||
}
|
||||
tv->tv_nsec = delta;
|
||||
ts->tv_nsec = delta;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -709,7 +712,7 @@ set_timecounter(struct timespec *ts)
|
||||
boottime.tv_sec--;
|
||||
}
|
||||
/* fiddle all the little crinkly bits around the fiords... */
|
||||
tco_forward();
|
||||
tco_forward(1);
|
||||
}
|
||||
|
||||
|
||||
@ -757,7 +760,7 @@ sync_other_counter(void)
|
||||
}
|
||||
|
||||
static void
|
||||
tco_forward(void)
|
||||
tco_forward(int force)
|
||||
{
|
||||
struct timecounter *tc, *tco;
|
||||
|
||||
@ -777,6 +780,7 @@ tco_forward(void)
|
||||
if (timedelta != 0) {
|
||||
tc->tc_offset_nano += (u_int64_t)(tickdelta * 1000) << 32;
|
||||
timedelta -= tickdelta;
|
||||
force++;
|
||||
}
|
||||
|
||||
while (tc->tc_offset_nano >= 1000000000ULL << 32) {
|
||||
@ -786,8 +790,12 @@ tco_forward(void)
|
||||
tc->tc_adjustment = tc->tc_tweak->tc_adjustment;
|
||||
ntp_update_second(tc); /* XXX only needed if xntpd runs */
|
||||
tco_setscales(tc);
|
||||
force++;
|
||||
}
|
||||
|
||||
if (!force)
|
||||
return;
|
||||
|
||||
tc->tc_offset_micro = (tc->tc_offset_nano / 1000) >> 32;
|
||||
|
||||
/* Figure out the wall-clock time */
|
||||
|
Loading…
Reference in New Issue
Block a user