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