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