1 /* $OpenBSD: kern_tc.c,v 1.68 2020/07/20 22:40:53 deraadt Exp $ */ 2 3 /* 4 * Copyright (c) 2000 Poul-Henning Kamp <phk@FreeBSD.org> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 /* 20 * If we meet some day, and you think this stuff is worth it, you 21 * can buy me a beer in return. Poul-Henning Kamp 22 */ 23 24 #include <sys/param.h> 25 #include <sys/atomic.h> 26 #include <sys/kernel.h> 27 #include <sys/mutex.h> 28 #include <sys/rwlock.h> 29 #include <sys/stdint.h> 30 #include <sys/timeout.h> 31 #include <sys/sysctl.h> 32 #include <sys/syslog.h> 33 #include <sys/systm.h> 34 #include <sys/timetc.h> 35 #include <sys/queue.h> 36 #include <sys/malloc.h> 37 38 u_int dummy_get_timecount(struct timecounter *); 39 40 int sysctl_tc_hardware(void *, size_t *, void *, size_t); 41 int sysctl_tc_choice(void *, size_t *, void *, size_t); 42 43 /* 44 * Implement a dummy timecounter which we can use until we get a real one 45 * in the air. This allows the console and other early stuff to use 46 * time services. 47 */ 48 49 u_int 50 dummy_get_timecount(struct timecounter *tc) 51 { 52 static u_int now; 53 54 return atomic_inc_int_nv(&now); 55 } 56 57 static struct timecounter dummy_timecounter = { 58 dummy_get_timecount, 0, ~0u, 1000000, "dummy", -1000000, NULL, 0 59 }; 60 61 /* 62 * Locks used to protect struct members, global variables in this file: 63 * I immutable after initialization 64 * T tc_lock 65 * W windup_mtx 66 */ 67 68 struct timehands { 69 /* These fields must be initialized by the driver. */ 70 struct timecounter *th_counter; /* [W] */ 71 int64_t th_adjtimedelta; /* [T,W] */ 72 struct bintime th_next_ntp_update; /* [T,W] */ 73 int64_t th_adjustment; /* [W] */ 74 u_int64_t th_scale; /* [W] */ 75 u_int th_offset_count; /* [W] */ 76 struct bintime th_boottime; /* [T,W] */ 77 struct bintime th_offset; /* [W] */ 78 struct bintime th_naptime; /* [W] */ 79 struct timeval th_microtime; /* [W] */ 80 struct timespec th_nanotime; /* [W] */ 81 /* Fields not to be copied in tc_windup start with th_generation. */ 82 volatile u_int th_generation; /* [W] */ 83 struct timehands *th_next; /* [I] */ 84 }; 85 86 static struct timehands th0; 87 static struct timehands th1 = { 88 .th_next = &th0 89 }; 90 static struct timehands th0 = { 91 .th_counter = &dummy_timecounter, 92 .th_scale = UINT64_MAX / 1000000, 93 .th_offset = { .sec = 1, .frac = 0 }, 94 .th_generation = 1, 95 .th_next = &th1 96 }; 97 98 struct rwlock tc_lock = RWLOCK_INITIALIZER("tc_lock"); 99 100 /* 101 * tc_windup() must be called before leaving this mutex. 102 */ 103 struct mutex windup_mtx = MUTEX_INITIALIZER(IPL_CLOCK); 104 105 static struct timehands *volatile timehands = &th0; /* [W] */ 106 struct timecounter *timecounter = &dummy_timecounter; /* [T] */ 107 static SLIST_HEAD(, timecounter) tc_list = SLIST_HEAD_INITIALIZER(tc_list); 108 109 /* 110 * These are updated from tc_windup(). They are useful when 111 * examining kernel core dumps. 112 */ 113 volatile time_t time_second = 1; 114 volatile time_t time_uptime = 0; 115 116 static int timestepwarnings; 117 118 void ntp_update_second(struct timehands *); 119 void tc_windup(struct bintime *, struct bintime *, int64_t *); 120 121 /* 122 * Return the difference between the timehands' counter value now and what 123 * was when we copied it to the timehands' offset_count. 124 */ 125 static __inline u_int 126 tc_delta(struct timehands *th) 127 { 128 struct timecounter *tc; 129 130 tc = th->th_counter; 131 return ((tc->tc_get_timecount(tc) - th->th_offset_count) & 132 tc->tc_counter_mask); 133 } 134 135 /* 136 * Functions for reading the time. We have to loop until we are sure that 137 * the timehands that we operated on was not updated under our feet. See 138 * the comment in <sys/time.h> for a description of these functions. 139 */ 140 141 void 142 binboottime(struct bintime *bt) 143 { 144 struct timehands *th; 145 u_int gen; 146 147 do { 148 th = timehands; 149 gen = th->th_generation; 150 membar_consumer(); 151 *bt = th->th_boottime; 152 membar_consumer(); 153 } while (gen == 0 || gen != th->th_generation); 154 } 155 156 void 157 microboottime(struct timeval *tvp) 158 { 159 struct bintime bt; 160 161 binboottime(&bt); 162 BINTIME_TO_TIMEVAL(&bt, tvp); 163 } 164 165 void 166 nanoboottime(struct timespec *tsp) 167 { 168 struct bintime bt; 169 170 binboottime(&bt); 171 BINTIME_TO_TIMESPEC(&bt, tsp); 172 } 173 174 void 175 binuptime(struct bintime *bt) 176 { 177 struct timehands *th; 178 u_int gen; 179 180 do { 181 th = timehands; 182 gen = th->th_generation; 183 membar_consumer(); 184 *bt = th->th_offset; 185 bintimeaddfrac(bt, th->th_scale * tc_delta(th), bt); 186 membar_consumer(); 187 } while (gen == 0 || gen != th->th_generation); 188 } 189 190 void 191 nanouptime(struct timespec *tsp) 192 { 193 struct bintime bt; 194 195 binuptime(&bt); 196 BINTIME_TO_TIMESPEC(&bt, tsp); 197 } 198 199 void 200 microuptime(struct timeval *tvp) 201 { 202 struct bintime bt; 203 204 binuptime(&bt); 205 BINTIME_TO_TIMEVAL(&bt, tvp); 206 } 207 208 time_t 209 getuptime(void) 210 { 211 #if defined(__LP64__) 212 return time_uptime; /* atomic */ 213 #else 214 time_t now; 215 struct timehands *th; 216 u_int gen; 217 218 do { 219 th = timehands; 220 gen = th->th_generation; 221 membar_consumer(); 222 now = th->th_offset.sec; 223 membar_consumer(); 224 } while (gen == 0 || gen != th->th_generation); 225 226 return now; 227 #endif 228 } 229 230 void 231 binruntime(struct bintime *bt) 232 { 233 struct timehands *th; 234 u_int gen; 235 236 do { 237 th = timehands; 238 gen = th->th_generation; 239 membar_consumer(); 240 bintimeaddfrac(&th->th_offset, th->th_scale * tc_delta(th), bt); 241 bintimesub(bt, &th->th_naptime, bt); 242 membar_consumer(); 243 } while (gen == 0 || gen != th->th_generation); 244 } 245 246 void 247 nanoruntime(struct timespec *ts) 248 { 249 struct bintime bt; 250 251 binruntime(&bt); 252 BINTIME_TO_TIMESPEC(&bt, ts); 253 } 254 255 void 256 bintime(struct bintime *bt) 257 { 258 struct timehands *th; 259 u_int gen; 260 261 do { 262 th = timehands; 263 gen = th->th_generation; 264 membar_consumer(); 265 *bt = th->th_offset; 266 bintimeaddfrac(bt, th->th_scale * tc_delta(th), bt); 267 bintimeadd(bt, &th->th_boottime, bt); 268 membar_consumer(); 269 } while (gen == 0 || gen != th->th_generation); 270 } 271 272 void 273 nanotime(struct timespec *tsp) 274 { 275 struct bintime bt; 276 277 bintime(&bt); 278 BINTIME_TO_TIMESPEC(&bt, tsp); 279 } 280 281 void 282 microtime(struct timeval *tvp) 283 { 284 struct bintime bt; 285 286 bintime(&bt); 287 BINTIME_TO_TIMEVAL(&bt, tvp); 288 } 289 290 time_t 291 gettime(void) 292 { 293 #if defined(__LP64__) 294 return time_second; /* atomic */ 295 #else 296 time_t now; 297 struct timehands *th; 298 u_int gen; 299 300 do { 301 th = timehands; 302 gen = th->th_generation; 303 membar_consumer(); 304 now = th->th_microtime.tv_sec; 305 membar_consumer(); 306 } while (gen == 0 || gen != th->th_generation); 307 308 return now; 309 #endif 310 } 311 312 void 313 getnanouptime(struct timespec *tsp) 314 { 315 struct timehands *th; 316 u_int gen; 317 318 do { 319 th = timehands; 320 gen = th->th_generation; 321 membar_consumer(); 322 BINTIME_TO_TIMESPEC(&th->th_offset, tsp); 323 membar_consumer(); 324 } while (gen == 0 || gen != th->th_generation); 325 } 326 327 void 328 getmicrouptime(struct timeval *tvp) 329 { 330 struct timehands *th; 331 u_int gen; 332 333 do { 334 th = timehands; 335 gen = th->th_generation; 336 membar_consumer(); 337 BINTIME_TO_TIMEVAL(&th->th_offset, tvp); 338 membar_consumer(); 339 } while (gen == 0 || gen != th->th_generation); 340 } 341 342 void 343 getnanotime(struct timespec *tsp) 344 { 345 struct timehands *th; 346 u_int gen; 347 348 do { 349 th = timehands; 350 gen = th->th_generation; 351 membar_consumer(); 352 *tsp = th->th_nanotime; 353 membar_consumer(); 354 } while (gen == 0 || gen != th->th_generation); 355 } 356 357 void 358 getmicrotime(struct timeval *tvp) 359 { 360 struct timehands *th; 361 u_int gen; 362 363 do { 364 th = timehands; 365 gen = th->th_generation; 366 membar_consumer(); 367 *tvp = th->th_microtime; 368 membar_consumer(); 369 } while (gen == 0 || gen != th->th_generation); 370 } 371 372 /* 373 * Initialize a new timecounter and possibly use it. 374 */ 375 void 376 tc_init(struct timecounter *tc) 377 { 378 u_int64_t tmp; 379 u_int u; 380 381 u = tc->tc_frequency / tc->tc_counter_mask; 382 /* XXX: We need some margin here, 10% is a guess */ 383 u *= 11; 384 u /= 10; 385 if (tc->tc_quality >= 0) { 386 if (u > hz) { 387 tc->tc_quality = -2000; 388 printf("Timecounter \"%s\" frequency %lu Hz", 389 tc->tc_name, (unsigned long)tc->tc_frequency); 390 printf(" -- Insufficient hz, needs at least %u\n", u); 391 } 392 } 393 394 /* Determine the counter's precision. */ 395 for (tmp = 1; (tmp & tc->tc_counter_mask) == 0; tmp <<= 1) 396 continue; 397 tc->tc_precision = tmp; 398 399 SLIST_INSERT_HEAD(&tc_list, tc, tc_next); 400 401 /* 402 * Never automatically use a timecounter with negative quality. 403 * Even though we run on the dummy counter, switching here may be 404 * worse since this timecounter may not be monotonic. 405 */ 406 if (tc->tc_quality < 0) 407 return; 408 if (tc->tc_quality < timecounter->tc_quality) 409 return; 410 if (tc->tc_quality == timecounter->tc_quality && 411 tc->tc_frequency < timecounter->tc_frequency) 412 return; 413 (void)tc->tc_get_timecount(tc); 414 enqueue_randomness(tc->tc_get_timecount(tc)); 415 416 timecounter = tc; 417 } 418 419 /* Report the frequency of the current timecounter. */ 420 u_int64_t 421 tc_getfrequency(void) 422 { 423 return (timehands->th_counter->tc_frequency); 424 } 425 426 /* Report the precision of the current timecounter. */ 427 u_int64_t 428 tc_getprecision(void) 429 { 430 return (timehands->th_counter->tc_precision); 431 } 432 433 /* 434 * Step our concept of UTC, aka the realtime clock. 435 * This is done by modifying our estimate of when we booted. 436 * 437 * Any ongoing adjustment is meaningless after a clock jump, 438 * so we zero adjtimedelta here as well. 439 */ 440 void 441 tc_setrealtimeclock(const struct timespec *ts) 442 { 443 struct bintime boottime, old_utc, uptime, utc; 444 struct timespec tmp; 445 int64_t zero = 0; 446 447 TIMESPEC_TO_BINTIME(ts, &utc); 448 449 rw_enter_write(&tc_lock); 450 mtx_enter(&windup_mtx); 451 452 binuptime(&uptime); 453 bintimesub(&utc, &uptime, &boottime); 454 bintimeadd(&timehands->th_boottime, &uptime, &old_utc); 455 /* XXX fiddle all the little crinkly bits around the fiords... */ 456 tc_windup(&boottime, NULL, &zero); 457 458 mtx_leave(&windup_mtx); 459 rw_exit_write(&tc_lock); 460 461 enqueue_randomness(ts->tv_sec); 462 463 if (timestepwarnings) { 464 BINTIME_TO_TIMESPEC(&old_utc, &tmp); 465 log(LOG_INFO, "Time stepped from %lld.%09ld to %lld.%09ld\n", 466 (long long)tmp.tv_sec, tmp.tv_nsec, 467 (long long)ts->tv_sec, ts->tv_nsec); 468 } 469 } 470 471 /* 472 * Step the monotonic and realtime clocks, triggering any timeouts that 473 * should have occurred across the interval. 474 */ 475 void 476 tc_setclock(const struct timespec *ts) 477 { 478 struct bintime naptime, old_naptime, uptime, utc; 479 struct timespec tmp; 480 static int first = 1; 481 #ifndef SMALL_KERNEL 482 struct bintime elapsed; 483 long long adj_ticks; 484 #endif 485 486 /* 487 * When we're called for the first time, during boot when 488 * the root partition is mounted, we need to set boottime. 489 */ 490 if (first) { 491 tc_setrealtimeclock(ts); 492 first = 0; 493 return; 494 } 495 496 enqueue_randomness(ts->tv_sec); 497 498 TIMESPEC_TO_BINTIME(ts, &utc); 499 500 mtx_enter(&windup_mtx); 501 502 bintimesub(&utc, &timehands->th_boottime, &uptime); 503 old_naptime = timehands->th_naptime; 504 /* XXX fiddle all the little crinkly bits around the fiords... */ 505 tc_windup(NULL, &uptime, NULL); 506 naptime = timehands->th_naptime; 507 508 mtx_leave(&windup_mtx); 509 510 if (bintimecmp(&old_naptime, &naptime, ==)) { 511 BINTIME_TO_TIMESPEC(&uptime, &tmp); 512 printf("%s: cannot rewind uptime to %lld.%09ld\n", 513 __func__, (long long)tmp.tv_sec, tmp.tv_nsec); 514 } 515 516 #ifndef SMALL_KERNEL 517 /* convert the bintime to ticks */ 518 bintimesub(&naptime, &old_naptime, &elapsed); 519 adj_ticks = (uint64_t)hz * elapsed.sec + 520 (((uint64_t)1000000 * (uint32_t)(elapsed.frac >> 32)) >> 32) / tick; 521 if (adj_ticks > 0) { 522 if (adj_ticks > INT_MAX) 523 adj_ticks = INT_MAX; 524 timeout_adjust_ticks(adj_ticks); 525 } 526 #endif 527 } 528 529 void 530 tc_update_timekeep(void) 531 { 532 static struct timecounter *last_tc = NULL; 533 struct timehands *th; 534 535 MUTEX_ASSERT_LOCKED(&windup_mtx); 536 537 if (timekeep == NULL) 538 return; 539 540 th = timehands; 541 timekeep->tk_generation = 0; 542 membar_producer(); 543 timekeep->tk_scale = th->th_scale; 544 timekeep->tk_offset_count = th->th_offset_count; 545 timekeep->tk_offset = th->th_offset; 546 timekeep->tk_naptime = th->th_naptime; 547 timekeep->tk_boottime = th->th_boottime; 548 if (last_tc != th->th_counter) { 549 timekeep->tk_counter_mask = th->th_counter->tc_counter_mask; 550 timekeep->tk_user = th->th_counter->tc_user; 551 last_tc = th->th_counter; 552 } 553 membar_producer(); 554 timekeep->tk_generation = th->th_generation; 555 556 return; 557 } 558 559 /* 560 * Initialize the next struct timehands in the ring and make 561 * it the active timehands. Along the way we might switch to a different 562 * timecounter and/or do seconds processing in NTP. Slightly magic. 563 */ 564 void 565 tc_windup(struct bintime *new_boottime, struct bintime *new_offset, 566 int64_t *new_adjtimedelta) 567 { 568 struct bintime bt; 569 struct timecounter *active_tc; 570 struct timehands *th, *tho; 571 u_int64_t scale; 572 u_int delta, ncount, ogen; 573 574 if (new_boottime != NULL || new_adjtimedelta != NULL) 575 rw_assert_wrlock(&tc_lock); 576 MUTEX_ASSERT_LOCKED(&windup_mtx); 577 578 active_tc = timecounter; 579 580 /* 581 * Make the next timehands a copy of the current one, but do not 582 * overwrite the generation or next pointer. While we update 583 * the contents, the generation must be zero. 584 */ 585 tho = timehands; 586 ogen = tho->th_generation; 587 th = tho->th_next; 588 th->th_generation = 0; 589 membar_producer(); 590 memcpy(th, tho, offsetof(struct timehands, th_generation)); 591 592 /* 593 * Capture a timecounter delta on the current timecounter and if 594 * changing timecounters, a counter value from the new timecounter. 595 * Update the offset fields accordingly. 596 */ 597 delta = tc_delta(th); 598 if (th->th_counter != active_tc) 599 ncount = active_tc->tc_get_timecount(active_tc); 600 else 601 ncount = 0; 602 th->th_offset_count += delta; 603 th->th_offset_count &= th->th_counter->tc_counter_mask; 604 bintimeaddfrac(&th->th_offset, th->th_scale * delta, &th->th_offset); 605 606 /* 607 * Ignore new offsets that predate the current offset. 608 * If changing the offset, first increase the naptime 609 * accordingly. 610 */ 611 if (new_offset != NULL && bintimecmp(&th->th_offset, new_offset, <)) { 612 bintimesub(new_offset, &th->th_offset, &bt); 613 bintimeadd(&th->th_naptime, &bt, &th->th_naptime); 614 th->th_offset = *new_offset; 615 } 616 617 #ifdef notyet 618 /* 619 * Hardware latching timecounters may not generate interrupts on 620 * PPS events, so instead we poll them. There is a finite risk that 621 * the hardware might capture a count which is later than the one we 622 * got above, and therefore possibly in the next NTP second which might 623 * have a different rate than the current NTP second. It doesn't 624 * matter in practice. 625 */ 626 if (tho->th_counter->tc_poll_pps) 627 tho->th_counter->tc_poll_pps(tho->th_counter); 628 #endif 629 630 /* 631 * If changing the boot time or clock adjustment, do so before 632 * NTP processing. 633 */ 634 if (new_boottime != NULL) 635 th->th_boottime = *new_boottime; 636 if (new_adjtimedelta != NULL) { 637 th->th_adjtimedelta = *new_adjtimedelta; 638 /* Reset the NTP update period. */ 639 bintimesub(&th->th_offset, &th->th_naptime, 640 &th->th_next_ntp_update); 641 } 642 643 /* 644 * Deal with NTP second processing. The while-loop normally 645 * iterates at most once, but in extreme situations it might 646 * keep NTP sane if tc_windup() is not run for several seconds. 647 */ 648 bintimesub(&th->th_offset, &th->th_naptime, &bt); 649 while (bintimecmp(&th->th_next_ntp_update, &bt, <=)) { 650 ntp_update_second(th); 651 th->th_next_ntp_update.sec++; 652 } 653 654 /* Update the UTC timestamps used by the get*() functions. */ 655 bintimeadd(&th->th_boottime, &th->th_offset, &bt); 656 BINTIME_TO_TIMEVAL(&bt, &th->th_microtime); 657 BINTIME_TO_TIMESPEC(&bt, &th->th_nanotime); 658 659 /* Now is a good time to change timecounters. */ 660 if (th->th_counter != active_tc) { 661 th->th_counter = active_tc; 662 th->th_offset_count = ncount; 663 } 664 665 /*- 666 * Recalculate the scaling factor. We want the number of 1/2^64 667 * fractions of a second per period of the hardware counter, taking 668 * into account the th_adjustment factor which the NTP PLL/adjtime(2) 669 * processing provides us with. 670 * 671 * The th_adjustment is nanoseconds per second with 32 bit binary 672 * fraction and we want 64 bit binary fraction of second: 673 * 674 * x = a * 2^32 / 10^9 = a * 4.294967296 675 * 676 * The range of th_adjustment is +/- 5000PPM so inside a 64bit int 677 * we can only multiply by about 850 without overflowing, but that 678 * leaves suitably precise fractions for multiply before divide. 679 * 680 * Divide before multiply with a fraction of 2199/512 results in a 681 * systematic undercompensation of 10PPM of th_adjustment. On a 682 * 5000PPM adjustment this is a 0.05PPM error. This is acceptable. 683 * 684 * We happily sacrifice the lowest of the 64 bits of our result 685 * to the goddess of code clarity. 686 * 687 */ 688 scale = (u_int64_t)1 << 63; 689 scale += \ 690 ((th->th_adjustment + th->th_counter->tc_freq_adj) / 1024) * 2199; 691 scale /= th->th_counter->tc_frequency; 692 th->th_scale = scale * 2; 693 694 /* 695 * Now that the struct timehands is again consistent, set the new 696 * generation number, making sure to not make it zero. 697 */ 698 if (++ogen == 0) 699 ogen = 1; 700 membar_producer(); 701 th->th_generation = ogen; 702 703 /* Go live with the new struct timehands. */ 704 time_second = th->th_microtime.tv_sec; 705 time_uptime = th->th_offset.sec; 706 membar_producer(); 707 timehands = th; 708 709 tc_update_timekeep(); 710 } 711 712 /* Report or change the active timecounter hardware. */ 713 int 714 sysctl_tc_hardware(void *oldp, size_t *oldlenp, void *newp, size_t newlen) 715 { 716 char newname[32]; 717 struct timecounter *newtc, *tc; 718 int error; 719 720 tc = timecounter; 721 strlcpy(newname, tc->tc_name, sizeof(newname)); 722 723 error = sysctl_string(oldp, oldlenp, newp, newlen, newname, sizeof(newname)); 724 if (error != 0 || strcmp(newname, tc->tc_name) == 0) 725 return (error); 726 SLIST_FOREACH(newtc, &tc_list, tc_next) { 727 if (strcmp(newname, newtc->tc_name) != 0) 728 continue; 729 730 /* Warm up new timecounter. */ 731 (void)newtc->tc_get_timecount(newtc); 732 (void)newtc->tc_get_timecount(newtc); 733 734 rw_enter_write(&tc_lock); 735 timecounter = newtc; 736 rw_exit_write(&tc_lock); 737 738 return (0); 739 } 740 return (EINVAL); 741 } 742 743 /* Report or change the active timecounter hardware. */ 744 int 745 sysctl_tc_choice(void *oldp, size_t *oldlenp, void *newp, size_t newlen) 746 { 747 char buf[32], *spc, *choices; 748 struct timecounter *tc; 749 int error, maxlen; 750 751 if (SLIST_EMPTY(&tc_list)) 752 return (sysctl_rdstring(oldp, oldlenp, newp, "")); 753 754 spc = ""; 755 maxlen = 0; 756 SLIST_FOREACH(tc, &tc_list, tc_next) 757 maxlen += sizeof(buf); 758 choices = malloc(maxlen, M_TEMP, M_WAITOK); 759 *choices = '\0'; 760 SLIST_FOREACH(tc, &tc_list, tc_next) { 761 snprintf(buf, sizeof(buf), "%s%s(%d)", 762 spc, tc->tc_name, tc->tc_quality); 763 spc = " "; 764 strlcat(choices, buf, maxlen); 765 } 766 error = sysctl_rdstring(oldp, oldlenp, newp, choices); 767 free(choices, M_TEMP, maxlen); 768 return (error); 769 } 770 771 /* 772 * Timecounters need to be updated every so often to prevent the hardware 773 * counter from overflowing. Updating also recalculates the cached values 774 * used by the get*() family of functions, so their precision depends on 775 * the update frequency. 776 */ 777 static int tc_tick; 778 779 void 780 tc_ticktock(void) 781 { 782 static int count; 783 784 if (++count < tc_tick) 785 return; 786 if (!mtx_enter_try(&windup_mtx)) 787 return; 788 count = 0; 789 tc_windup(NULL, NULL, NULL); 790 mtx_leave(&windup_mtx); 791 } 792 793 void 794 inittimecounter(void) 795 { 796 #ifdef DEBUG 797 u_int p; 798 #endif 799 800 /* 801 * Set the initial timeout to 802 * max(1, <approx. number of hardclock ticks in a millisecond>). 803 * People should probably not use the sysctl to set the timeout 804 * to smaller than its initial value, since that value is the 805 * smallest reasonable one. If they want better timestamps they 806 * should use the non-"get"* functions. 807 */ 808 if (hz > 1000) 809 tc_tick = (hz + 500) / 1000; 810 else 811 tc_tick = 1; 812 #ifdef DEBUG 813 p = (tc_tick * 1000000) / hz; 814 printf("Timecounters tick every %d.%03u msec\n", p / 1000, p % 1000); 815 #endif 816 817 /* warm up new timecounter (again) and get rolling. */ 818 (void)timecounter->tc_get_timecount(timecounter); 819 (void)timecounter->tc_get_timecount(timecounter); 820 } 821 822 /* 823 * Return timecounter-related information. 824 */ 825 int 826 sysctl_tc(int *name, u_int namelen, void *oldp, size_t *oldlenp, 827 void *newp, size_t newlen) 828 { 829 if (namelen != 1) 830 return (ENOTDIR); 831 832 switch (name[0]) { 833 case KERN_TIMECOUNTER_TICK: 834 return (sysctl_rdint(oldp, oldlenp, newp, tc_tick)); 835 case KERN_TIMECOUNTER_TIMESTEPWARNINGS: 836 return (sysctl_int(oldp, oldlenp, newp, newlen, 837 ×tepwarnings)); 838 case KERN_TIMECOUNTER_HARDWARE: 839 return (sysctl_tc_hardware(oldp, oldlenp, newp, newlen)); 840 case KERN_TIMECOUNTER_CHOICE: 841 return (sysctl_tc_choice(oldp, oldlenp, newp, newlen)); 842 default: 843 return (EOPNOTSUPP); 844 } 845 /* NOTREACHED */ 846 } 847 848 /* 849 * Skew the timehands according to any adjtime(2) adjustment. 850 */ 851 void 852 ntp_update_second(struct timehands *th) 853 { 854 int64_t adj; 855 856 MUTEX_ASSERT_LOCKED(&windup_mtx); 857 858 if (th->th_adjtimedelta > 0) 859 adj = MIN(5000, th->th_adjtimedelta); 860 else 861 adj = MAX(-5000, th->th_adjtimedelta); 862 th->th_adjtimedelta -= adj; 863 th->th_adjustment = (adj * 1000) << 32; 864 } 865 866 void 867 tc_adjfreq(int64_t *old, int64_t *new) 868 { 869 if (old != NULL) { 870 rw_assert_anylock(&tc_lock); 871 *old = timecounter->tc_freq_adj; 872 } 873 if (new != NULL) { 874 rw_assert_wrlock(&tc_lock); 875 mtx_enter(&windup_mtx); 876 timecounter->tc_freq_adj = *new; 877 tc_windup(NULL, NULL, NULL); 878 mtx_leave(&windup_mtx); 879 } 880 } 881 882 void 883 tc_adjtime(int64_t *old, int64_t *new) 884 { 885 struct timehands *th; 886 u_int gen; 887 888 if (old != NULL) { 889 do { 890 th = timehands; 891 gen = th->th_generation; 892 membar_consumer(); 893 *old = th->th_adjtimedelta; 894 membar_consumer(); 895 } while (gen == 0 || gen != th->th_generation); 896 } 897 if (new != NULL) { 898 rw_assert_wrlock(&tc_lock); 899 mtx_enter(&windup_mtx); 900 tc_windup(NULL, NULL, new); 901 mtx_leave(&windup_mtx); 902 } 903 } 904