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, u_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, const void *m) 447 { 448 struct intr_event *ie; 449 const 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 mtx_unlock(&event_lock); 545 if (ie->ie_thread != NULL) 546 ithread_destroy(ie->ie_thread); 547 mtx_unlock(&ie->ie_lock); 548 mtx_destroy(&ie->ie_lock); 549 free(ie, M_ITHREAD); 550 return (0); 551 } 552 553 static struct intr_thread * 554 ithread_create(const char *name) 555 { 556 struct intr_thread *ithd; 557 struct thread *td; 558 int error; 559 560 ithd = malloc(sizeof(struct intr_thread), M_ITHREAD, M_WAITOK | M_ZERO); 561 562 error = kproc_kthread_add(ithread_loop, ithd, &intrproc, 563 &td, RFSTOPPED | RFHIGHPID, 564 0, "intr", "%s", name); 565 if (error) 566 panic("kproc_create() failed with %d", error); 567 thread_lock(td); 568 sched_class(td, PRI_ITHD); 569 TD_SET_IWAIT(td); 570 thread_unlock(td); 571 td->td_pflags |= TDP_ITHREAD; 572 ithd->it_thread = td; 573 CTR2(KTR_INTR, "%s: created %s", __func__, name); 574 return (ithd); 575 } 576 577 static void 578 ithread_destroy(struct intr_thread *ithread) 579 { 580 struct intr_event *ie; 581 struct thread *td; 582 583 td = ithread->it_thread; 584 ie = ithread->it_event; 585 586 mtx_assert(&ie->ie_lock, MA_OWNED); 587 588 CTR2(KTR_INTR, "%s: killing %s", __func__, ie->ie_name); 589 590 thread_lock(td); 591 ithread->it_flags |= IT_DEAD; 592 if (TD_AWAITING_INTR(td)) { 593 TD_CLR_IWAIT(td); 594 sched_wakeup(td, SRQ_INTR); 595 } else 596 thread_unlock(td); 597 while (ie->ie_thread != NULL) 598 msleep(ithread, &ie->ie_lock, 0, "ithd_dth", 0); 599 } 600 601 int 602 intr_event_add_handler(struct intr_event *ie, const char *name, 603 driver_filter_t filter, driver_intr_t handler, void *arg, u_char pri, 604 enum intr_type flags, void **cookiep) 605 { 606 struct intr_handler *ih, *temp_ih; 607 struct intr_handler **prevptr; 608 struct intr_thread *it; 609 610 if (ie == NULL || name == NULL || (handler == NULL && filter == NULL)) 611 return (EINVAL); 612 613 /* Allocate and populate an interrupt handler structure. */ 614 ih = malloc(sizeof(struct intr_handler), M_ITHREAD, M_WAITOK | M_ZERO); 615 ih->ih_filter = filter; 616 ih->ih_handler = handler; 617 ih->ih_argument = arg; 618 strlcpy(ih->ih_name, name, sizeof(ih->ih_name)); 619 ih->ih_event = ie; 620 ih->ih_pri = pri; 621 if (flags & INTR_EXCL) 622 ih->ih_flags = IH_EXCLUSIVE; 623 if (flags & INTR_MPSAFE) 624 ih->ih_flags |= IH_MPSAFE; 625 if (flags & INTR_ENTROPY) 626 ih->ih_flags |= IH_ENTROPY; 627 if (flags & INTR_TYPE_NET) 628 ih->ih_flags |= IH_NET; 629 630 /* We can only have one exclusive handler in a event. */ 631 mtx_lock(&ie->ie_lock); 632 if (!CK_SLIST_EMPTY(&ie->ie_handlers)) { 633 if ((flags & INTR_EXCL) || 634 (CK_SLIST_FIRST(&ie->ie_handlers)->ih_flags & IH_EXCLUSIVE)) { 635 mtx_unlock(&ie->ie_lock); 636 free(ih, M_ITHREAD); 637 return (EINVAL); 638 } 639 } 640 641 /* Create a thread if we need one. */ 642 while (ie->ie_thread == NULL && handler != NULL) { 643 if (ie->ie_flags & IE_ADDING_THREAD) 644 msleep(ie, &ie->ie_lock, 0, "ithread", 0); 645 else { 646 ie->ie_flags |= IE_ADDING_THREAD; 647 mtx_unlock(&ie->ie_lock); 648 it = ithread_create("intr: newborn"); 649 mtx_lock(&ie->ie_lock); 650 ie->ie_flags &= ~IE_ADDING_THREAD; 651 ie->ie_thread = it; 652 it->it_event = ie; 653 ithread_update(it); 654 wakeup(ie); 655 } 656 } 657 658 /* Add the new handler to the event in priority order. */ 659 CK_SLIST_FOREACH_PREVPTR(temp_ih, prevptr, &ie->ie_handlers, ih_next) { 660 if (temp_ih->ih_pri > ih->ih_pri) 661 break; 662 } 663 CK_SLIST_INSERT_PREVPTR(prevptr, temp_ih, ih, ih_next); 664 665 intr_event_update(ie); 666 667 CTR3(KTR_INTR, "%s: added %s to %s", __func__, ih->ih_name, 668 ie->ie_name); 669 mtx_unlock(&ie->ie_lock); 670 671 if (cookiep != NULL) 672 *cookiep = ih; 673 return (0); 674 } 675 676 /* 677 * Append a description preceded by a ':' to the name of the specified 678 * interrupt handler. 679 */ 680 int 681 intr_event_describe_handler(struct intr_event *ie, void *cookie, 682 const char *descr) 683 { 684 struct intr_handler *ih; 685 size_t space; 686 char *start; 687 688 mtx_lock(&ie->ie_lock); 689 #ifdef INVARIANTS 690 CK_SLIST_FOREACH(ih, &ie->ie_handlers, ih_next) { 691 if (ih == cookie) 692 break; 693 } 694 if (ih == NULL) { 695 mtx_unlock(&ie->ie_lock); 696 panic("handler %p not found in interrupt event %p", cookie, ie); 697 } 698 #endif 699 ih = cookie; 700 701 /* 702 * Look for an existing description by checking for an 703 * existing ":". This assumes device names do not include 704 * colons. If one is found, prepare to insert the new 705 * description at that point. If one is not found, find the 706 * end of the name to use as the insertion point. 707 */ 708 start = strchr(ih->ih_name, ':'); 709 if (start == NULL) 710 start = strchr(ih->ih_name, 0); 711 712 /* 713 * See if there is enough remaining room in the string for the 714 * description + ":". The "- 1" leaves room for the trailing 715 * '\0'. The "+ 1" accounts for the colon. 716 */ 717 space = sizeof(ih->ih_name) - (start - ih->ih_name) - 1; 718 if (strlen(descr) + 1 > space) { 719 mtx_unlock(&ie->ie_lock); 720 return (ENOSPC); 721 } 722 723 /* Append a colon followed by the description. */ 724 *start = ':'; 725 strcpy(start + 1, descr); 726 intr_event_update(ie); 727 mtx_unlock(&ie->ie_lock); 728 return (0); 729 } 730 731 /* 732 * Return the ie_source field from the intr_event an intr_handler is 733 * associated with. 734 */ 735 void * 736 intr_handler_source(void *cookie) 737 { 738 struct intr_handler *ih; 739 struct intr_event *ie; 740 741 ih = (struct intr_handler *)cookie; 742 if (ih == NULL) 743 return (NULL); 744 ie = ih->ih_event; 745 KASSERT(ie != NULL, 746 ("interrupt handler \"%s\" has a NULL interrupt event", 747 ih->ih_name)); 748 return (ie->ie_source); 749 } 750 751 /* 752 * If intr_event_handle() is running in the ISR context at the time of the call, 753 * then wait for it to complete. 754 */ 755 static void 756 intr_event_barrier(struct intr_event *ie) 757 { 758 int phase; 759 760 mtx_assert(&ie->ie_lock, MA_OWNED); 761 phase = ie->ie_phase; 762 763 /* 764 * Switch phase to direct future interrupts to the other active counter. 765 * Make sure that any preceding stores are visible before the switch. 766 */ 767 KASSERT(ie->ie_active[!phase] == 0, ("idle phase has activity")); 768 atomic_store_rel_int(&ie->ie_phase, !phase); 769 770 /* 771 * This code cooperates with wait-free iteration of ie_handlers 772 * in intr_event_handle. 773 * Make sure that the removal and the phase update are not reordered 774 * with the active count check. 775 * Note that no combination of acquire and release fences can provide 776 * that guarantee as Store->Load sequences can always be reordered. 777 */ 778 atomic_thread_fence_seq_cst(); 779 780 /* 781 * Now wait on the inactive phase. 782 * The acquire fence is needed so that all post-barrier accesses 783 * are after the check. 784 */ 785 while (ie->ie_active[phase] > 0) 786 cpu_spinwait(); 787 atomic_thread_fence_acq(); 788 } 789 790 static void 791 intr_handler_barrier(struct intr_handler *handler) 792 { 793 struct intr_event *ie; 794 795 ie = handler->ih_event; 796 mtx_assert(&ie->ie_lock, MA_OWNED); 797 KASSERT((handler->ih_flags & IH_DEAD) == 0, 798 ("update for a removed handler")); 799 800 if (ie->ie_thread == NULL) { 801 intr_event_barrier(ie); 802 return; 803 } 804 if ((handler->ih_flags & IH_CHANGED) == 0) { 805 handler->ih_flags |= IH_CHANGED; 806 intr_event_schedule_thread(ie, NULL); 807 } 808 while ((handler->ih_flags & IH_CHANGED) != 0) 809 msleep(handler, &ie->ie_lock, 0, "ih_barr", 0); 810 } 811 812 /* 813 * Sleep until an ithread finishes executing an interrupt handler. 814 * 815 * XXX Doesn't currently handle interrupt filters or fast interrupt 816 * handlers. This is intended for LinuxKPI drivers only. 817 * Do not use in BSD code. 818 */ 819 void 820 _intr_drain(int irq) 821 { 822 struct intr_event *ie; 823 struct intr_thread *ithd; 824 struct thread *td; 825 826 ie = intr_lookup(irq); 827 if (ie == NULL) 828 return; 829 if (ie->ie_thread == NULL) 830 return; 831 ithd = ie->ie_thread; 832 td = ithd->it_thread; 833 /* 834 * We set the flag and wait for it to be cleared to avoid 835 * long delays with potentially busy interrupt handlers 836 * were we to only sample TD_AWAITING_INTR() every tick. 837 */ 838 thread_lock(td); 839 if (!TD_AWAITING_INTR(td)) { 840 ithd->it_flags |= IT_WAIT; 841 while (ithd->it_flags & IT_WAIT) { 842 thread_unlock(td); 843 pause("idrain", 1); 844 thread_lock(td); 845 } 846 } 847 thread_unlock(td); 848 return; 849 } 850 851 int 852 intr_event_remove_handler(void *cookie) 853 { 854 struct intr_handler *handler = (struct intr_handler *)cookie; 855 struct intr_event *ie; 856 struct intr_handler *ih; 857 struct intr_handler **prevptr; 858 859 if (handler == NULL) 860 return (EINVAL); 861 ie = handler->ih_event; 862 KASSERT(ie != NULL, 863 ("interrupt handler \"%s\" has a NULL interrupt event", 864 handler->ih_name)); 865 866 mtx_lock(&ie->ie_lock); 867 CTR3(KTR_INTR, "%s: removing %s from %s", __func__, handler->ih_name, 868 ie->ie_name); 869 CK_SLIST_FOREACH_PREVPTR(ih, prevptr, &ie->ie_handlers, ih_next) { 870 if (ih == handler) 871 break; 872 } 873 if (ih == NULL) { 874 panic("interrupt handler \"%s\" not found in " 875 "interrupt event \"%s\"", handler->ih_name, ie->ie_name); 876 } 877 878 if (ie->ie_thread == NULL) { 879 /* 880 * If there is no ithread, then directly remove the handler. 881 * Note that intr_event_handle() iterates ie_handlers in a 882 * lock-less fashion, so care needs to be taken to keep 883 * ie_handlers consistent and to free the removed handler only 884 * when ie_handlers is quiescent. 885 */ 886 CK_SLIST_REMOVE_PREVPTR(prevptr, ih, ih_next); 887 intr_event_barrier(ie); 888 } else { 889 /* 890 * Let the interrupt thread do the job. The interrupt source is 891 * disabled when the interrupt thread is running, so it does not 892 * have to worry about interaction with intr_event_handle(). 893 */ 894 KASSERT((handler->ih_flags & IH_DEAD) == 0, 895 ("duplicate handle remove")); 896 handler->ih_flags |= IH_DEAD; 897 intr_event_schedule_thread(ie, NULL); 898 while (handler->ih_flags & IH_DEAD) 899 msleep(handler, &ie->ie_lock, 0, "iev_rmh", 0); 900 } 901 intr_event_update(ie); 902 mtx_unlock(&ie->ie_lock); 903 free(handler, M_ITHREAD); 904 return (0); 905 } 906 907 int 908 intr_event_suspend_handler(void *cookie) 909 { 910 struct intr_handler *handler = (struct intr_handler *)cookie; 911 struct intr_event *ie; 912 913 if (handler == NULL) 914 return (EINVAL); 915 ie = handler->ih_event; 916 KASSERT(ie != NULL, 917 ("interrupt handler \"%s\" has a NULL interrupt event", 918 handler->ih_name)); 919 mtx_lock(&ie->ie_lock); 920 handler->ih_flags |= IH_SUSP; 921 intr_handler_barrier(handler); 922 mtx_unlock(&ie->ie_lock); 923 return (0); 924 } 925 926 int 927 intr_event_resume_handler(void *cookie) 928 { 929 struct intr_handler *handler = (struct intr_handler *)cookie; 930 struct intr_event *ie; 931 932 if (handler == NULL) 933 return (EINVAL); 934 ie = handler->ih_event; 935 KASSERT(ie != NULL, 936 ("interrupt handler \"%s\" has a NULL interrupt event", 937 handler->ih_name)); 938 939 /* 940 * intr_handler_barrier() acts not only as a barrier, 941 * it also allows to check for any pending interrupts. 942 */ 943 mtx_lock(&ie->ie_lock); 944 handler->ih_flags &= ~IH_SUSP; 945 intr_handler_barrier(handler); 946 mtx_unlock(&ie->ie_lock); 947 return (0); 948 } 949 950 static int 951 intr_event_schedule_thread(struct intr_event *ie, struct trapframe *frame) 952 { 953 struct intr_entropy entropy; 954 struct intr_thread *it; 955 struct thread *td; 956 struct thread *ctd; 957 958 /* 959 * If no ithread or no handlers, then we have a stray interrupt. 960 */ 961 if (ie == NULL || CK_SLIST_EMPTY(&ie->ie_handlers) || 962 ie->ie_thread == NULL) 963 return (EINVAL); 964 965 ctd = curthread; 966 it = ie->ie_thread; 967 td = it->it_thread; 968 969 /* 970 * If any of the handlers for this ithread claim to be good 971 * sources of entropy, then gather some. 972 */ 973 if (ie->ie_hflags & IH_ENTROPY) { 974 entropy.event = (uintptr_t)ie; 975 entropy.td = ctd; 976 random_harvest_queue(&entropy, sizeof(entropy), RANDOM_INTERRUPT); 977 } 978 979 KASSERT(td->td_proc != NULL, ("ithread %s has no process", ie->ie_name)); 980 981 /* 982 * Set it_need to tell the thread to keep running if it is already 983 * running. Then, lock the thread and see if we actually need to 984 * put it on the runqueue. 985 * 986 * Use store_rel to arrange that the store to ih_need in 987 * swi_sched() is before the store to it_need and prepare for 988 * transfer of this order to loads in the ithread. 989 */ 990 atomic_store_rel_int(&it->it_need, 1); 991 thread_lock(td); 992 if (TD_AWAITING_INTR(td)) { 993 #ifdef HWPMC_HOOKS 994 it->it_waiting = 0; 995 if (PMC_HOOK_INSTALLED_ANY()) 996 PMC_SOFT_CALL_INTR_HLPR(schedule, frame); 997 #endif 998 CTR3(KTR_INTR, "%s: schedule pid %d (%s)", __func__, td->td_proc->p_pid, 999 td->td_name); 1000 TD_CLR_IWAIT(td); 1001 sched_wakeup(td, SRQ_INTR); 1002 } else { 1003 #ifdef HWPMC_HOOKS 1004 it->it_waiting++; 1005 if (PMC_HOOK_INSTALLED_ANY() && 1006 (it->it_waiting >= intr_hwpmc_waiting_report_threshold)) 1007 PMC_SOFT_CALL_INTR_HLPR(waiting, frame); 1008 #endif 1009 CTR5(KTR_INTR, "%s: pid %d (%s): it_need %d, state %d", 1010 __func__, td->td_proc->p_pid, td->td_name, it->it_need, TD_GET_STATE(td)); 1011 thread_unlock(td); 1012 } 1013 1014 return (0); 1015 } 1016 1017 /* 1018 * Allow interrupt event binding for software interrupt handlers -- a no-op, 1019 * since interrupts are generated in software rather than being directed by 1020 * a PIC. 1021 */ 1022 static int 1023 swi_assign_cpu(void *arg, int cpu) 1024 { 1025 1026 return (0); 1027 } 1028 1029 /* 1030 * Add a software interrupt handler to a specified event. If a given event 1031 * is not specified, then a new event is created. 1032 */ 1033 int 1034 swi_add(struct intr_event **eventp, const char *name, driver_intr_t handler, 1035 void *arg, int pri, enum intr_type flags, void **cookiep) 1036 { 1037 struct intr_event *ie; 1038 int error = 0; 1039 1040 if (flags & INTR_ENTROPY) 1041 return (EINVAL); 1042 1043 ie = (eventp != NULL) ? *eventp : NULL; 1044 1045 if (ie != NULL) { 1046 if (!(ie->ie_flags & IE_SOFT)) 1047 return (EINVAL); 1048 } else { 1049 error = intr_event_create(&ie, NULL, IE_SOFT, 0, 1050 NULL, NULL, NULL, swi_assign_cpu, "swi%d:", pri); 1051 if (error) 1052 return (error); 1053 if (eventp != NULL) 1054 *eventp = ie; 1055 } 1056 if (handler != NULL) { 1057 error = intr_event_add_handler(ie, name, NULL, handler, arg, 1058 PI_SWI(pri), flags, cookiep); 1059 } 1060 return (error); 1061 } 1062 1063 /* 1064 * Schedule a software interrupt thread. 1065 */ 1066 void 1067 swi_sched(void *cookie, int flags) 1068 { 1069 struct intr_handler *ih = (struct intr_handler *)cookie; 1070 struct intr_event *ie = ih->ih_event; 1071 struct intr_entropy entropy; 1072 int error __unused; 1073 1074 CTR3(KTR_INTR, "swi_sched: %s %s need=%d", ie->ie_name, ih->ih_name, 1075 ih->ih_need); 1076 1077 if ((flags & SWI_FROMNMI) == 0) { 1078 entropy.event = (uintptr_t)ih; 1079 entropy.td = curthread; 1080 random_harvest_queue(&entropy, sizeof(entropy), RANDOM_SWI); 1081 } 1082 1083 /* 1084 * Set ih_need for this handler so that if the ithread is already 1085 * running it will execute this handler on the next pass. Otherwise, 1086 * it will execute it the next time it runs. 1087 */ 1088 ih->ih_need = 1; 1089 1090 if (flags & SWI_DELAY) 1091 return; 1092 1093 if (flags & SWI_FROMNMI) { 1094 #if defined(SMP) && (defined(__i386__) || defined(__amd64__)) 1095 KASSERT(ie == clk_intr_event, 1096 ("SWI_FROMNMI used not with clk_intr_event")); 1097 ipi_self_from_nmi(IPI_SWI); 1098 #endif 1099 } else { 1100 VM_CNT_INC(v_soft); 1101 error = intr_event_schedule_thread(ie, NULL); 1102 KASSERT(error == 0, ("stray software interrupt")); 1103 } 1104 } 1105 1106 /* 1107 * Remove a software interrupt handler. Currently this code does not 1108 * remove the associated interrupt event if it becomes empty. Calling code 1109 * may do so manually via intr_event_destroy(), but that's not really 1110 * an optimal interface. 1111 */ 1112 int 1113 swi_remove(void *cookie) 1114 { 1115 1116 return (intr_event_remove_handler(cookie)); 1117 } 1118 1119 static void 1120 intr_event_execute_handlers(struct proc *p, struct intr_event *ie) 1121 { 1122 struct intr_handler *ih, *ihn, *ihp; 1123 1124 ihp = NULL; 1125 CK_SLIST_FOREACH_SAFE(ih, &ie->ie_handlers, ih_next, ihn) { 1126 /* 1127 * If this handler is marked for death, remove it from 1128 * the list of handlers and wake up the sleeper. 1129 */ 1130 if (ih->ih_flags & IH_DEAD) { 1131 mtx_lock(&ie->ie_lock); 1132 if (ihp == NULL) 1133 CK_SLIST_REMOVE_HEAD(&ie->ie_handlers, ih_next); 1134 else 1135 CK_SLIST_REMOVE_AFTER(ihp, ih_next); 1136 ih->ih_flags &= ~IH_DEAD; 1137 wakeup(ih); 1138 mtx_unlock(&ie->ie_lock); 1139 continue; 1140 } 1141 1142 /* 1143 * Now that we know that the current element won't be removed 1144 * update the previous element. 1145 */ 1146 ihp = ih; 1147 1148 if ((ih->ih_flags & IH_CHANGED) != 0) { 1149 mtx_lock(&ie->ie_lock); 1150 ih->ih_flags &= ~IH_CHANGED; 1151 wakeup(ih); 1152 mtx_unlock(&ie->ie_lock); 1153 } 1154 1155 /* Skip filter only handlers */ 1156 if (ih->ih_handler == NULL) 1157 continue; 1158 1159 /* Skip suspended handlers */ 1160 if ((ih->ih_flags & IH_SUSP) != 0) 1161 continue; 1162 1163 /* 1164 * For software interrupt threads, we only execute 1165 * handlers that have their need flag set. Hardware 1166 * interrupt threads always invoke all of their handlers. 1167 * 1168 * ih_need can only be 0 or 1. Failed cmpset below 1169 * means that there is no request to execute handlers, 1170 * so a retry of the cmpset is not needed. 1171 */ 1172 if ((ie->ie_flags & IE_SOFT) != 0 && 1173 atomic_cmpset_int(&ih->ih_need, 1, 0) == 0) 1174 continue; 1175 1176 /* Execute this handler. */ 1177 CTR6(KTR_INTR, "%s: pid %d exec %p(%p) for %s flg=%x", 1178 __func__, p->p_pid, (void *)ih->ih_handler, 1179 ih->ih_argument, ih->ih_name, ih->ih_flags); 1180 1181 if (!(ih->ih_flags & IH_MPSAFE)) 1182 mtx_lock(&Giant); 1183 ih->ih_handler(ih->ih_argument); 1184 if (!(ih->ih_flags & IH_MPSAFE)) 1185 mtx_unlock(&Giant); 1186 } 1187 } 1188 1189 static void 1190 ithread_execute_handlers(struct proc *p, struct intr_event *ie) 1191 { 1192 1193 /* Interrupt handlers should not sleep. */ 1194 if (!(ie->ie_flags & IE_SOFT)) 1195 THREAD_NO_SLEEPING(); 1196 intr_event_execute_handlers(p, ie); 1197 if (!(ie->ie_flags & IE_SOFT)) 1198 THREAD_SLEEPING_OK(); 1199 1200 /* 1201 * Interrupt storm handling: 1202 * 1203 * If this interrupt source is currently storming, then throttle 1204 * it to only fire the handler once per clock tick. 1205 * 1206 * If this interrupt source is not currently storming, but the 1207 * number of back to back interrupts exceeds the storm threshold, 1208 * then enter storming mode. 1209 */ 1210 if (__predict_false(intr_storm_threshold != 0 && 1211 ie->ie_count >= intr_storm_threshold && 1212 (ie->ie_flags & IE_SOFT) == 0)) { 1213 /* Report the message only once every second. */ 1214 if (ppsratecheck(&ie->ie_warntm, &ie->ie_warncnt, 1)) { 1215 printf( 1216 "interrupt storm detected on \"%s\"; throttling interrupt source\n", 1217 ie->ie_name); 1218 } 1219 pause("istorm", 1); 1220 } else 1221 ie->ie_count++; 1222 1223 /* 1224 * Now that all the handlers have had a chance to run, reenable 1225 * the interrupt source. 1226 */ 1227 if (ie->ie_post_ithread != NULL) 1228 ie->ie_post_ithread(ie->ie_source); 1229 } 1230 1231 /* 1232 * This is the main code for interrupt threads. 1233 */ 1234 static void 1235 ithread_loop(void *arg) 1236 { 1237 struct epoch_tracker et; 1238 struct intr_thread *ithd; 1239 struct intr_event *ie; 1240 struct thread *td; 1241 struct proc *p; 1242 int epoch_count; 1243 bool needs_epoch; 1244 1245 td = curthread; 1246 p = td->td_proc; 1247 ithd = (struct intr_thread *)arg; 1248 KASSERT(ithd->it_thread == td, 1249 ("%s: ithread and proc linkage out of sync", __func__)); 1250 ie = ithd->it_event; 1251 ie->ie_count = 0; 1252 1253 /* 1254 * As long as we have interrupts outstanding, go through the 1255 * list of handlers, giving each one a go at it. 1256 */ 1257 for (;;) { 1258 /* 1259 * If we are an orphaned thread, then just die. 1260 */ 1261 if (__predict_false((ithd->it_flags & IT_DEAD) != 0)) { 1262 CTR3(KTR_INTR, "%s: pid %d (%s) exiting", __func__, 1263 p->p_pid, td->td_name); 1264 mtx_lock(&ie->ie_lock); 1265 ie->ie_thread = NULL; 1266 wakeup(ithd); 1267 mtx_unlock(&ie->ie_lock); 1268 1269 free(ithd, M_ITHREAD); 1270 kthread_exit(); 1271 } 1272 1273 /* 1274 * Service interrupts. If another interrupt arrives while 1275 * we are running, it will set it_need to note that we 1276 * should make another pass. 1277 * 1278 * The load_acq part of the following cmpset ensures 1279 * that the load of ih_need in ithread_execute_handlers() 1280 * is ordered after the load of it_need here. 1281 */ 1282 needs_epoch = 1283 (atomic_load_int(&ie->ie_hflags) & IH_NET) != 0; 1284 if (needs_epoch) { 1285 epoch_count = 0; 1286 NET_EPOCH_ENTER(et); 1287 } 1288 while (atomic_cmpset_acq_int(&ithd->it_need, 1, 0) != 0) { 1289 ithread_execute_handlers(p, ie); 1290 if (needs_epoch && 1291 ++epoch_count >= intr_epoch_batch) { 1292 NET_EPOCH_EXIT(et); 1293 epoch_count = 0; 1294 NET_EPOCH_ENTER(et); 1295 } 1296 } 1297 if (needs_epoch) 1298 NET_EPOCH_EXIT(et); 1299 WITNESS_WARN(WARN_PANIC, NULL, "suspending ithread"); 1300 mtx_assert(&Giant, MA_NOTOWNED); 1301 1302 /* 1303 * Processed all our interrupts. Now get the sched 1304 * lock. This may take a while and it_need may get 1305 * set again, so we have to check it again. 1306 */ 1307 thread_lock(td); 1308 if (atomic_load_acq_int(&ithd->it_need) == 0 && 1309 (ithd->it_flags & (IT_DEAD | IT_WAIT)) == 0) { 1310 TD_SET_IWAIT(td); 1311 ie->ie_count = 0; 1312 mi_switch(SW_VOL | SWT_IWAIT); 1313 } else if ((ithd->it_flags & IT_WAIT) != 0) { 1314 ithd->it_flags &= ~IT_WAIT; 1315 thread_unlock(td); 1316 wakeup(ithd); 1317 } else 1318 thread_unlock(td); 1319 } 1320 } 1321 1322 /* 1323 * Main interrupt handling body. 1324 * 1325 * Input: 1326 * o ie: the event connected to this interrupt. 1327 -------------------------------------------------------------------------------- 1328 * o frame: the current trap frame. If the client interrupt 1329 * handler needs this frame, they should get it 1330 * via curthread->td_intr_frame. 1331 * 1332 * Return value: 1333 * o 0: everything ok. 1334 * o EINVAL: stray interrupt. 1335 */ 1336 int 1337 intr_event_handle(struct intr_event *ie, struct trapframe *frame) 1338 { 1339 struct intr_handler *ih; 1340 struct trapframe *oldframe; 1341 struct thread *td; 1342 int phase; 1343 int ret; 1344 bool filter, thread; 1345 1346 td = curthread; 1347 1348 #ifdef KSTACK_USAGE_PROF 1349 intr_prof_stack_use(td, frame); 1350 #endif 1351 1352 /* An interrupt with no event or handlers is a stray interrupt. */ 1353 if (ie == NULL || CK_SLIST_EMPTY(&ie->ie_handlers)) 1354 return (EINVAL); 1355 1356 /* 1357 * Execute fast interrupt handlers directly. 1358 */ 1359 td->td_intr_nesting_level++; 1360 filter = false; 1361 thread = false; 1362 ret = 0; 1363 critical_enter(); 1364 oldframe = td->td_intr_frame; 1365 td->td_intr_frame = frame; 1366 1367 phase = ie->ie_phase; 1368 atomic_add_int(&ie->ie_active[phase], 1); 1369 1370 /* 1371 * This fence is required to ensure that no later loads are 1372 * re-ordered before the ie_active store. 1373 */ 1374 atomic_thread_fence_seq_cst(); 1375 1376 CK_SLIST_FOREACH(ih, &ie->ie_handlers, ih_next) { 1377 if ((ih->ih_flags & IH_SUSP) != 0) 1378 continue; 1379 if ((ie->ie_flags & IE_SOFT) != 0 && ih->ih_need == 0) 1380 continue; 1381 if (ih->ih_filter == NULL) { 1382 thread = true; 1383 continue; 1384 } 1385 CTR4(KTR_INTR, "%s: exec %p(%p) for %s", __func__, 1386 ih->ih_filter, ih->ih_argument, ih->ih_name); 1387 ret = ih->ih_filter(ih->ih_argument); 1388 #ifdef HWPMC_HOOKS 1389 PMC_SOFT_CALL_TF( , , intr, all, frame); 1390 #endif 1391 KASSERT(ret == FILTER_STRAY || 1392 ((ret & (FILTER_SCHEDULE_THREAD | FILTER_HANDLED)) != 0 && 1393 (ret & ~(FILTER_SCHEDULE_THREAD | FILTER_HANDLED)) == 0), 1394 ("%s: incorrect return value %#x from %s", __func__, ret, 1395 ih->ih_name)); 1396 filter = filter || ret == FILTER_HANDLED; 1397 #ifdef HWPMC_HOOKS 1398 if (ret & FILTER_SCHEDULE_THREAD) 1399 PMC_SOFT_CALL_TF( , , intr, ithread, frame); 1400 else if (ret & FILTER_HANDLED) 1401 PMC_SOFT_CALL_TF( , , intr, filter, frame); 1402 else if (ret == FILTER_STRAY) 1403 PMC_SOFT_CALL_TF( , , intr, stray, frame); 1404 #endif 1405 1406 /* 1407 * Wrapper handler special handling: 1408 * 1409 * in some particular cases (like pccard and pccbb), 1410 * the _real_ device handler is wrapped in a couple of 1411 * functions - a filter wrapper and an ithread wrapper. 1412 * In this case (and just in this case), the filter wrapper 1413 * could ask the system to schedule the ithread and mask 1414 * the interrupt source if the wrapped handler is composed 1415 * of just an ithread handler. 1416 * 1417 * TODO: write a generic wrapper to avoid people rolling 1418 * their own. 1419 */ 1420 if (!thread) { 1421 if (ret == FILTER_SCHEDULE_THREAD) 1422 thread = true; 1423 } 1424 } 1425 atomic_add_rel_int(&ie->ie_active[phase], -1); 1426 1427 td->td_intr_frame = oldframe; 1428 1429 if (thread) { 1430 if (ie->ie_pre_ithread != NULL) 1431 ie->ie_pre_ithread(ie->ie_source); 1432 } else { 1433 if (ie->ie_post_filter != NULL) 1434 ie->ie_post_filter(ie->ie_source); 1435 } 1436 1437 /* Schedule the ithread if needed. */ 1438 if (thread) { 1439 int error __unused; 1440 1441 error = intr_event_schedule_thread(ie, frame); 1442 KASSERT(error == 0, ("bad stray interrupt")); 1443 } 1444 critical_exit(); 1445 td->td_intr_nesting_level--; 1446 #ifdef notyet 1447 /* The interrupt is not aknowledged by any filter and has no ithread. */ 1448 if (!thread && !filter) 1449 return (EINVAL); 1450 #endif 1451 return (0); 1452 } 1453 1454 #ifdef DDB 1455 /* 1456 * Dump details about an interrupt handler 1457 */ 1458 static void 1459 db_dump_intrhand(struct intr_handler *ih) 1460 { 1461 int comma; 1462 1463 db_printf("\t%-10s ", ih->ih_name); 1464 switch (ih->ih_pri) { 1465 case PI_REALTIME: 1466 db_printf("CLK "); 1467 break; 1468 case PI_INTR: 1469 db_printf("INTR"); 1470 break; 1471 default: 1472 if (ih->ih_pri >= PI_SOFT) 1473 db_printf("SWI "); 1474 else 1475 db_printf("%4u", ih->ih_pri); 1476 break; 1477 } 1478 db_printf(" "); 1479 if (ih->ih_filter != NULL) { 1480 db_printf("[F]"); 1481 db_printsym((uintptr_t)ih->ih_filter, DB_STGY_PROC); 1482 } 1483 if (ih->ih_handler != NULL) { 1484 if (ih->ih_filter != NULL) 1485 db_printf(","); 1486 db_printf("[H]"); 1487 db_printsym((uintptr_t)ih->ih_handler, DB_STGY_PROC); 1488 } 1489 db_printf("(%p)", ih->ih_argument); 1490 if (ih->ih_need || 1491 (ih->ih_flags & (IH_EXCLUSIVE | IH_ENTROPY | IH_DEAD | 1492 IH_MPSAFE)) != 0) { 1493 db_printf(" {"); 1494 comma = 0; 1495 if (ih->ih_flags & IH_EXCLUSIVE) { 1496 if (comma) 1497 db_printf(", "); 1498 db_printf("EXCL"); 1499 comma = 1; 1500 } 1501 if (ih->ih_flags & IH_ENTROPY) { 1502 if (comma) 1503 db_printf(", "); 1504 db_printf("ENTROPY"); 1505 comma = 1; 1506 } 1507 if (ih->ih_flags & IH_DEAD) { 1508 if (comma) 1509 db_printf(", "); 1510 db_printf("DEAD"); 1511 comma = 1; 1512 } 1513 if (ih->ih_flags & IH_MPSAFE) { 1514 if (comma) 1515 db_printf(", "); 1516 db_printf("MPSAFE"); 1517 comma = 1; 1518 } 1519 if (ih->ih_need) { 1520 if (comma) 1521 db_printf(", "); 1522 db_printf("NEED"); 1523 } 1524 db_printf("}"); 1525 } 1526 db_printf("\n"); 1527 } 1528 1529 /* 1530 * Dump details about a event. 1531 */ 1532 void 1533 db_dump_intr_event(struct intr_event *ie, int handlers) 1534 { 1535 struct intr_handler *ih; 1536 struct intr_thread *it; 1537 int comma; 1538 1539 db_printf("%s ", ie->ie_fullname); 1540 it = ie->ie_thread; 1541 if (it != NULL) 1542 db_printf("(pid %d)", it->it_thread->td_proc->p_pid); 1543 else 1544 db_printf("(no thread)"); 1545 if ((ie->ie_flags & (IE_SOFT | IE_ADDING_THREAD)) != 0 || 1546 (it != NULL && it->it_need)) { 1547 db_printf(" {"); 1548 comma = 0; 1549 if (ie->ie_flags & IE_SOFT) { 1550 db_printf("SOFT"); 1551 comma = 1; 1552 } 1553 if (ie->ie_flags & IE_ADDING_THREAD) { 1554 if (comma) 1555 db_printf(", "); 1556 db_printf("ADDING_THREAD"); 1557 comma = 1; 1558 } 1559 if (it != NULL && it->it_need) { 1560 if (comma) 1561 db_printf(", "); 1562 db_printf("NEED"); 1563 } 1564 db_printf("}"); 1565 } 1566 db_printf("\n"); 1567 1568 if (handlers) 1569 CK_SLIST_FOREACH(ih, &ie->ie_handlers, ih_next) 1570 db_dump_intrhand(ih); 1571 } 1572 1573 /* 1574 * Dump data about interrupt handlers 1575 */ 1576 DB_SHOW_COMMAND_FLAGS(intr, db_show_intr, DB_CMD_MEMSAFE) 1577 { 1578 struct intr_event *ie; 1579 int all, verbose; 1580 1581 verbose = strchr(modif, 'v') != NULL; 1582 all = strchr(modif, 'a') != NULL; 1583 TAILQ_FOREACH(ie, &event_list, ie_list) { 1584 if (!all && CK_SLIST_EMPTY(&ie->ie_handlers)) 1585 continue; 1586 db_dump_intr_event(ie, verbose); 1587 if (db_pager_quit) 1588 break; 1589 } 1590 } 1591 #endif /* DDB */ 1592 1593 /* 1594 * Start standard software interrupt threads 1595 */ 1596 static void 1597 start_softintr(void *dummy) 1598 { 1599 1600 if (swi_add(&clk_intr_event, "clk", NULL, NULL, SWI_CLOCK, 1601 INTR_MPSAFE, NULL)) 1602 panic("died while creating clk swi ithread"); 1603 } 1604 SYSINIT(start_softintr, SI_SUB_SOFTINTR, SI_ORDER_FIRST, start_softintr, 1605 NULL); 1606 1607 /* 1608 * Sysctls used by systat and others: hw.intrnames and hw.intrcnt. 1609 * The data for this machine dependent, and the declarations are in machine 1610 * dependent code. The layout of intrnames and intrcnt however is machine 1611 * independent. 1612 * 1613 * We do not know the length of intrcnt and intrnames at compile time, so 1614 * calculate things at run time. 1615 */ 1616 static int 1617 sysctl_intrnames(SYSCTL_HANDLER_ARGS) 1618 { 1619 return (sysctl_handle_opaque(oidp, intrnames, sintrnames, req)); 1620 } 1621 1622 SYSCTL_PROC(_hw, OID_AUTO, intrnames, 1623 CTLTYPE_OPAQUE | CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, 0, 1624 sysctl_intrnames, "", 1625 "Interrupt Names"); 1626 1627 static int 1628 sysctl_intrcnt(SYSCTL_HANDLER_ARGS) 1629 { 1630 #ifdef SCTL_MASK32 1631 uint32_t *intrcnt32; 1632 unsigned i; 1633 int error; 1634 1635 if (req->flags & SCTL_MASK32) { 1636 if (!req->oldptr) 1637 return (sysctl_handle_opaque(oidp, NULL, sintrcnt / 2, req)); 1638 intrcnt32 = malloc(sintrcnt / 2, M_TEMP, M_NOWAIT); 1639 if (intrcnt32 == NULL) 1640 return (ENOMEM); 1641 for (i = 0; i < sintrcnt / sizeof (u_long); i++) 1642 intrcnt32[i] = intrcnt[i]; 1643 error = sysctl_handle_opaque(oidp, intrcnt32, sintrcnt / 2, req); 1644 free(intrcnt32, M_TEMP); 1645 return (error); 1646 } 1647 #endif 1648 return (sysctl_handle_opaque(oidp, intrcnt, sintrcnt, req)); 1649 } 1650 1651 SYSCTL_PROC(_hw, OID_AUTO, intrcnt, 1652 CTLTYPE_OPAQUE | CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, 0, 1653 sysctl_intrcnt, "", 1654 "Interrupt Counts"); 1655 1656 #ifdef DDB 1657 /* 1658 * DDB command to dump the interrupt statistics. 1659 */ 1660 DB_SHOW_COMMAND_FLAGS(intrcnt, db_show_intrcnt, DB_CMD_MEMSAFE) 1661 { 1662 u_long *i; 1663 char *cp; 1664 u_int j; 1665 1666 cp = intrnames; 1667 j = 0; 1668 for (i = intrcnt; j < (sintrcnt / sizeof(u_long)) && !db_pager_quit; 1669 i++, j++) { 1670 if (*cp == '\0') 1671 break; 1672 if (*i != 0) 1673 db_printf("%s\t%lu\n", cp, *i); 1674 cp += strlen(cp) + 1; 1675 } 1676 } 1677 #endif 1678