aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/time/ntp.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/time/ntp.c')
-rw-r--r--kernel/time/ntp.c182
1 files changed, 99 insertions, 83 deletions
diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c
index fc08eb10ced4..aded09be98cc 100644
--- a/kernel/time/ntp.c
+++ b/kernel/time/ntp.c
@@ -332,6 +332,102 @@ static void notify_cmos_timer(void)
332static inline void notify_cmos_timer(void) { } 332static inline void notify_cmos_timer(void) { }
333#endif 333#endif
334 334
335
336/*
337 * Propagate a new txc->status value into the NTP state:
338 */
339static inline void process_adj_status(struct timex *txc, struct timespec *ts)
340{
341 long now;
342
343 if ((time_status & STA_PLL) && !(txc->status & STA_PLL)) {
344 time_state = TIME_OK;
345 time_status = STA_UNSYNC;
346 }
347 /* only set allowed bits */
348 time_status &= STA_RONLY;
349
350 /*
351 * If we turn on PLL adjustments then reset the
352 * reference time to current time.
353 */
354 if (!(time_status & STA_PLL) && (txc->status & STA_PLL))
355 time_reftime = xtime.tv_sec;
356
357 time_status |= txc->status & ~STA_RONLY;
358
359 switch (time_state) {
360 case TIME_OK:
361 start_timer:
362 now = ts->tv_sec;
363 if (time_status & STA_INS) {
364 time_state = TIME_INS;
365 now += 86400 - now % 86400;
366 hrtimer_start(&leap_timer, ktime_set(now, 0), HRTIMER_MODE_ABS);
367 } else if (time_status & STA_DEL) {
368 time_state = TIME_DEL;
369 now += 86400 - (now + 1) % 86400;
370 hrtimer_start(&leap_timer, ktime_set(now, 0), HRTIMER_MODE_ABS);
371 }
372 break;
373 case TIME_INS:
374 case TIME_DEL:
375 time_state = TIME_OK;
376 goto start_timer;
377 case TIME_WAIT:
378 if (!(time_status & (STA_INS | STA_DEL)))
379 time_state = TIME_OK;
380 break;
381 case TIME_OOP:
382 hrtimer_restart(&leap_timer);
383 break;
384 }
385}
386/*
387 * Called with the xtime lock held, so we can access and modify
388 * all the global NTP state:
389 */
390static inline void process_adjtimex_modes(struct timex *txc, struct timespec *ts)
391{
392 if (txc->modes & ADJ_STATUS)
393 process_adj_status(txc, ts);
394
395 if (txc->modes & ADJ_NANO)
396 time_status |= STA_NANO;
397 if (txc->modes & ADJ_MICRO)
398 time_status &= ~STA_NANO;
399
400 if (txc->modes & ADJ_FREQUENCY) {
401 time_freq = (s64)txc->freq * PPM_SCALE;
402 time_freq = min(time_freq, MAXFREQ_SCALED);
403 time_freq = max(time_freq, -MAXFREQ_SCALED);
404 }
405
406 if (txc->modes & ADJ_MAXERROR)
407 time_maxerror = txc->maxerror;
408 if (txc->modes & ADJ_ESTERROR)
409 time_esterror = txc->esterror;
410
411 if (txc->modes & ADJ_TIMECONST) {
412 time_constant = txc->constant;
413 if (!(time_status & STA_NANO))
414 time_constant += 4;
415 time_constant = min(time_constant, (long)MAXTC);
416 time_constant = max(time_constant, 0l);
417 }
418
419 if (txc->modes & ADJ_TAI && txc->constant > 0)
420 time_tai = txc->constant;
421
422 if (txc->modes & ADJ_OFFSET)
423 ntp_update_offset(txc->offset);
424 if (txc->modes & ADJ_TICK)
425 tick_usec = txc->tick;
426
427 if (txc->modes & (ADJ_TICK|ADJ_FREQUENCY|ADJ_OFFSET))
428 ntp_update_frequency();
429}
430
335/* 431/*
336 * adjtimex mainly allows reading (and writing, if superuser) of 432 * adjtimex mainly allows reading (and writing, if superuser) of
337 * kernel time-keeping variables. used by xntpd. 433 * kernel time-keeping variables. used by xntpd.
@@ -383,90 +479,10 @@ int do_adjtimex(struct timex *txc)
383 txc->offset = save_adjust; 479 txc->offset = save_adjust;
384 goto adj_done; 480 goto adj_done;
385 } 481 }
386 if (txc->modes) {
387 long sec;
388
389 if (txc->modes & ADJ_STATUS) {
390 if ((time_status & STA_PLL) &&
391 !(txc->status & STA_PLL)) {
392 time_state = TIME_OK;
393 time_status = STA_UNSYNC;
394 }
395 /* only set allowed bits */
396 time_status &= STA_RONLY;
397 /*
398 * If we turn on PLL adjustments then reset the
399 * reference time to current time.
400 */
401 if (!(time_status & STA_PLL) && (txc->status & STA_PLL))
402 time_reftime = xtime.tv_sec;
403
404 time_status |= txc->status & ~STA_RONLY;
405
406 switch (time_state) {
407 case TIME_OK:
408 start_timer:
409 sec = ts.tv_sec;
410 if (time_status & STA_INS) {
411 time_state = TIME_INS;
412 sec += 86400 - sec % 86400;
413 hrtimer_start(&leap_timer, ktime_set(sec, 0), HRTIMER_MODE_ABS);
414 } else if (time_status & STA_DEL) {
415 time_state = TIME_DEL;
416 sec += 86400 - (sec + 1) % 86400;
417 hrtimer_start(&leap_timer, ktime_set(sec, 0), HRTIMER_MODE_ABS);
418 }
419 break;
420 case TIME_INS:
421 case TIME_DEL:
422 time_state = TIME_OK;
423 goto start_timer;
424 break;
425 case TIME_WAIT:
426 if (!(time_status & (STA_INS | STA_DEL)))
427 time_state = TIME_OK;
428 break;
429 case TIME_OOP:
430 hrtimer_restart(&leap_timer);
431 break;
432 }
433 }
434
435 if (txc->modes & ADJ_NANO)
436 time_status |= STA_NANO;
437 if (txc->modes & ADJ_MICRO)
438 time_status &= ~STA_NANO;
439 482
440 if (txc->modes & ADJ_FREQUENCY) { 483 /* If there are input parameters, then process them: */
441 time_freq = (s64)txc->freq * PPM_SCALE; 484 if (txc->modes)
442 time_freq = min(time_freq, MAXFREQ_SCALED); 485 process_adjtimex_modes(txc, &ts);
443 time_freq = max(time_freq, -MAXFREQ_SCALED);
444 }
445
446 if (txc->modes & ADJ_MAXERROR)
447 time_maxerror = txc->maxerror;
448 if (txc->modes & ADJ_ESTERROR)
449 time_esterror = txc->esterror;
450
451 if (txc->modes & ADJ_TIMECONST) {
452 time_constant = txc->constant;
453 if (!(time_status & STA_NANO))
454 time_constant += 4;
455 time_constant = min(time_constant, (long)MAXTC);
456 time_constant = max(time_constant, 0l);
457 }
458
459 if (txc->modes & ADJ_TAI && txc->constant > 0)
460 time_tai = txc->constant;
461
462 if (txc->modes & ADJ_OFFSET)
463 ntp_update_offset(txc->offset);
464 if (txc->modes & ADJ_TICK)
465 tick_usec = txc->tick;
466
467 if (txc->modes & (ADJ_TICK|ADJ_FREQUENCY|ADJ_OFFSET))
468 ntp_update_frequency();
469 }
470 486
471 txc->offset = shift_right(time_offset * NTP_INTERVAL_FREQ, 487 txc->offset = shift_right(time_offset * NTP_INTERVAL_FREQ,
472 NTP_SCALE_SHIFT); 488 NTP_SCALE_SHIFT);