1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 1997, Stefan Esser <se@freebsd.org> 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice unmodified, this list of conditions, and the following 12 * disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 #include <sys/cdefs.h> 30 #include "opt_ddb.h" 31 #include "opt_hwpmc_hooks.h" 32 #include "opt_kstack_usage_prof.h" 33 34 #include <sys/param.h> 35 #include <sys/bus.h> 36 #include <sys/conf.h> 37 #include <sys/cpuset.h> 38 #include <sys/rtprio.h> 39 #include <sys/systm.h> 40 #include <sys/interrupt.h> 41 #include <sys/kernel.h> 42 #include <sys/kthread.h> 43 #include <sys/ktr.h> 44 #include <sys/limits.h> 45 #include <sys/lock.h> 46 #include <sys/malloc.h> 47 #include <sys/mutex.h> 48 #include <sys/priv.h> 49 #include <sys/proc.h> 50 #include <sys/epoch.h> 51 #include <sys/random.h> 52 #include <sys/resourcevar.h> 53 #include <sys/sched.h> 54 #include <sys/smp.h> 55 #include <sys/sysctl.h> 56 #include <sys/syslog.h> 57 #include <sys/unistd.h> 58 #include <sys/vmmeter.h> 59 #include <machine/atomic.h> 60 #include <machine/cpu.h> 61 #include <machine/md_var.h> 62 #include <machine/smp.h> 63 #include <machine/stdarg.h> 64 #ifdef DDB 65 #include <ddb/ddb.h> 66 #include <ddb/db_sym.h> 67 #endif 68 69 /* 70 * Describe an interrupt thread. There is one of these per interrupt event. 71 */ 72 struct intr_thread { 73 struct intr_event *it_event; 74 struct thread *it_thread; /* Kernel thread. */ 75 int it_flags; /* (j) IT_* flags. */ 76 int it_need; /* Needs service. */ 77 int it_waiting; /* Waiting in the runq. */ 78 }; 79 80 /* Interrupt thread flags kept in it_flags */ 81 #define IT_DEAD 0x000001 /* Thread is waiting to exit. */ 82 #define IT_WAIT 0x000002 /* Thread is waiting for completion. */ 83 84 struct intr_entropy { 85 struct thread *td; 86 uintptr_t event; 87 }; 88 89 struct intr_event *clk_intr_event; 90 struct proc *intrproc; 91 92 static MALLOC_DEFINE(M_ITHREAD, "ithread", "Interrupt Threads"); 93 94 static int intr_storm_threshold = 0; 95 SYSCTL_INT(_hw, OID_AUTO, intr_storm_threshold, CTLFLAG_RWTUN, 96 &intr_storm_threshold, 0, 97 "Number of consecutive interrupts before storm protection is enabled"); 98 static int intr_epoch_batch = 1000; 99 SYSCTL_INT(_hw, OID_AUTO, intr_epoch_batch, CTLFLAG_RWTUN, &intr_epoch_batch, 100 0, "Maximum interrupt handler executions without re-entering epoch(9)"); 101 #ifdef HWPMC_HOOKS 102 static int intr_hwpmc_waiting_report_threshold = 1; 103 SYSCTL_INT(_hw, OID_AUTO, intr_hwpmc_waiting_report_threshold, CTLFLAG_RWTUN, 104 &intr_hwpmc_waiting_report_threshold, 1, 105 "Threshold for reporting number of events in a workq"); 106 #define PMC_HOOK_INSTALLED_ANY() __predict_false(pmc_hook != NULL) 107 #endif 108 static TAILQ_HEAD(, intr_event) event_list = 109 TAILQ_HEAD_INITIALIZER(event_list); 110 static struct mtx event_lock; 111 MTX_SYSINIT(intr_event_list, &event_lock, "intr event list", MTX_DEF); 112 113 static void intr_event_update(struct intr_event *ie); 114 static int intr_event_schedule_thread(struct intr_event *ie, struct trapframe *frame); 115 static struct intr_thread *ithread_create(const char *name); 116 static void ithread_destroy(struct intr_thread *ithread); 117 static void ithread_execute_handlers(struct proc *p, 118 struct intr_event *ie); 119 static void ithread_loop(void *); 120 static void ithread_update(struct intr_thread *ithd); 121 static void start_softintr(void *); 122 123 #ifdef HWPMC_HOOKS 124 #include <sys/pmckern.h> 125 PMC_SOFT_DEFINE( , , intr, all); 126 PMC_SOFT_DEFINE( , , intr, ithread); 127 PMC_SOFT_DEFINE( , , intr, filter); 128 PMC_SOFT_DEFINE( , , intr, stray); 129 PMC_SOFT_DEFINE( , , intr, schedule); 130 PMC_SOFT_DEFINE( , , intr, waiting); 131 132 #define PMC_SOFT_CALL_INTR_HLPR(event, frame) \ 133 do { \ 134 if (frame != NULL) \ 135 PMC_SOFT_CALL_TF( , , intr, event, frame); \ 136 else \ 137 PMC_SOFT_CALL( , , intr, event); \ 138 } while (0) 139 #endif 140 141 /* Map an interrupt type to an ithread priority. */ 142 u_char 143 intr_priority(enum intr_type flags) 144 { 145 u_char pri; 146 147 flags &= (INTR_TYPE_TTY | INTR_TYPE_BIO | INTR_TYPE_NET | 148 INTR_TYPE_CAM | INTR_TYPE_MISC | INTR_TYPE_CLK | INTR_TYPE_AV); 149 switch (flags) { 150 case INTR_TYPE_TTY: 151 pri = PI_TTY; 152 break; 153 case INTR_TYPE_BIO: 154 pri = PI_DISK; 155 break; 156 case INTR_TYPE_NET: 157 pri = PI_NET; 158 break; 159 case INTR_TYPE_CAM: 160 pri = PI_DISK; 161 break; 162 case INTR_TYPE_AV: 163 pri = PI_AV; 164 break; 165 case INTR_TYPE_CLK: 166 pri = PI_REALTIME; 167 break; 168 case INTR_TYPE_MISC: 169 pri = PI_DULL; /* don't care */ 170 break; 171 default: 172 /* We didn't specify an interrupt level. */ 173 panic("intr_priority: no interrupt type in flags"); 174 } 175 176 return pri; 177 } 178 179 /* 180 * Update an ithread based on the associated intr_event. 181 */ 182 static void 183 ithread_update(struct intr_thread *ithd) 184 { 185 struct intr_event *ie; 186 struct thread *td; 187 u_char pri; 188 189 ie = ithd->it_event; 190 td = ithd->it_thread; 191 mtx_assert(&ie->ie_lock, MA_OWNED); 192 193 /* Determine the overall priority of this event. */ 194 if (CK_SLIST_EMPTY(&ie->ie_handlers)) 195 pri = PRI_MAX_ITHD; 196 else 197 pri = CK_SLIST_FIRST(&ie->ie_handlers)->ih_pri; 198 199 /* Update name and priority. */ 200 strlcpy(td->td_name, ie->ie_fullname, sizeof(td->td_name)); 201 #ifdef KTR 202 sched_clear_tdname(td); 203 #endif 204 thread_lock(td); 205 sched_ithread_prio(td, pri); 206 thread_unlock(td); 207 } 208 209 /* 210 * Regenerate the full name of an interrupt event and update its priority. 211 */ 212 static void 213 intr_event_update(struct intr_event *ie) 214 { 215 struct intr_handler *ih; 216 char *last; 217 int missed, space, flags; 218 219 /* Start off with no entropy and just the name of the event. */ 220 mtx_assert(&ie->ie_lock, MA_OWNED); 221 strlcpy(ie->ie_fullname, ie->ie_name, sizeof(ie->ie_fullname)); 222 flags = 0; 223 missed = 0; 224 space = 1; 225 226 /* Run through all the handlers updating values. */ 227 CK_SLIST_FOREACH(ih, &ie->ie_handlers, ih_next) { 228 if (strlen(ie->ie_fullname) + strlen(ih->ih_name) + 1 < 229 sizeof(ie->ie_fullname)) { 230 strcat(ie->ie_fullname, " "); 231 strcat(ie->ie_fullname, ih->ih_name); 232 space = 0; 233 } else 234 missed++; 235 flags |= ih->ih_flags; 236 } 237 ie->ie_hflags = flags; 238 239 /* 240 * If there is only one handler and its name is too long, just copy in 241 * as much of the end of the name (includes the unit number) as will 242 * fit. Otherwise, we have multiple handlers and not all of the names 243 * will fit. Add +'s to indicate missing names. If we run out of room 244 * and still have +'s to add, change the last character from a + to a *. 245 */ 246 if (missed == 1 && space == 1) { 247 ih = CK_SLIST_FIRST(&ie->ie_handlers); 248 missed = strlen(ie->ie_fullname) + strlen(ih->ih_name) + 2 - 249 sizeof(ie->ie_fullname); 250 strcat(ie->ie_fullname, (missed == 0) ? " " : "-"); 251 strcat(ie->ie_fullname, &ih->ih_name[missed]); 252 missed = 0; 253 } 254 last = &ie->ie_fullname[sizeof(ie->ie_fullname) - 2]; 255 while (missed-- > 0) { 256 if (strlen(ie->ie_fullname) + 1 == sizeof(ie->ie_fullname)) { 257 if (*last == '+') { 258 *last = '*'; 259 break; 260 } else 261 *last = '+'; 262 } else if (space) { 263 strcat(ie->ie_fullname, " +"); 264 space = 0; 265 } else 266 strcat(ie->ie_fullname, "+"); 267 } 268 269 /* 270 * If this event has an ithread, update it's priority and 271 * name. 272 */ 273 if (ie->ie_thread != NULL) 274 ithread_update(ie->ie_thread); 275 CTR2(KTR_INTR, "%s: updated %s", __func__, ie->ie_fullname); 276 } 277 278 int 279 intr_event_create(struct intr_event **event, void *source, int flags, int irq, 280 void (*pre_ithread)(void *), void (*post_ithread)(void *), 281 void (*post_filter)(void *), int (*assign_cpu)(void *, int), 282 const char *fmt, ...) 283 { 284 struct intr_event *ie; 285 va_list ap; 286 287 /* The only valid flag during creation is IE_SOFT. */ 288 if ((flags & ~IE_SOFT) != 0) 289 return (EINVAL); 290 ie = malloc(sizeof(struct intr_event), M_ITHREAD, M_WAITOK | M_ZERO); 291 ie->ie_source = source; 292 ie->ie_pre_ithread = pre_ithread; 293 ie->ie_post_ithread = post_ithread; 294 ie->ie_post_filter = post_filter; 295 ie->ie_assign_cpu = assign_cpu; 296 ie->ie_flags = flags; 297 ie->ie_irq = irq; 298 ie->ie_cpu = NOCPU; 299 CK_SLIST_INIT(&ie->ie_handlers); 300 mtx_init(&ie->ie_lock, "intr event", NULL, MTX_DEF); 301 302 va_start(ap, fmt); 303 vsnprintf(ie->ie_name, sizeof(ie->ie_name), fmt, ap); 304 va_end(ap); 305 strlcpy(ie->ie_fullname, ie->ie_name, sizeof(ie->ie_fullname)); 306 mtx_lock(&event_lock); 307 TAILQ_INSERT_TAIL(&event_list, ie, ie_list); 308 mtx_unlock(&event_lock); 309 if (event != NULL) 310 *event = ie; 311 CTR2(KTR_INTR, "%s: created %s", __func__, ie->ie_name); 312 return (0); 313 } 314 315 /* 316 * Bind an interrupt event to the specified CPU. Note that not all 317 * platforms support binding an interrupt to a CPU. For those 318 * platforms this request will fail. Using a cpu id of NOCPU unbinds 319 * the interrupt event. 320 */ 321 static int 322 _intr_event_bind(struct intr_event *ie, int cpu, bool bindirq, bool bindithread) 323 { 324 lwpid_t id; 325 int error; 326 327 /* Need a CPU to bind to. */ 328 if (cpu != NOCPU && CPU_ABSENT(cpu)) 329 return (EINVAL); 330 331 if (ie->ie_assign_cpu == NULL) 332 return (EOPNOTSUPP); 333 334 error = priv_check(curthread, PRIV_SCHED_CPUSET_INTR); 335 if (error) 336 return (error); 337 338 /* 339 * If we have any ithreads try to set their mask first to verify 340 * permissions, etc. 341 */ 342 if (bindithread) { 343 mtx_lock(&ie->ie_lock); 344 if (ie->ie_thread != NULL) { 345 id = ie->ie_thread->it_thread->td_tid; 346 mtx_unlock(&ie->ie_lock); 347 error = cpuset_setithread(id, cpu); 348 if (error) 349 return (error); 350 } else 351 mtx_unlock(&ie->ie_lock); 352 } 353 if (bindirq) 354 error = ie->ie_assign_cpu(ie->ie_source, cpu); 355 if (error) { 356 if (bindithread) { 357 mtx_lock(&ie->ie_lock); 358 if (ie->ie_thread != NULL) { 359 cpu = ie->ie_cpu; 360 id = ie->ie_thread->it_thread->td_tid; 361 mtx_unlock(&ie->ie_lock); 362 (void)cpuset_setithread(id, cpu); 363 } else 364 mtx_unlock(&ie->ie_lock); 365 } 366 return (error); 367 } 368 369 if (bindirq) { 370 mtx_lock(&ie->ie_lock); 371 ie->ie_cpu = cpu; 372 mtx_unlock(&ie->ie_lock); 373 } 374 375 return (error); 376 } 377 378 /* 379 * Bind an interrupt event to the specified CPU. For supported platforms, any 380 * associated ithreads as well as the primary interrupt context will be bound 381 * to the specificed CPU. 382 */ 383 int 384 intr_event_bind(struct intr_event *ie, int cpu) 385 { 386 387 return (_intr_event_bind(ie, cpu, true, true)); 388 } 389 390 /* 391 * Bind an interrupt event to the specified CPU, but do not bind associated 392 * ithreads. 393 */ 394 int 395 intr_event_bind_irqonly(struct intr_event *ie, int cpu) 396 { 397 398 return (_intr_event_bind(ie, cpu, true, false)); 399 } 400 401 /* 402 * Bind an interrupt event's ithread to the specified CPU. 403 */ 404 int 405 intr_event_bind_ithread(struct intr_event *ie, int cpu) 406 { 407 408 return (_intr_event_bind(ie, cpu, false, true)); 409 } 410 411 /* 412 * Bind an interrupt event's ithread to the specified cpuset. 413 */ 414 int 415 intr_event_bind_ithread_cpuset(struct intr_event *ie, cpuset_t *cs) 416 { 417 lwpid_t id; 418 419 mtx_lock(&ie->ie_lock); 420 if (ie->ie_thread != NULL) { 421 id = ie->ie_thread->it_thread->td_tid; 422 mtx_unlock(&ie->ie_lock); 423 return (cpuset_setthread(id, cs)); 424 } else { 425 mtx_unlock(&ie->ie_lock); 426 } 427 return (ENODEV); 428 } 429 430 static struct intr_event * 431 intr_lookup(int irq) 432 { 433 struct intr_event *ie; 434 435 mtx_lock(&event_lock); 436 TAILQ_FOREACH(ie, &event_list, ie_list) 437 if (ie->ie_irq == irq && 438 (ie->ie_flags & IE_SOFT) == 0 && 439 CK_SLIST_FIRST(&ie->ie_handlers) != NULL) 440 break; 441 mtx_unlock(&event_lock); 442 return (ie); 443 } 444 445 int 446 intr_setaffinity(int irq, int mode, void *m) 447 { 448 struct intr_event *ie; 449 cpuset_t *mask; 450 int cpu, n; 451 452 mask = m; 453 cpu = NOCPU; 454 /* 455 * If we're setting all cpus we can unbind. Otherwise make sure 456 * only one cpu is in the set. 457 */ 458 if (CPU_CMP(cpuset_root, mask)) { 459 for (n = 0; n < CPU_SETSIZE; n++) { 460 if (!CPU_ISSET(n, mask)) 461 continue; 462 if (cpu != NOCPU) 463 return (EINVAL); 464 cpu = n; 465 } 466 } 467 ie = intr_lookup(irq); 468 if (ie == NULL) 469 return (ESRCH); 470 switch (mode) { 471 case CPU_WHICH_IRQ: 472 return (intr_event_bind(ie, cpu)); 473 case CPU_WHICH_INTRHANDLER: 474 return (intr_event_bind_irqonly(ie, cpu)); 475 case CPU_WHICH_ITHREAD: 476 return (intr_event_bind_ithread(ie, cpu)); 477 default: 478 return (EINVAL); 479 } 480 } 481 482 int 483 intr_getaffinity(int irq, int mode, void *m) 484 { 485 struct intr_event *ie; 486 struct thread *td; 487 struct proc *p; 488 cpuset_t *mask; 489 lwpid_t id; 490 int error; 491 492 mask = m; 493 ie = intr_lookup(irq); 494 if (ie == NULL) 495 return (ESRCH); 496 497 error = 0; 498 CPU_ZERO(mask); 499 switch (mode) { 500 case CPU_WHICH_IRQ: 501 case CPU_WHICH_INTRHANDLER: 502 mtx_lock(&ie->ie_lock); 503 if (ie->ie_cpu == NOCPU) 504 CPU_COPY(cpuset_root, mask); 505 else 506 CPU_SET(ie->ie_cpu, mask); 507 mtx_unlock(&ie->ie_lock); 508 break; 509 case CPU_WHICH_ITHREAD: 510 mtx_lock(&ie->ie_lock); 511 if (ie->ie_thread == NULL) { 512 mtx_unlock(&ie->ie_lock); 513 CPU_COPY(cpuset_root, mask); 514 } else { 515 id = ie->ie_thread->it_thread->td_tid; 516 mtx_unlock(&ie->ie_lock); 517 error = cpuset_which(CPU_WHICH_TID, id, &p, &td, NULL); 518 if (error != 0) 519 return (error); 520 CPU_COPY(&td->td_cpuset->cs_mask, mask); 521 PROC_UNLOCK(p); 522 } 523 default: 524 return (EINVAL); 525 } 526 return (0); 527 } 528 529 int 530 intr_event_destroy(struct intr_event *ie) 531 { 532 533 if (ie == NULL) 534 return (EINVAL); 535 536 mtx_lock(&event_lock); 537 mtx_lock(&ie->ie_lock); 538 if (!CK_SLIST_EMPTY(&ie->ie_handlers)) { 539 mtx_unlock(&ie->ie_lock); 540 mtx_unlock(&event_lock); 541 return (EBUSY); 542 } 543 TAILQ_REMOVE(&event_list, ie, ie_list); 544 #ifndef notyet 545 if (ie->ie_thread != NULL) { 546 ithread_destroy(ie->ie_thread); 547 ie->ie_thread = NULL; 548 } 549 #endif 550 mtx_unlock(&ie->ie_lock); 551 mtx_unlock(&event_lock); 552 mtx_destroy(&ie->ie_lock); 553 free(ie, M_ITHREAD); 554 return (0); 555 } 556 557 static struct intr_thread * 558 ithread_create(const char *name) 559 { 560 struct intr_thread *ithd; 561 struct thread *td; 562 int error; 563 564 ithd = malloc(sizeof(struct intr_thread), M_ITHREAD, M_WAITOK | M_ZERO); 565 566 error = kproc_kthread_add(ithread_loop, ithd, &intrproc, 567 &td, RFSTOPPED | RFHIGHPID, 568 0, "intr", "%s", name); 569 if (error) 570 panic("kproc_create() failed with %d", error); 571 thread_lock(td); 572 sched_class(td, PRI_ITHD); 573 TD_SET_IWAIT(td); 574 thread_unlock(td); 575 td->td_pflags |= TDP_ITHREAD; 576 ithd->it_thread = td; 577 CTR2(KTR_INTR, "%s: created %s", __func__, name); 578 return (ithd); 579 } 580 581 static void 582 ithread_destroy(struct intr_thread *ithread) 583 { 584 struct thread *td; 585 586 CTR2(KTR_INTR, "%s: killing %s", __func__, ithread->it_event->ie_name); 587 td = ithread->it_thread; 588 thread_lock(td); 589 ithread->it_flags |= IT_DEAD; 590 if (TD_AWAITING_INTR(td)) { 591 TD_CLR_IWAIT(td); 592 sched_wakeup(td, SRQ_INTR); 593 } else 594 thread_unlock(td); 595 } 596 597 int 598 intr_event_add_handler(struct intr_event *ie, const char *name, 599 driver_filter_t filter, driver_intr_t handler, void *arg, u_char pri, 600 enum intr_type flags, void **cookiep) 601 { 602 struct intr_handler *ih, *temp_ih; 603 struct intr_handler **prevptr; 604 struct intr_thread *it; 605 606 if (ie == NULL || name == NULL || (handler == NULL && filter == NULL)) 607 return (EINVAL); 608 609 /* Allocate and populate an interrupt handler structure. */ 610 ih = malloc(sizeof(struct intr_handler), M_ITHREAD, M_WAITOK | M_ZERO); 611 ih->ih_filter = filter; 612 ih->ih_handler = handler; 613 ih->ih_argument = arg; 614 strlcpy(ih->ih_name, name, sizeof(ih->ih_name)); 615 ih->ih_event = ie; 616 ih->ih_pri = pri; 617 if (flags & INTR_EXCL) 618 ih->ih_flags = IH_EXCLUSIVE; 619 if (flags & INTR_MPSAFE) 620 ih->ih_flags |= IH_MPSAFE; 621 if (flags & INTR_ENTROPY) 622 ih->ih_flags |= IH_ENTROPY; 623 if (flags & INTR_TYPE_NET) 624 ih->ih_flags |= IH_NET; 625 626 /* We can only have one exclusive handler in a event. */ 627 mtx_lock(&ie->ie_lock); 628 if (!CK_SLIST_EMPTY(&ie->ie_handlers)) { 629 if ((flags & INTR_EXCL) || 630 (CK_SLIST_FIRST(&ie->ie_handlers)->ih_flags & IH_EXCLUSIVE)) { 631 mtx_unlock(&ie->ie_lock); 632 free(ih, M_ITHREAD); 633 return (EINVAL); 634 } 635 } 636 637 /* Create a thread if we need one. */ 638 while (ie->ie_thread == NULL && handler != NULL) { 639 if (ie->ie_flags & IE_ADDING_THREAD) 640 msleep(ie, &ie->ie_lock, 0, "ithread", 0); 641 else { 642 ie->ie_flags |= IE_ADDING_THREAD; 643 mtx_unlock(&ie->ie_lock); 644 it = ithread_create("intr: newborn"); 645 mtx_lock(&ie->ie_lock); 646 ie->ie_flags &= ~IE_ADDING_THREAD; 647 ie->ie_thread = it; 648 it->it_event = ie; 649 ithread_update(it); 650 wakeup(ie); 651 } 652 } 653 654 /* Add the new handler to the event in priority order. */ 655 CK_SLIST_FOREACH_PREVPTR(temp_ih, prevptr, &ie->ie_handlers, ih_next) { 656 if (temp_ih->ih_pri > ih->ih_pri) 657 break; 658 } 659 CK_SLIST_INSERT_PREVPTR(prevptr, temp_ih, ih, ih_next); 660 661 intr_event_update(ie); 662 663 CTR3(KTR_INTR, "%s: added %s to %s", __func__, ih->ih_name, 664 ie->ie_name); 665 mtx_unlock(&ie->ie_lock); 666 667 if (cookiep != NULL) 668 *cookiep = ih; 669 return (0); 670 } 671 672 /* 673 * Append a description preceded by a ':' to the name of the specified 674 * interrupt handler. 675 */ 676 int 677 intr_event_describe_handler(struct intr_event *ie, void *cookie, 678 const char *descr) 679 { 680 struct intr_handler *ih; 681 size_t space; 682 char *start; 683 684 mtx_lock(&ie->ie_lock); 685 #ifdef INVARIANTS 686 CK_SLIST_FOREACH(ih, &ie->ie_handlers, ih_next) { 687 if (ih == cookie) 688 break; 689 } 690 if (ih == NULL) { 691 mtx_unlock(&ie->ie_lock); 692 panic("handler %p not found in interrupt event %p", cookie, ie); 693 } 694 #endif 695 ih = cookie; 696 697 /* 698 * Look for an existing description by checking for an 699 * existing ":". This assumes device names do not include 700 * colons. If one is found, prepare to insert the new 701 * description at that point. If one is not found, find the 702 * end of the name to use as the insertion point. 703 */ 704 start = strchr(ih->ih_name, ':'); 705 if (start == NULL) 706 start = strchr(ih->ih_name, 0); 707 708 /* 709 * See if there is enough remaining room in the string for the 710 * description + ":". The "- 1" leaves room for the trailing 711 * '\0'. The "+ 1" accounts for the colon. 712 */ 713 space = sizeof(ih->ih_name) - (start - ih->ih_name) - 1; 714 if (strlen(descr) + 1 > space) { 715 mtx_unlock(&ie->ie_lock); 716 return (ENOSPC); 717 } 718 719 /* Append a colon followed by the description. */ 720 *start = ':'; 721 strcpy(start + 1, descr); 722 intr_event_update(ie); 723 mtx_unlock(&ie->ie_lock); 724 return (0); 725 } 726 727 /* 728 * Return the ie_source field from the intr_event an intr_handler is 729 * associated with. 730 */ 731 void * 732 intr_handler_source(void *cookie) 733 { 734 struct intr_handler *ih; 735 struct intr_event *ie; 736 737 ih = (struct intr_handler *)cookie; 738 if (ih == NULL) 739 return (NULL); 740 ie = ih->ih_event; 741 KASSERT(ie != NULL, 742 ("interrupt handler \"%s\" has a NULL interrupt event", 743 ih->ih_name)); 744 return (ie->ie_source); 745 } 746 747 /* 748 * If intr_event_handle() is running in the ISR context at the time of the call, 749 * then wait for it to complete. 750 */ 751 static void 752 intr_event_barrier(struct intr_event *ie) 753 { 754 int phase; 755 756 mtx_assert(&ie->ie_lock, MA_OWNED); 757 phase = ie->ie_phase; 758 759 /* 760 * Switch phase to direct future interrupts to the other active counter. 761 * Make sure that any preceding stores are visible before the switch. 762 */ 763 KASSERT(ie->ie_active[!phase] == 0, ("idle phase has activity")); 764 atomic_store_rel_int(&ie->ie_phase, !phase); 765 766 /* 767 * This code cooperates with wait-free iteration of ie_handlers 768 * in intr_event_handle. 769 * Make sure that the removal and the phase update are not reordered 770 * with the active count check. 771 * Note that no combination of acquire and release fences can provide 772 * that guarantee as Store->Load sequences can always be reordered. 773 */ 774 atomic_thread_fence_seq_cst(); 775 776 /* 777 * Now wait on the inactive phase. 778 * The acquire fence is needed so that all post-barrier accesses 779 * are after the check. 780 */ 781 while (ie->ie_active[phase] > 0) 782 cpu_spinwait(); 783 atomic_thread_fence_acq(); 784 } 785 786 static void 787 intr_handler_barrier(struct intr_handler *handler) 788 { 789 struct intr_event *ie; 790 791 ie = handler->ih_event; 792 mtx_assert(&ie->ie_lock, MA_OWNED); 793 KASSERT((handler->ih_flags & IH_DEAD) == 0, 794 ("update for a removed handler")); 795 796 if (ie->ie_thread == NULL) { 797 intr_event_barrier(ie); 798 return; 799 } 800 if ((handler->ih_flags & IH_CHANGED) == 0) { 801 handler->ih_flags |= IH_CHANGED; 802 intr_event_schedule_thread(ie, NULL); 803 } 804 while ((handler->ih_flags & IH_CHANGED) != 0) 805 msleep(handler, &ie->ie_lock, 0, "ih_barr", 0); 806 } 807 808 /* 809 * Sleep until an ithread finishes executing an interrupt handler. 810 * 811 * XXX Doesn't currently handle interrupt filters or fast interrupt 812 * handlers. This is intended for LinuxKPI drivers only. 813 * Do not use in BSD code. 814 */ 815 void 816 _intr_drain(int irq) 817 { 818 struct intr_event *ie; 819 struct intr_thread *ithd; 820 struct thread *td; 821 822 ie = intr_lookup(irq); 823 if (ie == NULL) 824 return; 825 if (ie->ie_thread == NULL) 826 return; 827 ithd = ie->ie_thread; 828 td = ithd->it_thread; 829 /* 830 * We set the flag and wait for it to be cleared to avoid 831 * long delays with potentially busy interrupt handlers 832 * were we to only sample TD_AWAITING_INTR() every tick. 833 */ 834 thread_lock(td); 835 if (!TD_AWAITING_INTR(td)) { 836 ithd->it_flags |= IT_WAIT; 837 while (ithd->it_flags & IT_WAIT) { 838 thread_unlock(td); 839 pause("idrain", 1); 840 thread_lock(td); 841 } 842 } 843 thread_unlock(td); 844 return; 845 } 846 847 int 848 intr_event_remove_handler(void *cookie) 849 { 850 struct intr_handler *handler = (struct intr_handler *)cookie; 851 struct intr_event *ie; 852 struct intr_handler *ih; 853 struct intr_handler **prevptr; 854 #ifdef notyet 855 int dead; 856 #endif 857 858 if (handler == NULL) 859 return (EINVAL); 860 ie = handler->ih_event; 861 KASSERT(ie != NULL, 862 ("interrupt handler \"%s\" has a NULL interrupt event", 863 handler->ih_name)); 864 865 mtx_lock(&ie->ie_lock); 866 CTR3(KTR_INTR, "%s: removing %s from %s", __func__, handler->ih_name, 867 ie->ie_name); 868 CK_SLIST_FOREACH_PREVPTR(ih, prevptr, &ie->ie_handlers, ih_next) { 869 if (ih == handler) 870 break; 871 } 872 if (ih == NULL) { 873 panic("interrupt handler \"%s\" not found in " 874 "interrupt event \"%s\"", handler->ih_name, ie->ie_name); 875 } 876 877 /* 878 * If there is no ithread, then directly remove the handler. Note that 879 * intr_event_handle() iterates ie_handlers in a lock-less fashion, so 880 * care needs to be taken to keep ie_handlers consistent and to free 881 * the removed handler only when ie_handlers is quiescent. 882 */ 883 if (ie->ie_thread == NULL) { 884 CK_SLIST_REMOVE_PREVPTR(prevptr, ih, ih_next); 885 intr_event_barrier(ie); 886 intr_event_update(ie); 887 mtx_unlock(&ie->ie_lock); 888 free(handler, M_ITHREAD); 889 return (0); 890 } 891 892 /* 893 * Let the interrupt thread do the job. 894 * The interrupt source is disabled when the interrupt thread is 895 * running, so it does not have to worry about interaction with 896 * intr_event_handle(). 897 */ 898 KASSERT((handler->ih_flags & IH_DEAD) == 0, 899 ("duplicate handle remove")); 900 handler->ih_flags |= IH_DEAD; 901 intr_event_schedule_thread(ie, NULL); 902 while (handler->ih_flags & IH_DEAD) 903 msleep(handler, &ie->ie_lock, 0, "iev_rmh", 0); 904 intr_event_update(ie); 905 906 #ifdef notyet 907 /* 908 * XXX: This could be bad in the case of ppbus(8). Also, I think 909 * this could lead to races of stale data when servicing an 910 * interrupt. 911 */ 912 dead = 1; 913 CK_SLIST_FOREACH(ih, &ie->ie_handlers, ih_next) { 914 if (ih->ih_handler != NULL) { 915 dead = 0; 916 break; 917 } 918 } 919 if (dead) { 920 ithread_destroy(ie->ie_thread); 921 ie->ie_thread = NULL; 922 } 923 #endif 924 mtx_unlock(&ie->ie_lock); 925 free(handler, M_ITHREAD); 926 return (0); 927 } 928 929 int 930 intr_event_suspend_handler(void *cookie) 931 { 932 struct intr_handler *handler = (struct intr_handler *)cookie; 933 struct intr_event *ie; 934 935 if (handler == NULL) 936 return (EINVAL); 937 ie = handler->ih_event; 938 KASSERT(ie != NULL, 939 ("interrupt handler \"%s\" has a NULL interrupt event", 940 handler->ih_name)); 941 mtx_lock(&ie->ie_lock); 942 handler->ih_flags |= IH_SUSP; 943 intr_handler_barrier(handler); 944 mtx_unlock(&ie->ie_lock); 945 return (0); 946 } 947 948 int 949 intr_event_resume_handler(void *cookie) 950 { 951 struct intr_handler *handler = (struct intr_handler *)cookie; 952 struct intr_event *ie; 953 954 if (handler == NULL) 955 return (EINVAL); 956 ie = handler->ih_event; 957 KASSERT(ie != NULL, 958 ("interrupt handler \"%s\" has a NULL interrupt event", 959 handler->ih_name)); 960 961 /* 962 * intr_handler_barrier() acts not only as a barrier, 963 * it also allows to check for any pending interrupts. 964 */ 965 mtx_lock(&ie->ie_lock); 966 handler->ih_flags &= ~IH_SUSP; 967 intr_handler_barrier(handler); 968 mtx_unlock(&ie->ie_lock); 969 return (0); 970 } 971 972 static int 973 intr_event_schedule_thread(struct intr_event *ie, struct trapframe *frame) 974 { 975 struct intr_entropy entropy; 976 struct intr_thread *it; 977 struct thread *td; 978 struct thread *ctd; 979 980 /* 981 * If no ithread or no handlers, then we have a stray interrupt. 982 */ 983 if (ie == NULL || CK_SLIST_EMPTY(&ie->ie_handlers) || 984 ie->ie_thread == NULL) 985 return (EINVAL); 986 987 ctd = curthread; 988 it = ie->ie_thread; 989 td = it->it_thread; 990 991 /* 992 * If any of the handlers for this ithread claim to be good 993 * sources of entropy, then gather some. 994 */ 995 if (ie->ie_hflags & IH_ENTROPY) { 996 entropy.event = (uintptr_t)ie; 997 entropy.td = ctd; 998 random_harvest_queue(&entropy, sizeof(entropy), RANDOM_INTERRUPT); 999 } 1000 1001 KASSERT(td->td_proc != NULL, ("ithread %s has no process", ie->ie_name)); 1002 1003 /* 1004 * Set it_need to tell the thread to keep running if it is already 1005 * running. Then, lock the thread and see if we actually need to 1006 * put it on the runqueue. 1007 * 1008 * Use store_rel to arrange that the store to ih_need in 1009 * swi_sched() is before the store to it_need and prepare for 1010 * transfer of this order to loads in the ithread. 1011 */ 1012 atomic_store_rel_int(&it->it_need, 1); 1013 thread_lock(td); 1014 if (TD_AWAITING_INTR(td)) { 1015 #ifdef HWPMC_HOOKS 1016 it->it_waiting = 0; 1017 if (PMC_HOOK_INSTALLED_ANY()) 1018 PMC_SOFT_CALL_INTR_HLPR(schedule, frame); 1019 #endif 1020 CTR3(KTR_INTR, "%s: schedule pid %d (%s)", __func__, td->td_proc->p_pid, 1021 td->td_name); 1022 TD_CLR_IWAIT(td); 1023 sched_wakeup(td, SRQ_INTR); 1024 } else { 1025 #ifdef HWPMC_HOOKS 1026 it->it_waiting++; 1027 if (PMC_HOOK_INSTALLED_ANY() && 1028 (it->it_waiting >= intr_hwpmc_waiting_report_threshold)) 1029 PMC_SOFT_CALL_INTR_HLPR(waiting, frame); 1030 #endif 1031 CTR5(KTR_INTR, "%s: pid %d (%s): it_need %d, state %d", 1032 __func__, td->td_proc->p_pid, td->td_name, it->it_need, TD_GET_STATE(td)); 1033 thread_unlock(td); 1034 } 1035 1036 return (0); 1037 } 1038 1039 /* 1040 * Allow interrupt event binding for software interrupt handlers -- a no-op, 1041 * since interrupts are generated in software rather than being directed by 1042 * a PIC. 1043 */ 1044 static int 1045 swi_assign_cpu(void *arg, int cpu) 1046 { 1047 1048 return (0); 1049 } 1050 1051 /* 1052 * Add a software interrupt handler to a specified event. If a given event 1053 * is not specified, then a new event is created. 1054 */ 1055 int 1056 swi_add(struct intr_event **eventp, const char *name, driver_intr_t handler, 1057 void *arg, int pri, enum intr_type flags, void **cookiep) 1058 { 1059 struct intr_event *ie; 1060 int error = 0; 1061 1062 if (flags & INTR_ENTROPY) 1063 return (EINVAL); 1064 1065 ie = (eventp != NULL) ? *eventp : NULL; 1066 1067 if (ie != NULL) { 1068 if (!(ie->ie_flags & IE_SOFT)) 1069 return (EINVAL); 1070 } else { 1071 error = intr_event_create(&ie, NULL, IE_SOFT, 0, 1072 NULL, NULL, NULL, swi_assign_cpu, "swi%d:", pri); 1073 if (error) 1074 return (error); 1075 if (eventp != NULL) 1076 *eventp = ie; 1077 } 1078 if (handler != NULL) { 1079 error = intr_event_add_handler(ie, name, NULL, handler, arg, 1080 PI_SWI(pri), flags, cookiep); 1081 } 1082 return (error); 1083 } 1084 1085 /* 1086 * Schedule a software interrupt thread. 1087 */ 1088 void 1089 swi_sched(void *cookie, int flags) 1090 { 1091 struct intr_handler *ih = (struct intr_handler *)cookie; 1092 struct intr_event *ie = ih->ih_event; 1093 struct intr_entropy entropy; 1094 int error __unused; 1095 1096 CTR3(KTR_INTR, "swi_sched: %s %s need=%d", ie->ie_name, ih->ih_name, 1097 ih->ih_need); 1098 1099 if ((flags & SWI_FROMNMI) == 0) { 1100 entropy.event = (uintptr_t)ih; 1101 entropy.td = curthread; 1102 random_harvest_queue(&entropy, sizeof(entropy), RANDOM_SWI); 1103 } 1104 1105 /* 1106 * Set ih_need for this handler so that if the ithread is already 1107 * running it will execute this handler on the next pass. Otherwise, 1108 * it will execute it the next time it runs. 1109 */ 1110 ih->ih_need = 1; 1111 1112 if (flags & SWI_DELAY) 1113 return; 1114 1115 if (flags & SWI_FROMNMI) { 1116 #if defined(SMP) && (defined(__i386__) || defined(__amd64__)) 1117 KASSERT(ie == clk_intr_event, 1118 ("SWI_FROMNMI used not with clk_intr_event")); 1119 ipi_self_from_nmi(IPI_SWI); 1120 #endif 1121 } else { 1122 VM_CNT_INC(v_soft); 1123 error = intr_event_schedule_thread(ie, NULL); 1124 KASSERT(error == 0, ("stray software interrupt")); 1125 } 1126 } 1127 1128 /* 1129 * Remove a software interrupt handler. Currently this code does not 1130 * remove the associated interrupt event if it becomes empty. Calling code 1131 * may do so manually via intr_event_destroy(), but that's not really 1132 * an optimal interface. 1133 */ 1134 int 1135 swi_remove(void *cookie) 1136 { 1137 1138 return (intr_event_remove_handler(cookie)); 1139 } 1140 1141 static void 1142 intr_event_execute_handlers(struct proc *p, struct intr_event *ie) 1143 { 1144 struct intr_handler *ih, *ihn, *ihp; 1145 1146 ihp = NULL; 1147 CK_SLIST_FOREACH_SAFE(ih, &ie->ie_handlers, ih_next, ihn) { 1148 /* 1149 * If this handler is marked for death, remove it from 1150 * the list of handlers and wake up the sleeper. 1151 */ 1152 if (ih->ih_flags & IH_DEAD) { 1153 mtx_lock(&ie->ie_lock); 1154 if (ihp == NULL) 1155 CK_SLIST_REMOVE_HEAD(&ie->ie_handlers, ih_next); 1156 else 1157 CK_SLIST_REMOVE_AFTER(ihp, ih_next); 1158 ih->ih_flags &= ~IH_DEAD; 1159 wakeup(ih); 1160 mtx_unlock(&ie->ie_lock); 1161 continue; 1162 } 1163 1164 /* 1165 * Now that we know that the current element won't be removed 1166 * update the previous element. 1167 */ 1168 ihp = ih; 1169 1170 if ((ih->ih_flags & IH_CHANGED) != 0) { 1171 mtx_lock(&ie->ie_lock); 1172 ih->ih_flags &= ~IH_CHANGED; 1173 wakeup(ih); 1174 mtx_unlock(&ie->ie_lock); 1175 } 1176 1177 /* Skip filter only handlers */ 1178 if (ih->ih_handler == NULL) 1179 continue; 1180 1181 /* Skip suspended handlers */ 1182 if ((ih->ih_flags & IH_SUSP) != 0) 1183 continue; 1184 1185 /* 1186 * For software interrupt threads, we only execute 1187 * handlers that have their need flag set. Hardware 1188 * interrupt threads always invoke all of their handlers. 1189 * 1190 * ih_need can only be 0 or 1. Failed cmpset below 1191 * means that there is no request to execute handlers, 1192 * so a retry of the cmpset is not needed. 1193 */ 1194 if ((ie->ie_flags & IE_SOFT) != 0 && 1195 atomic_cmpset_int(&ih->ih_need, 1, 0) == 0) 1196 continue; 1197 1198 /* Execute this handler. */ 1199 CTR6(KTR_INTR, "%s: pid %d exec %p(%p) for %s flg=%x", 1200 __func__, p->p_pid, (void *)ih->ih_handler, 1201 ih->ih_argument, ih->ih_name, ih->ih_flags); 1202 1203 if (!(ih->ih_flags & IH_MPSAFE)) 1204 mtx_lock(&Giant); 1205 ih->ih_handler(ih->ih_argument); 1206 if (!(ih->ih_flags & IH_MPSAFE)) 1207 mtx_unlock(&Giant); 1208 } 1209 } 1210 1211 static void 1212 ithread_execute_handlers(struct proc *p, struct intr_event *ie) 1213 { 1214 1215 /* Interrupt handlers should not sleep. */ 1216 if (!(ie->ie_flags & IE_SOFT)) 1217 THREAD_NO_SLEEPING(); 1218 intr_event_execute_handlers(p, ie); 1219 if (!(ie->ie_flags & IE_SOFT)) 1220 THREAD_SLEEPING_OK(); 1221 1222 /* 1223 * Interrupt storm handling: 1224 * 1225 * If this interrupt source is currently storming, then throttle 1226 * it to only fire the handler once per clock tick. 1227 * 1228 * If this interrupt source is not currently storming, but the 1229 * number of back to back interrupts exceeds the storm threshold, 1230 * then enter storming mode. 1231 */ 1232 if (intr_storm_threshold != 0 && ie->ie_count >= intr_storm_threshold && 1233 !(ie->ie_flags & IE_SOFT)) { 1234 /* Report the message only once every second. */ 1235 if (ppsratecheck(&ie->ie_warntm, &ie->ie_warncnt, 1)) { 1236 printf( 1237 "interrupt storm detected on \"%s\"; throttling interrupt source\n", 1238 ie->ie_name); 1239 } 1240 pause("istorm", 1); 1241 } else 1242 ie->ie_count++; 1243 1244 /* 1245 * Now that all the handlers have had a chance to run, reenable 1246 * the interrupt source. 1247 */ 1248 if (ie->ie_post_ithread != NULL) 1249 ie->ie_post_ithread(ie->ie_source); 1250 } 1251 1252 /* 1253 * This is the main code for interrupt threads. 1254 */ 1255 static void 1256 ithread_loop(void *arg) 1257 { 1258 struct epoch_tracker et; 1259 struct intr_thread *ithd; 1260 struct intr_event *ie; 1261 struct thread *td; 1262 struct proc *p; 1263 int wake, epoch_count; 1264 bool needs_epoch; 1265 1266 td = curthread; 1267 p = td->td_proc; 1268 ithd = (struct intr_thread *)arg; 1269 KASSERT(ithd->it_thread == td, 1270 ("%s: ithread and proc linkage out of sync", __func__)); 1271 ie = ithd->it_event; 1272 ie->ie_count = 0; 1273 wake = 0; 1274 1275 /* 1276 * As long as we have interrupts outstanding, go through the 1277 * list of handlers, giving each one a go at it. 1278 */ 1279 for (;;) { 1280 /* 1281 * If we are an orphaned thread, then just die. 1282 */ 1283 if (ithd->it_flags & IT_DEAD) { 1284 CTR3(KTR_INTR, "%s: pid %d (%s) exiting", __func__, 1285 p->p_pid, td->td_name); 1286 free(ithd, M_ITHREAD); 1287 kthread_exit(); 1288 } 1289 1290 /* 1291 * Service interrupts. If another interrupt arrives while 1292 * we are running, it will set it_need to note that we 1293 * should make another pass. 1294 * 1295 * The load_acq part of the following cmpset ensures 1296 * that the load of ih_need in ithread_execute_handlers() 1297 * is ordered after the load of it_need here. 1298 */ 1299 needs_epoch = 1300 (atomic_load_int(&ie->ie_hflags) & IH_NET) != 0; 1301 if (needs_epoch) { 1302 epoch_count = 0; 1303 NET_EPOCH_ENTER(et); 1304 } 1305 while (atomic_cmpset_acq_int(&ithd->it_need, 1, 0) != 0) { 1306 ithread_execute_handlers(p, ie); 1307 if (needs_epoch && 1308 ++epoch_count >= intr_epoch_batch) { 1309 NET_EPOCH_EXIT(et); 1310 epoch_count = 0; 1311 NET_EPOCH_ENTER(et); 1312 } 1313 } 1314 if (needs_epoch) 1315 NET_EPOCH_EXIT(et); 1316 WITNESS_WARN(WARN_PANIC, NULL, "suspending ithread"); 1317 mtx_assert(&Giant, MA_NOTOWNED); 1318 1319 /* 1320 * Processed all our interrupts. Now get the sched 1321 * lock. This may take a while and it_need may get 1322 * set again, so we have to check it again. 1323 */ 1324 thread_lock(td); 1325 if (atomic_load_acq_int(&ithd->it_need) == 0 && 1326 (ithd->it_flags & (IT_DEAD | IT_WAIT)) == 0) { 1327 TD_SET_IWAIT(td); 1328 ie->ie_count = 0; 1329 mi_switch(SW_VOL | SWT_IWAIT); 1330 } else { 1331 if (ithd->it_flags & IT_WAIT) { 1332 wake = 1; 1333 ithd->it_flags &= ~IT_WAIT; 1334 } 1335 thread_unlock(td); 1336 } 1337 if (wake) { 1338 wakeup(ithd); 1339 wake = 0; 1340 } 1341 } 1342 } 1343 1344 /* 1345 * Main interrupt handling body. 1346 * 1347 * Input: 1348 * o ie: the event connected to this interrupt. 1349 * o frame: some archs (i.e. i386) pass a frame to some. 1350 * handlers as their main argument. 1351 * Return value: 1352 * o 0: everything ok. 1353 * o EINVAL: stray interrupt. 1354 */ 1355 int 1356 intr_event_handle(struct intr_event *ie, struct trapframe *frame) 1357 { 1358 struct intr_handler *ih; 1359 struct trapframe *oldframe; 1360 struct thread *td; 1361 int phase; 1362 int ret; 1363 bool filter, thread; 1364 1365 td = curthread; 1366 1367 #ifdef KSTACK_USAGE_PROF 1368 intr_prof_stack_use(td, frame); 1369 #endif 1370 1371 /* An interrupt with no event or handlers is a stray interrupt. */ 1372 if (ie == NULL || CK_SLIST_EMPTY(&ie->ie_handlers)) 1373 return (EINVAL); 1374 1375 /* 1376 * Execute fast interrupt handlers directly. 1377 * To support clock handlers, if a handler registers 1378 * with a NULL argument, then we pass it a pointer to 1379 * a trapframe as its argument. 1380 */ 1381 td->td_intr_nesting_level++; 1382 filter = false; 1383 thread = false; 1384 ret = 0; 1385 critical_enter(); 1386 oldframe = td->td_intr_frame; 1387 td->td_intr_frame = frame; 1388 1389 phase = ie->ie_phase; 1390 atomic_add_int(&ie->ie_active[phase], 1); 1391 1392 /* 1393 * This fence is required to ensure that no later loads are 1394 * re-ordered before the ie_active store. 1395 */ 1396 atomic_thread_fence_seq_cst(); 1397 1398 CK_SLIST_FOREACH(ih, &ie->ie_handlers, ih_next) { 1399 if ((ih->ih_flags & IH_SUSP) != 0) 1400 continue; 1401 if ((ie->ie_flags & IE_SOFT) != 0 && ih->ih_need == 0) 1402 continue; 1403 if (ih->ih_filter == NULL) { 1404 thread = true; 1405 continue; 1406 } 1407 CTR4(KTR_INTR, "%s: exec %p(%p) for %s", __func__, 1408 ih->ih_filter, ih->ih_argument == NULL ? frame : 1409 ih->ih_argument, ih->ih_name); 1410 if (ih->ih_argument == NULL) 1411 ret = ih->ih_filter(frame); 1412 else 1413 ret = ih->ih_filter(ih->ih_argument); 1414 #ifdef HWPMC_HOOKS 1415 PMC_SOFT_CALL_TF( , , intr, all, frame); 1416 #endif 1417 KASSERT(ret == FILTER_STRAY || 1418 ((ret & (FILTER_SCHEDULE_THREAD | FILTER_HANDLED)) != 0 && 1419 (ret & ~(FILTER_SCHEDULE_THREAD | FILTER_HANDLED)) == 0), 1420 ("%s: incorrect return value %#x from %s", __func__, ret, 1421 ih->ih_name)); 1422 filter = filter || ret == FILTER_HANDLED; 1423 #ifdef HWPMC_HOOKS 1424 if (ret & FILTER_SCHEDULE_THREAD) 1425 PMC_SOFT_CALL_TF( , , intr, ithread, frame); 1426 else if (ret & FILTER_HANDLED) 1427 PMC_SOFT_CALL_TF( , , intr, filter, frame); 1428 else if (ret == FILTER_STRAY) 1429 PMC_SOFT_CALL_TF( , , intr, stray, frame); 1430 #endif 1431 1432 /* 1433 * Wrapper handler special handling: 1434 * 1435 * in some particular cases (like pccard and pccbb), 1436 * the _real_ device handler is wrapped in a couple of 1437 * functions - a filter wrapper and an ithread wrapper. 1438 * In this case (and just in this case), the filter wrapper 1439 * could ask the system to schedule the ithread and mask 1440 * the interrupt source if the wrapped handler is composed 1441 * of just an ithread handler. 1442 * 1443 * TODO: write a generic wrapper to avoid people rolling 1444 * their own. 1445 */ 1446 if (!thread) { 1447 if (ret == FILTER_SCHEDULE_THREAD) 1448 thread = true; 1449 } 1450 } 1451 atomic_add_rel_int(&ie->ie_active[phase], -1); 1452 1453 td->td_intr_frame = oldframe; 1454 1455 if (thread) { 1456 if (ie->ie_pre_ithread != NULL) 1457 ie->ie_pre_ithread(ie->ie_source); 1458 } else { 1459 if (ie->ie_post_filter != NULL) 1460 ie->ie_post_filter(ie->ie_source); 1461 } 1462 1463 /* Schedule the ithread if needed. */ 1464 if (thread) { 1465 int error __unused; 1466 1467 error = intr_event_schedule_thread(ie, frame); 1468 KASSERT(error == 0, ("bad stray interrupt")); 1469 } 1470 critical_exit(); 1471 td->td_intr_nesting_level--; 1472 #ifdef notyet 1473 /* The interrupt is not aknowledged by any filter and has no ithread. */ 1474 if (!thread && !filter) 1475 return (EINVAL); 1476 #endif 1477 return (0); 1478 } 1479 1480 #ifdef DDB 1481 /* 1482 * Dump details about an interrupt handler 1483 */ 1484 static void 1485 db_dump_intrhand(struct intr_handler *ih) 1486 { 1487 int comma; 1488 1489 db_printf("\t%-10s ", ih->ih_name); 1490 switch (ih->ih_pri) { 1491 case PI_REALTIME: 1492 db_printf("CLK "); 1493 break; 1494 case PI_INTR: 1495 db_printf("INTR"); 1496 break; 1497 default: 1498 if (ih->ih_pri >= PI_SOFT) 1499 db_printf("SWI "); 1500 else 1501 db_printf("%4u", ih->ih_pri); 1502 break; 1503 } 1504 db_printf(" "); 1505 if (ih->ih_filter != NULL) { 1506 db_printf("[F]"); 1507 db_printsym((uintptr_t)ih->ih_filter, DB_STGY_PROC); 1508 } 1509 if (ih->ih_handler != NULL) { 1510 if (ih->ih_filter != NULL) 1511 db_printf(","); 1512 db_printf("[H]"); 1513 db_printsym((uintptr_t)ih->ih_handler, DB_STGY_PROC); 1514 } 1515 db_printf("(%p)", ih->ih_argument); 1516 if (ih->ih_need || 1517 (ih->ih_flags & (IH_EXCLUSIVE | IH_ENTROPY | IH_DEAD | 1518 IH_MPSAFE)) != 0) { 1519 db_printf(" {"); 1520 comma = 0; 1521 if (ih->ih_flags & IH_EXCLUSIVE) { 1522 if (comma) 1523 db_printf(", "); 1524 db_printf("EXCL"); 1525 comma = 1; 1526 } 1527 if (ih->ih_flags & IH_ENTROPY) { 1528 if (comma) 1529 db_printf(", "); 1530 db_printf("ENTROPY"); 1531 comma = 1; 1532 } 1533 if (ih->ih_flags & IH_DEAD) { 1534 if (comma) 1535 db_printf(", "); 1536 db_printf("DEAD"); 1537 comma = 1; 1538 } 1539 if (ih->ih_flags & IH_MPSAFE) { 1540 if (comma) 1541 db_printf(", "); 1542 db_printf("MPSAFE"); 1543 comma = 1; 1544 } 1545 if (ih->ih_need) { 1546 if (comma) 1547 db_printf(", "); 1548 db_printf("NEED"); 1549 } 1550 db_printf("}"); 1551 } 1552 db_printf("\n"); 1553 } 1554 1555 /* 1556 * Dump details about a event. 1557 */ 1558 void 1559 db_dump_intr_event(struct intr_event *ie, int handlers) 1560 { 1561 struct intr_handler *ih; 1562 struct intr_thread *it; 1563 int comma; 1564 1565 db_printf("%s ", ie->ie_fullname); 1566 it = ie->ie_thread; 1567 if (it != NULL) 1568 db_printf("(pid %d)", it->it_thread->td_proc->p_pid); 1569 else 1570 db_printf("(no thread)"); 1571 if ((ie->ie_flags & (IE_SOFT | IE_ADDING_THREAD)) != 0 || 1572 (it != NULL && it->it_need)) { 1573 db_printf(" {"); 1574 comma = 0; 1575 if (ie->ie_flags & IE_SOFT) { 1576 db_printf("SOFT"); 1577 comma = 1; 1578 } 1579 if (ie->ie_flags & IE_ADDING_THREAD) { 1580 if (comma) 1581 db_printf(", "); 1582 db_printf("ADDING_THREAD"); 1583 comma = 1; 1584 } 1585 if (it != NULL && it->it_need) { 1586 if (comma) 1587 db_printf(", "); 1588 db_printf("NEED"); 1589 } 1590 db_printf("}"); 1591 } 1592 db_printf("\n"); 1593 1594 if (handlers) 1595 CK_SLIST_FOREACH(ih, &ie->ie_handlers, ih_next) 1596 db_dump_intrhand(ih); 1597 } 1598 1599 /* 1600 * Dump data about interrupt handlers 1601 */ 1602 DB_SHOW_COMMAND_FLAGS(intr, db_show_intr, DB_CMD_MEMSAFE) 1603 { 1604 struct intr_event *ie; 1605 int all, verbose; 1606 1607 verbose = strchr(modif, 'v') != NULL; 1608 all = strchr(modif, 'a') != NULL; 1609 TAILQ_FOREACH(ie, &event_list, ie_list) { 1610 if (!all && CK_SLIST_EMPTY(&ie->ie_handlers)) 1611 continue; 1612 db_dump_intr_event(ie, verbose); 1613 if (db_pager_quit) 1614 break; 1615 } 1616 } 1617 #endif /* DDB */ 1618 1619 /* 1620 * Start standard software interrupt threads 1621 */ 1622 static void 1623 start_softintr(void *dummy) 1624 { 1625 1626 if (swi_add(&clk_intr_event, "clk", NULL, NULL, SWI_CLOCK, 1627 INTR_MPSAFE, NULL)) 1628 panic("died while creating clk swi ithread"); 1629 } 1630 SYSINIT(start_softintr, SI_SUB_SOFTINTR, SI_ORDER_FIRST, start_softintr, 1631 NULL); 1632 1633 /* 1634 * Sysctls used by systat and others: hw.intrnames and hw.intrcnt. 1635 * The data for this machine dependent, and the declarations are in machine 1636 * dependent code. The layout of intrnames and intrcnt however is machine 1637 * independent. 1638 * 1639 * We do not know the length of intrcnt and intrnames at compile time, so 1640 * calculate things at run time. 1641 */ 1642 static int 1643 sysctl_intrnames(SYSCTL_HANDLER_ARGS) 1644 { 1645 return (sysctl_handle_opaque(oidp, intrnames, sintrnames, req)); 1646 } 1647 1648 SYSCTL_PROC(_hw, OID_AUTO, intrnames, 1649 CTLTYPE_OPAQUE | CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, 0, 1650 sysctl_intrnames, "", 1651 "Interrupt Names"); 1652 1653 static int 1654 sysctl_intrcnt(SYSCTL_HANDLER_ARGS) 1655 { 1656 #ifdef SCTL_MASK32 1657 uint32_t *intrcnt32; 1658 unsigned i; 1659 int error; 1660 1661 if (req->flags & SCTL_MASK32) { 1662 if (!req->oldptr) 1663 return (sysctl_handle_opaque(oidp, NULL, sintrcnt / 2, req)); 1664 intrcnt32 = malloc(sintrcnt / 2, M_TEMP, M_NOWAIT); 1665 if (intrcnt32 == NULL) 1666 return (ENOMEM); 1667 for (i = 0; i < sintrcnt / sizeof (u_long); i++) 1668 intrcnt32[i] = intrcnt[i]; 1669 error = sysctl_handle_opaque(oidp, intrcnt32, sintrcnt / 2, req); 1670 free(intrcnt32, M_TEMP); 1671 return (error); 1672 } 1673 #endif 1674 return (sysctl_handle_opaque(oidp, intrcnt, sintrcnt, req)); 1675 } 1676 1677 SYSCTL_PROC(_hw, OID_AUTO, intrcnt, 1678 CTLTYPE_OPAQUE | CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, 0, 1679 sysctl_intrcnt, "", 1680 "Interrupt Counts"); 1681 1682 #ifdef DDB 1683 /* 1684 * DDB command to dump the interrupt statistics. 1685 */ 1686 DB_SHOW_COMMAND_FLAGS(intrcnt, db_show_intrcnt, DB_CMD_MEMSAFE) 1687 { 1688 u_long *i; 1689 char *cp; 1690 u_int j; 1691 1692 cp = intrnames; 1693 j = 0; 1694 for (i = intrcnt; j < (sintrcnt / sizeof(u_long)) && !db_pager_quit; 1695 i++, j++) { 1696 if (*cp == '\0') 1697 break; 1698 if (*i != 0) 1699 db_printf("%s\t%lu\n", cp, *i); 1700 cp += strlen(cp) + 1; 1701 } 1702 } 1703 #endif 1704