Fixed the calculation of `delta' in settime(). We once set all

times consistently wrong (up to 1 tick too late), but recent changes
fixed the setting of the main clock, making other times inconsistent.
The inconsistencies tended to show up as a negative resource usage
for the process that set the time.

Fixed the check for setting the clock backwards.  A stale timestamp
(`time') was checked, so it was possible to set the clock backwards
by up to almost 1 tick.  Until recently, this bug was compensated
for by setting the clock consistently wrong.

Merged the comment about setting the clock backwards from Lite2.

Removed latency micro-optimizations/speed pessimizations in settime().
microtime() and set_timecounter() are relatively expensive, and
they must be called together with clock updates blocked to get a
consistent `delta', so significant latency optimizations are not
possible.

Removed some stale comments.
This commit is contained in:
bde 1998-02-25 04:10:32 +00:00
parent 014146c040
commit 6898166010

View File

@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)kern_time.c 8.1 (Berkeley) 6/10/93
* $Id: kern_time.c,v 1.40 1997/11/07 08:52:58 phk Exp $
* $Id: kern_time.c,v 1.41 1998/02/20 16:35:53 phk Exp $
*/
#include <sys/param.h>
@ -77,43 +77,32 @@ static int
settime(tv)
struct timeval *tv;
{
struct timeval delta;
struct timeval delta, tv1;
struct timespec ts;
struct proc *p;
int s;
/*
* Must not set clock backwards in highly secure mode.
*/
s = splclock();
delta.tv_sec = tv->tv_sec - time.tv_sec;
delta.tv_usec = tv->tv_usec - time.tv_usec;
splx(s);
microtime(&tv1);
delta.tv_sec = tv->tv_sec - tv1.tv_sec;
delta.tv_usec = tv->tv_usec - tv1.tv_usec;
timevalfix(&delta);
if (delta.tv_sec < 0 && securelevel > 1)
return (EPERM);
s = splclock();
/*
* Recalculate delta directly to minimize clock interrupt
* latency. Fix it after the ipl has been lowered.
* If the system is secure, we do not allow the time to be
* set to an earlier value (it may be slowed using adjtime,
* but not set back). This feature prevent interlopers from
* setting arbitrary time stamps on files.
*/
delta.tv_sec = tv->tv_sec - time.tv_sec;
delta.tv_usec = tv->tv_usec - time.tv_usec;
if (delta.tv_sec < 0 && securelevel > 1) {
splx(s);
return (EPERM);
}
ts.tv_sec = tv->tv_sec;
ts.tv_nsec = tv->tv_usec * 1000;
set_timecounter(&ts);
/*
* XXX should arrange for microtime() to agree with *tv if
* it is called now. As it is, it may add up to about
* `tick' unwanted usec.
* Another problem is that clock interrupts may occur at
* other than multiples of `tick'. It's not worth fixing
* this here, since the problem is also caused by tick
* adjustments.
*/
(void) splsoftclock();
timevalfix(&delta);
timevaladd(&boottime, &delta);
timevaladd(&runtime, &delta);
for (p = allproc.lh_first; p != 0; p = p->p_list.le_next) {
@ -239,10 +228,6 @@ nanosleep1(p, rqt, rmt)
atv.tv_usec = 0;
}
}
/*
* XXX this is not as careful as settimeofday() about minimising
* interrupt latency. The hzto() interface is inconvenient as usual.
*/
s = splclock();
timevaladd(&atv, &time);
timo = hzto(&atv);