1 /*- 2 * Copyright (c) 2010 Alexander Motin <mav@FreeBSD.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer, 10 * without modification, immediately at the beginning of the file. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27 #include <sys/cdefs.h> 28 __FBSDID("$FreeBSD$"); 29 30 /* 31 * Common routines to manage event timers hardware. 32 */ 33 34 /* XEN has own timer routines now. */ 35 #ifndef XEN 36 37 #include "opt_device_polling.h" 38 #include "opt_kdtrace.h" 39 40 #include <sys/param.h> 41 #include <sys/systm.h> 42 #include <sys/bus.h> 43 #include <sys/lock.h> 44 #include <sys/kdb.h> 45 #include <sys/ktr.h> 46 #include <sys/mutex.h> 47 #include <sys/proc.h> 48 #include <sys/kernel.h> 49 #include <sys/sched.h> 50 #include <sys/smp.h> 51 #include <sys/sysctl.h> 52 #include <sys/timeet.h> 53 #include <sys/timetc.h> 54 55 #include <machine/atomic.h> 56 #include <machine/clock.h> 57 #include <machine/cpu.h> 58 #include <machine/smp.h> 59 60 #ifdef KDTRACE_HOOKS 61 #include <sys/dtrace_bsd.h> 62 cyclic_clock_func_t cyclic_clock_func[MAXCPU]; 63 #endif 64 65 int cpu_disable_deep_sleep = 0; /* Timer dies in C3. */ 66 67 static void setuptimer(void); 68 static void loadtimer(struct bintime *now, int first); 69 static int doconfigtimer(void); 70 static void configtimer(int start); 71 static int round_freq(struct eventtimer *et, int freq); 72 73 static void getnextcpuevent(struct bintime *event, int idle); 74 static void getnextevent(struct bintime *event); 75 static int handleevents(struct bintime *now, int fake); 76 #ifdef SMP 77 static void cpu_new_callout(int cpu, int ticks); 78 #endif 79 80 static struct mtx et_hw_mtx; 81 82 #define ET_HW_LOCK(state) \ 83 { \ 84 if (timer->et_flags & ET_FLAGS_PERCPU) \ 85 mtx_lock_spin(&(state)->et_hw_mtx); \ 86 else \ 87 mtx_lock_spin(&et_hw_mtx); \ 88 } 89 90 #define ET_HW_UNLOCK(state) \ 91 { \ 92 if (timer->et_flags & ET_FLAGS_PERCPU) \ 93 mtx_unlock_spin(&(state)->et_hw_mtx); \ 94 else \ 95 mtx_unlock_spin(&et_hw_mtx); \ 96 } 97 98 static struct eventtimer *timer = NULL; 99 static struct bintime timerperiod; /* Timer period for periodic mode. */ 100 static struct bintime hardperiod; /* hardclock() events period. */ 101 static struct bintime statperiod; /* statclock() events period. */ 102 static struct bintime profperiod; /* profclock() events period. */ 103 static struct bintime nexttick; /* Next global timer tick time. */ 104 static u_int busy = 0; /* Reconfiguration is in progress. */ 105 static int profiling = 0; /* Profiling events enabled. */ 106 107 static char timername[32]; /* Wanted timer. */ 108 TUNABLE_STR("kern.eventtimer.timer", timername, sizeof(timername)); 109 110 static int singlemul = 0; /* Multiplier for periodic mode. */ 111 TUNABLE_INT("kern.eventtimer.singlemul", &singlemul); 112 SYSCTL_INT(_kern_eventtimer, OID_AUTO, singlemul, CTLFLAG_RW, &singlemul, 113 0, "Multiplier for periodic mode"); 114 115 static u_int idletick = 0; /* Idle mode allowed. */ 116 TUNABLE_INT("kern.eventtimer.idletick", &idletick); 117 SYSCTL_INT(_kern_eventtimer, OID_AUTO, idletick, CTLFLAG_RW, &idletick, 118 0, "Run periodic events when idle"); 119 120 static int periodic = 0; /* Periodic or one-shot mode. */ 121 static int want_periodic = 0; /* What mode to prefer. */ 122 TUNABLE_INT("kern.eventtimer.periodic", &want_periodic); 123 124 struct pcpu_state { 125 struct mtx et_hw_mtx; /* Per-CPU timer mutex. */ 126 u_int action; /* Reconfiguration requests. */ 127 u_int handle; /* Immediate handle resuests. */ 128 struct bintime now; /* Last tick time. */ 129 struct bintime nextevent; /* Next scheduled event on this CPU. */ 130 struct bintime nexttick; /* Next timer tick time. */ 131 struct bintime nexthard; /* Next hardlock() event. */ 132 struct bintime nextstat; /* Next statclock() event. */ 133 struct bintime nextprof; /* Next profclock() event. */ 134 int ipi; /* This CPU needs IPI. */ 135 int idle; /* This CPU is in idle mode. */ 136 }; 137 138 static DPCPU_DEFINE(struct pcpu_state, timerstate); 139 140 #define FREQ2BT(freq, bt) \ 141 { \ 142 (bt)->sec = 0; \ 143 (bt)->frac = ((uint64_t)0x8000000000000000 / (freq)) << 1; \ 144 } 145 #define BT2FREQ(bt) \ 146 (((uint64_t)0x8000000000000000 + ((bt)->frac >> 2)) / \ 147 ((bt)->frac >> 1)) 148 149 /* 150 * Timer broadcast IPI handler. 151 */ 152 int 153 hardclockintr(void) 154 { 155 struct bintime now; 156 struct pcpu_state *state; 157 int done; 158 159 if (doconfigtimer() || busy) 160 return (FILTER_HANDLED); 161 state = DPCPU_PTR(timerstate); 162 now = state->now; 163 CTR4(KTR_SPARE2, "ipi at %d: now %d.%08x%08x", 164 curcpu, now.sec, (unsigned int)(now.frac >> 32), 165 (unsigned int)(now.frac & 0xffffffff)); 166 done = handleevents(&now, 0); 167 return (done ? FILTER_HANDLED : FILTER_STRAY); 168 } 169 170 /* 171 * Handle all events for specified time on this CPU 172 */ 173 static int 174 handleevents(struct bintime *now, int fake) 175 { 176 struct bintime t; 177 struct trapframe *frame; 178 struct pcpu_state *state; 179 uintfptr_t pc; 180 int usermode; 181 int done, runs; 182 183 CTR4(KTR_SPARE2, "handle at %d: now %d.%08x%08x", 184 curcpu, now->sec, (unsigned int)(now->frac >> 32), 185 (unsigned int)(now->frac & 0xffffffff)); 186 done = 0; 187 if (fake) { 188 frame = NULL; 189 usermode = 0; 190 pc = 0; 191 } else { 192 frame = curthread->td_intr_frame; 193 usermode = TRAPF_USERMODE(frame); 194 pc = TRAPF_PC(frame); 195 } 196 #ifdef KDTRACE_HOOKS 197 /* 198 * If the DTrace hooks are configured and a callback function 199 * has been registered, then call it to process the high speed 200 * timers. 201 */ 202 if (!fake && cyclic_clock_func[curcpu] != NULL) 203 (*cyclic_clock_func[curcpu])(frame); 204 #endif 205 runs = 0; 206 state = DPCPU_PTR(timerstate); 207 while (bintime_cmp(now, &state->nexthard, >=)) { 208 bintime_add(&state->nexthard, &hardperiod); 209 runs++; 210 } 211 if (runs && fake < 2) { 212 hardclock_anycpu(runs, usermode); 213 done = 1; 214 } 215 while (bintime_cmp(now, &state->nextstat, >=)) { 216 if (fake < 2) 217 statclock(usermode); 218 bintime_add(&state->nextstat, &statperiod); 219 done = 1; 220 } 221 if (profiling) { 222 while (bintime_cmp(now, &state->nextprof, >=)) { 223 if (!fake) 224 profclock(usermode, pc); 225 bintime_add(&state->nextprof, &profperiod); 226 done = 1; 227 } 228 } else 229 state->nextprof = state->nextstat; 230 getnextcpuevent(&t, 0); 231 if (fake == 2) { 232 state->nextevent = t; 233 return (done); 234 } 235 ET_HW_LOCK(state); 236 if (!busy) { 237 state->idle = 0; 238 state->nextevent = t; 239 loadtimer(now, 0); 240 } 241 ET_HW_UNLOCK(state); 242 return (done); 243 } 244 245 /* 246 * Schedule binuptime of the next event on current CPU. 247 */ 248 static void 249 getnextcpuevent(struct bintime *event, int idle) 250 { 251 struct bintime tmp; 252 struct pcpu_state *state; 253 int skip; 254 255 state = DPCPU_PTR(timerstate); 256 *event = state->nexthard; 257 if (idle) { /* If CPU is idle - ask callouts for how long. */ 258 skip = 4; 259 if (curcpu == CPU_FIRST() && tc_min_ticktock_freq > skip) 260 skip = tc_min_ticktock_freq; 261 skip = callout_tickstofirst(hz / skip) - 1; 262 CTR2(KTR_SPARE2, "skip at %d: %d", curcpu, skip); 263 tmp = hardperiod; 264 bintime_mul(&tmp, skip); 265 bintime_add(event, &tmp); 266 } else { /* If CPU is active - handle all types of events. */ 267 if (bintime_cmp(event, &state->nextstat, >)) 268 *event = state->nextstat; 269 if (profiling && 270 bintime_cmp(event, &state->nextprof, >)) 271 *event = state->nextprof; 272 } 273 } 274 275 /* 276 * Schedule binuptime of the next event on all CPUs. 277 */ 278 static void 279 getnextevent(struct bintime *event) 280 { 281 struct pcpu_state *state; 282 #ifdef SMP 283 int cpu; 284 #endif 285 int c; 286 287 state = DPCPU_PTR(timerstate); 288 *event = state->nextevent; 289 c = curcpu; 290 #ifdef SMP 291 if ((timer->et_flags & ET_FLAGS_PERCPU) == 0) { 292 CPU_FOREACH(cpu) { 293 if (curcpu == cpu) 294 continue; 295 state = DPCPU_ID_PTR(cpu, timerstate); 296 if (bintime_cmp(event, &state->nextevent, >)) { 297 *event = state->nextevent; 298 c = cpu; 299 } 300 } 301 } 302 #endif 303 CTR5(KTR_SPARE2, "next at %d: next %d.%08x%08x by %d", 304 curcpu, event->sec, (unsigned int)(event->frac >> 32), 305 (unsigned int)(event->frac & 0xffffffff), c); 306 } 307 308 /* Hardware timer callback function. */ 309 static void 310 timercb(struct eventtimer *et, void *arg) 311 { 312 struct bintime now; 313 struct bintime *next; 314 struct pcpu_state *state; 315 #ifdef SMP 316 int cpu, bcast; 317 #endif 318 319 /* Do not touch anything if somebody reconfiguring timers. */ 320 if (busy) 321 return; 322 /* Update present and next tick times. */ 323 state = DPCPU_PTR(timerstate); 324 if (et->et_flags & ET_FLAGS_PERCPU) { 325 next = &state->nexttick; 326 } else 327 next = &nexttick; 328 if (periodic) { 329 now = *next; /* Ex-next tick time becomes present time. */ 330 bintime_add(next, &timerperiod); /* Next tick in 1 period. */ 331 } else { 332 binuptime(&now); /* Get present time from hardware. */ 333 next->sec = -1; /* Next tick is not scheduled yet. */ 334 } 335 state->now = now; 336 CTR4(KTR_SPARE2, "intr at %d: now %d.%08x%08x", 337 curcpu, now.sec, (unsigned int)(now.frac >> 32), 338 (unsigned int)(now.frac & 0xffffffff)); 339 340 #ifdef SMP 341 /* Prepare broadcasting to other CPUs for non-per-CPU timers. */ 342 bcast = 0; 343 if ((et->et_flags & ET_FLAGS_PERCPU) == 0 && smp_started) { 344 CPU_FOREACH(cpu) { 345 state = DPCPU_ID_PTR(cpu, timerstate); 346 ET_HW_LOCK(state); 347 state->now = now; 348 if (bintime_cmp(&now, &state->nextevent, >=)) { 349 state->nextevent.sec++; 350 if (curcpu != cpu) { 351 state->ipi = 1; 352 bcast = 1; 353 } 354 } 355 ET_HW_UNLOCK(state); 356 } 357 } 358 #endif 359 360 /* Handle events for this time on this CPU. */ 361 handleevents(&now, 0); 362 363 #ifdef SMP 364 /* Broadcast interrupt to other CPUs for non-per-CPU timers. */ 365 if (bcast) { 366 CPU_FOREACH(cpu) { 367 if (curcpu == cpu) 368 continue; 369 state = DPCPU_ID_PTR(cpu, timerstate); 370 if (state->ipi) { 371 state->ipi = 0; 372 ipi_cpu(cpu, IPI_HARDCLOCK); 373 } 374 } 375 } 376 #endif 377 } 378 379 /* 380 * Load new value into hardware timer. 381 */ 382 static void 383 loadtimer(struct bintime *now, int start) 384 { 385 struct pcpu_state *state; 386 struct bintime new; 387 struct bintime *next; 388 uint64_t tmp; 389 int eq; 390 391 if (timer->et_flags & ET_FLAGS_PERCPU) { 392 state = DPCPU_PTR(timerstate); 393 next = &state->nexttick; 394 } else 395 next = &nexttick; 396 if (periodic) { 397 if (start) { 398 /* 399 * Try to start all periodic timers aligned 400 * to period to make events synchronous. 401 */ 402 tmp = ((uint64_t)now->sec << 36) + (now->frac >> 28); 403 tmp = (tmp % (timerperiod.frac >> 28)) << 28; 404 new.sec = 0; 405 new.frac = timerperiod.frac - tmp; 406 if (new.frac < tmp) /* Left less then passed. */ 407 bintime_add(&new, &timerperiod); 408 CTR5(KTR_SPARE2, "load p at %d: now %d.%08x first in %d.%08x", 409 curcpu, now->sec, (unsigned int)(now->frac >> 32), 410 new.sec, (unsigned int)(new.frac >> 32)); 411 *next = new; 412 bintime_add(next, now); 413 et_start(timer, &new, &timerperiod); 414 } 415 } else { 416 getnextevent(&new); 417 eq = bintime_cmp(&new, next, ==); 418 CTR5(KTR_SPARE2, "load at %d: next %d.%08x%08x eq %d", 419 curcpu, new.sec, (unsigned int)(new.frac >> 32), 420 (unsigned int)(new.frac & 0xffffffff), 421 eq); 422 if (!eq) { 423 *next = new; 424 bintime_sub(&new, now); 425 et_start(timer, &new, NULL); 426 } 427 } 428 } 429 430 /* 431 * Prepare event timer parameters after configuration changes. 432 */ 433 static void 434 setuptimer(void) 435 { 436 int freq; 437 438 if (periodic && (timer->et_flags & ET_FLAGS_PERIODIC) == 0) 439 periodic = 0; 440 else if (!periodic && (timer->et_flags & ET_FLAGS_ONESHOT) == 0) 441 periodic = 1; 442 singlemul = MIN(MAX(singlemul, 1), 20); 443 freq = hz * singlemul; 444 while (freq < (profiling ? profhz : stathz)) 445 freq += hz; 446 freq = round_freq(timer, freq); 447 FREQ2BT(freq, &timerperiod); 448 } 449 450 /* 451 * Reconfigure specified per-CPU timer on other CPU. Called from IPI handler. 452 */ 453 static int 454 doconfigtimer(void) 455 { 456 struct bintime now; 457 struct pcpu_state *state; 458 459 state = DPCPU_PTR(timerstate); 460 switch (atomic_load_acq_int(&state->action)) { 461 case 1: 462 binuptime(&now); 463 ET_HW_LOCK(state); 464 loadtimer(&now, 1); 465 ET_HW_UNLOCK(state); 466 state->handle = 0; 467 atomic_store_rel_int(&state->action, 0); 468 return (1); 469 case 2: 470 ET_HW_LOCK(state); 471 et_stop(timer); 472 ET_HW_UNLOCK(state); 473 state->handle = 0; 474 atomic_store_rel_int(&state->action, 0); 475 return (1); 476 } 477 if (atomic_readandclear_int(&state->handle) && !busy) { 478 binuptime(&now); 479 handleevents(&now, 0); 480 return (1); 481 } 482 return (0); 483 } 484 485 /* 486 * Reconfigure specified timer. 487 * For per-CPU timers use IPI to make other CPUs to reconfigure. 488 */ 489 static void 490 configtimer(int start) 491 { 492 struct bintime now, next; 493 struct pcpu_state *state; 494 int cpu; 495 496 if (start) { 497 setuptimer(); 498 binuptime(&now); 499 } 500 critical_enter(); 501 ET_HW_LOCK(DPCPU_PTR(timerstate)); 502 if (start) { 503 /* Initialize time machine parameters. */ 504 next = now; 505 bintime_add(&next, &timerperiod); 506 if (periodic) 507 nexttick = next; 508 else 509 nexttick.sec = -1; 510 CPU_FOREACH(cpu) { 511 state = DPCPU_ID_PTR(cpu, timerstate); 512 state->now = now; 513 state->nextevent = next; 514 if (periodic) 515 state->nexttick = next; 516 else 517 state->nexttick.sec = -1; 518 state->nexthard = next; 519 state->nextstat = next; 520 state->nextprof = next; 521 hardclock_sync(cpu); 522 } 523 busy = 0; 524 /* Start global timer or per-CPU timer of this CPU. */ 525 loadtimer(&now, 1); 526 } else { 527 busy = 1; 528 /* Stop global timer or per-CPU timer of this CPU. */ 529 et_stop(timer); 530 } 531 ET_HW_UNLOCK(DPCPU_PTR(timerstate)); 532 #ifdef SMP 533 /* If timer is global or there is no other CPUs yet - we are done. */ 534 if ((timer->et_flags & ET_FLAGS_PERCPU) == 0 || !smp_started) { 535 critical_exit(); 536 return; 537 } 538 /* Set reconfigure flags for other CPUs. */ 539 CPU_FOREACH(cpu) { 540 state = DPCPU_ID_PTR(cpu, timerstate); 541 atomic_store_rel_int(&state->action, 542 (cpu == curcpu) ? 0 : ( start ? 1 : 2)); 543 } 544 /* Broadcast reconfigure IPI. */ 545 ipi_all_but_self(IPI_HARDCLOCK); 546 /* Wait for reconfiguration completed. */ 547 restart: 548 cpu_spinwait(); 549 CPU_FOREACH(cpu) { 550 if (cpu == curcpu) 551 continue; 552 state = DPCPU_ID_PTR(cpu, timerstate); 553 if (atomic_load_acq_int(&state->action)) 554 goto restart; 555 } 556 #endif 557 critical_exit(); 558 } 559 560 /* 561 * Calculate nearest frequency supported by hardware timer. 562 */ 563 static int 564 round_freq(struct eventtimer *et, int freq) 565 { 566 uint64_t div; 567 568 if (et->et_frequency != 0) { 569 div = lmax((et->et_frequency + freq / 2) / freq, 1); 570 if (et->et_flags & ET_FLAGS_POW2DIV) 571 div = 1 << (flsl(div + div / 2) - 1); 572 freq = (et->et_frequency + div / 2) / div; 573 } 574 if (et->et_min_period.sec > 0) 575 freq = 0; 576 else if (et->et_min_period.frac != 0) 577 freq = min(freq, BT2FREQ(&et->et_min_period)); 578 if (et->et_max_period.sec == 0 && et->et_max_period.frac != 0) 579 freq = max(freq, BT2FREQ(&et->et_max_period)); 580 return (freq); 581 } 582 583 /* 584 * Configure and start event timers (BSP part). 585 */ 586 void 587 cpu_initclocks_bsp(void) 588 { 589 struct pcpu_state *state; 590 int base, div, cpu; 591 592 mtx_init(&et_hw_mtx, "et_hw_mtx", NULL, MTX_SPIN); 593 CPU_FOREACH(cpu) { 594 state = DPCPU_ID_PTR(cpu, timerstate); 595 mtx_init(&state->et_hw_mtx, "et_hw_mtx", NULL, MTX_SPIN); 596 } 597 #ifdef SMP 598 callout_new_inserted = cpu_new_callout; 599 #endif 600 periodic = want_periodic; 601 /* Grab requested timer or the best of present. */ 602 if (timername[0]) 603 timer = et_find(timername, 0, 0); 604 if (timer == NULL && periodic) { 605 timer = et_find(NULL, 606 ET_FLAGS_PERIODIC, ET_FLAGS_PERIODIC); 607 } 608 if (timer == NULL) { 609 timer = et_find(NULL, 610 ET_FLAGS_ONESHOT, ET_FLAGS_ONESHOT); 611 } 612 if (timer == NULL && !periodic) { 613 timer = et_find(NULL, 614 ET_FLAGS_PERIODIC, ET_FLAGS_PERIODIC); 615 } 616 if (timer == NULL) 617 panic("No usable event timer found!"); 618 et_init(timer, timercb, NULL, NULL); 619 620 /* Adapt to timer capabilities. */ 621 if (periodic && (timer->et_flags & ET_FLAGS_PERIODIC) == 0) 622 periodic = 0; 623 else if (!periodic && (timer->et_flags & ET_FLAGS_ONESHOT) == 0) 624 periodic = 1; 625 if (timer->et_flags & ET_FLAGS_C3STOP) 626 cpu_disable_deep_sleep++; 627 628 /* 629 * We honor the requested 'hz' value. 630 * We want to run stathz in the neighborhood of 128hz. 631 * We would like profhz to run as often as possible. 632 */ 633 if (singlemul <= 0 || singlemul > 20) { 634 if (hz >= 1500 || (hz % 128) == 0) 635 singlemul = 1; 636 else if (hz >= 750) 637 singlemul = 2; 638 else 639 singlemul = 4; 640 } 641 if (periodic) { 642 base = round_freq(timer, hz * singlemul); 643 singlemul = max((base + hz / 2) / hz, 1); 644 hz = (base + singlemul / 2) / singlemul; 645 if (base <= 128) 646 stathz = base; 647 else { 648 div = base / 128; 649 if (div >= singlemul && (div % singlemul) == 0) 650 div++; 651 stathz = base / div; 652 } 653 profhz = stathz; 654 while ((profhz + stathz) <= 128 * 64) 655 profhz += stathz; 656 profhz = round_freq(timer, profhz); 657 } else { 658 hz = round_freq(timer, hz); 659 stathz = round_freq(timer, 127); 660 profhz = round_freq(timer, stathz * 64); 661 } 662 tick = 1000000 / hz; 663 FREQ2BT(hz, &hardperiod); 664 FREQ2BT(stathz, &statperiod); 665 FREQ2BT(profhz, &profperiod); 666 ET_LOCK(); 667 configtimer(1); 668 ET_UNLOCK(); 669 } 670 671 /* 672 * Start per-CPU event timers on APs. 673 */ 674 void 675 cpu_initclocks_ap(void) 676 { 677 struct bintime now; 678 struct pcpu_state *state; 679 680 state = DPCPU_PTR(timerstate); 681 binuptime(&now); 682 ET_HW_LOCK(state); 683 if ((timer->et_flags & ET_FLAGS_PERCPU) == 0 && periodic) { 684 state->now = nexttick; 685 bintime_sub(&state->now, &timerperiod); 686 } else 687 state->now = now; 688 hardclock_sync(curcpu); 689 handleevents(&state->now, 2); 690 if (timer->et_flags & ET_FLAGS_PERCPU) 691 loadtimer(&now, 1); 692 ET_HW_UNLOCK(state); 693 } 694 695 /* 696 * Switch to profiling clock rates. 697 */ 698 void 699 cpu_startprofclock(void) 700 { 701 702 ET_LOCK(); 703 if (periodic) { 704 configtimer(0); 705 profiling = 1; 706 configtimer(1); 707 } else 708 profiling = 1; 709 ET_UNLOCK(); 710 } 711 712 /* 713 * Switch to regular clock rates. 714 */ 715 void 716 cpu_stopprofclock(void) 717 { 718 719 ET_LOCK(); 720 if (periodic) { 721 configtimer(0); 722 profiling = 0; 723 configtimer(1); 724 } else 725 profiling = 0; 726 ET_UNLOCK(); 727 } 728 729 /* 730 * Switch to idle mode (all ticks handled). 731 */ 732 void 733 cpu_idleclock(void) 734 { 735 struct bintime now, t; 736 struct pcpu_state *state; 737 738 if (idletick || busy || 739 (periodic && (timer->et_flags & ET_FLAGS_PERCPU)) 740 #ifdef DEVICE_POLLING 741 || curcpu == CPU_FIRST() 742 #endif 743 ) 744 return; 745 state = DPCPU_PTR(timerstate); 746 if (periodic) 747 now = state->now; 748 else 749 binuptime(&now); 750 CTR4(KTR_SPARE2, "idle at %d: now %d.%08x%08x", 751 curcpu, now.sec, (unsigned int)(now.frac >> 32), 752 (unsigned int)(now.frac & 0xffffffff)); 753 getnextcpuevent(&t, 1); 754 ET_HW_LOCK(state); 755 state->idle = 1; 756 state->nextevent = t; 757 if (!periodic) 758 loadtimer(&now, 0); 759 ET_HW_UNLOCK(state); 760 } 761 762 /* 763 * Switch to active mode (skip empty ticks). 764 */ 765 void 766 cpu_activeclock(void) 767 { 768 struct bintime now; 769 struct pcpu_state *state; 770 struct thread *td; 771 772 state = DPCPU_PTR(timerstate); 773 if (state->idle == 0 || busy) 774 return; 775 if (periodic) 776 now = state->now; 777 else 778 binuptime(&now); 779 CTR4(KTR_SPARE2, "active at %d: now %d.%08x%08x", 780 curcpu, now.sec, (unsigned int)(now.frac >> 32), 781 (unsigned int)(now.frac & 0xffffffff)); 782 spinlock_enter(); 783 td = curthread; 784 td->td_intr_nesting_level++; 785 handleevents(&now, 1); 786 td->td_intr_nesting_level--; 787 spinlock_exit(); 788 } 789 790 #ifdef SMP 791 static void 792 cpu_new_callout(int cpu, int ticks) 793 { 794 struct bintime tmp; 795 struct pcpu_state *state; 796 797 CTR3(KTR_SPARE2, "new co at %d: on %d in %d", 798 curcpu, cpu, ticks); 799 state = DPCPU_ID_PTR(cpu, timerstate); 800 ET_HW_LOCK(state); 801 if (state->idle == 0 || busy) { 802 ET_HW_UNLOCK(state); 803 return; 804 } 805 /* 806 * If timer is periodic - just update next event time for target CPU. 807 * If timer is global - there is chance it is already programmed. 808 */ 809 if (periodic || (timer->et_flags & ET_FLAGS_PERCPU) == 0) { 810 state->nextevent = state->nexthard; 811 tmp = hardperiod; 812 bintime_mul(&tmp, ticks - 1); 813 bintime_add(&state->nextevent, &tmp); 814 if (periodic || 815 bintime_cmp(&state->nextevent, &nexttick, >=)) { 816 ET_HW_UNLOCK(state); 817 return; 818 } 819 } 820 /* 821 * Otherwise we have to wake that CPU up, as we can't get present 822 * bintime to reprogram global timer from here. If timer is per-CPU, 823 * we by definition can't do it from here. 824 */ 825 ET_HW_UNLOCK(state); 826 if (timer->et_flags & ET_FLAGS_PERCPU) { 827 state->handle = 1; 828 ipi_cpu(cpu, IPI_HARDCLOCK); 829 } else { 830 if (!cpu_idle_wakeup(cpu)) 831 ipi_cpu(cpu, IPI_AST); 832 } 833 } 834 #endif 835 836 /* 837 * Report or change the active event timers hardware. 838 */ 839 static int 840 sysctl_kern_eventtimer_timer(SYSCTL_HANDLER_ARGS) 841 { 842 char buf[32]; 843 struct eventtimer *et; 844 int error; 845 846 ET_LOCK(); 847 et = timer; 848 snprintf(buf, sizeof(buf), "%s", et->et_name); 849 ET_UNLOCK(); 850 error = sysctl_handle_string(oidp, buf, sizeof(buf), req); 851 ET_LOCK(); 852 et = timer; 853 if (error != 0 || req->newptr == NULL || 854 strcasecmp(buf, et->et_name) == 0) { 855 ET_UNLOCK(); 856 return (error); 857 } 858 et = et_find(buf, 0, 0); 859 if (et == NULL) { 860 ET_UNLOCK(); 861 return (ENOENT); 862 } 863 configtimer(0); 864 et_free(timer); 865 if (et->et_flags & ET_FLAGS_C3STOP) 866 cpu_disable_deep_sleep++; 867 if (timer->et_flags & ET_FLAGS_C3STOP) 868 cpu_disable_deep_sleep--; 869 periodic = want_periodic; 870 timer = et; 871 et_init(timer, timercb, NULL, NULL); 872 configtimer(1); 873 ET_UNLOCK(); 874 return (error); 875 } 876 SYSCTL_PROC(_kern_eventtimer, OID_AUTO, timer, 877 CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_MPSAFE, 878 0, 0, sysctl_kern_eventtimer_timer, "A", "Chosen event timer"); 879 880 /* 881 * Report or change the active event timer periodicity. 882 */ 883 static int 884 sysctl_kern_eventtimer_periodic(SYSCTL_HANDLER_ARGS) 885 { 886 int error, val; 887 888 val = periodic; 889 error = sysctl_handle_int(oidp, &val, 0, req); 890 if (error != 0 || req->newptr == NULL) 891 return (error); 892 ET_LOCK(); 893 configtimer(0); 894 periodic = want_periodic = val; 895 configtimer(1); 896 ET_UNLOCK(); 897 return (error); 898 } 899 SYSCTL_PROC(_kern_eventtimer, OID_AUTO, periodic, 900 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE, 901 0, 0, sysctl_kern_eventtimer_periodic, "I", "Enable event timer periodic mode"); 902 903 #endif 904