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