The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/kern/kern_intr.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * Copyright (c) 2003 Matthew Dillon <dillon@backplane.com> All rights reserved.
    3  * Copyright (c) 1997, Stefan Esser <se@freebsd.org> All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  * 1. Redistributions of source code must retain the above copyright
    9  *    notice unmodified, this list of conditions, and the following
   10  *    disclaimer.
   11  * 2. Redistributions in binary form must reproduce the above copyright
   12  *    notice, this list of conditions and the following disclaimer in the
   13  *    documentation and/or other materials provided with the distribution.
   14  *
   15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   17  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   18  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   19  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   20  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   22  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   24  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   25  *
   26  * $FreeBSD: src/sys/kern/kern_intr.c,v 1.24.2.1 2001/10/14 20:05:50 luigi Exp $
   27  *
   28  */
   29 
   30 #include <sys/param.h>
   31 #include <sys/systm.h>
   32 #include <sys/malloc.h>
   33 #include <sys/kernel.h>
   34 #include <sys/sysctl.h>
   35 #include <sys/thread.h>
   36 #include <sys/proc.h>
   37 #include <sys/random.h>
   38 #include <sys/serialize.h>
   39 #include <sys/interrupt.h>
   40 #include <sys/bus.h>
   41 #include <sys/machintr.h>
   42 
   43 #include <machine/frame.h>
   44 
   45 #include <sys/thread2.h>
   46 #include <sys/mplock2.h>
   47 
   48 struct intr_info;
   49 
   50 typedef struct intrec {
   51     struct intrec *next;
   52     struct intr_info *info;
   53     inthand2_t  *handler;
   54     void        *argument;
   55     char        *name;
   56     int         intr;
   57     int         intr_flags;
   58     struct lwkt_serialize *serializer;
   59 } *intrec_t;
   60 
   61 struct intr_info {
   62         intrec_t        i_reclist;
   63         struct thread   *i_thread;      /* don't embed struct thread */
   64         struct random_softc i_random;
   65         int             i_running;
   66         long            i_count;        /* interrupts dispatched */
   67         int             i_mplock_required;
   68         int             i_fast;
   69         int             i_slow;
   70         int             i_state;
   71         int             i_errorticks;
   72         unsigned long   i_straycount;
   73         int             i_cpuid;
   74         int             i_intr;
   75 };
   76 
   77 static struct intr_info intr_info_ary[MAXCPU][MAX_INTS];
   78 static struct intr_info *swi_info_ary[MAX_SOFTINTS];
   79 
   80 static int max_installed_hard_intr[MAXCPU];
   81 
   82 #define EMERGENCY_INTR_POLLING_FREQ_MAX 20000
   83 
   84 /*
   85  * Assert that callers into interrupt handlers don't return with
   86  * dangling tokens, spinlocks, or mp locks.
   87  */
   88 #ifdef INVARIANTS
   89 
   90 #define TD_INVARIANTS_DECLARE   \
   91         int spincount;          \
   92         lwkt_tokref_t curstop
   93 
   94 #define TD_INVARIANTS_GET(td)                                   \
   95         do {                                                    \
   96                 spincount = (td)->td_gd->gd_spinlocks;          \
   97                 curstop = (td)->td_toks_stop;                   \
   98         } while(0)
   99 
  100 #define TD_INVARIANTS_TEST(td, name)                                    \
  101         do {                                                            \
  102                 KASSERT(spincount == (td)->td_gd->gd_spinlocks,         \
  103                         ("spincount mismatch after interrupt handler %s", \
  104                         name));                                         \
  105                 KASSERT(curstop == (td)->td_toks_stop,                  \
  106                         ("token count mismatch after interrupt handler %s", \
  107                         name));                                         \
  108         } while(0)
  109 
  110 #else
  111 
  112 /* !INVARIANTS */
  113 
  114 #define TD_INVARIANTS_DECLARE
  115 #define TD_INVARIANTS_GET(td)
  116 #define TD_INVARIANTS_TEST(td, name)
  117 
  118 #endif /* ndef INVARIANTS */
  119 
  120 static int sysctl_emergency_freq(SYSCTL_HANDLER_ARGS);
  121 static int sysctl_emergency_enable(SYSCTL_HANDLER_ARGS);
  122 static void emergency_intr_timer_callback(systimer_t, int, struct intrframe *);
  123 static void ithread_handler(void *arg);
  124 static void ithread_emergency(void *arg);
  125 static void report_stray_interrupt(struct intr_info *info, const char *func);
  126 static void int_moveto_destcpu(int *, int);
  127 static void int_moveto_origcpu(int, int);
  128 static void sched_ithd_intern(struct intr_info *info);
  129 
  130 static struct systimer emergency_intr_timer[MAXCPU];
  131 static struct thread emergency_intr_thread[MAXCPU];
  132 
  133 #define ISTATE_NOTHREAD         0
  134 #define ISTATE_NORMAL           1
  135 #define ISTATE_LIVELOCKED       2
  136 
  137 static int livelock_limit = 40000;
  138 static int livelock_lowater = 20000;
  139 static int livelock_debug = -1;
  140 SYSCTL_INT(_kern, OID_AUTO, livelock_limit,
  141         CTLFLAG_RW, &livelock_limit, 0, "Livelock interrupt rate limit");
  142 SYSCTL_INT(_kern, OID_AUTO, livelock_lowater,
  143         CTLFLAG_RW, &livelock_lowater, 0, "Livelock low-water mark restore");
  144 SYSCTL_INT(_kern, OID_AUTO, livelock_debug,
  145         CTLFLAG_RW, &livelock_debug, 0, "Livelock debug intr#");
  146 
  147 static int emergency_intr_enable = 0;   /* emergency interrupt polling */
  148 TUNABLE_INT("kern.emergency_intr_enable", &emergency_intr_enable);
  149 SYSCTL_PROC(_kern, OID_AUTO, emergency_intr_enable, CTLTYPE_INT | CTLFLAG_RW,
  150         0, 0, sysctl_emergency_enable, "I", "Emergency Interrupt Poll Enable");
  151 
  152 static int emergency_intr_freq = 10;    /* emergency polling frequency */
  153 TUNABLE_INT("kern.emergency_intr_freq", &emergency_intr_freq);
  154 SYSCTL_PROC(_kern, OID_AUTO, emergency_intr_freq, CTLTYPE_INT | CTLFLAG_RW,
  155         0, 0, sysctl_emergency_freq, "I", "Emergency Interrupt Poll Frequency");
  156 
  157 /*
  158  * Sysctl support routines
  159  */
  160 static int
  161 sysctl_emergency_enable(SYSCTL_HANDLER_ARGS)
  162 {
  163         int error, enabled, cpuid, freq;
  164 
  165         enabled = emergency_intr_enable;
  166         error = sysctl_handle_int(oidp, &enabled, 0, req);
  167         if (error || req->newptr == NULL)
  168                 return error;
  169         emergency_intr_enable = enabled;
  170         if (emergency_intr_enable)
  171                 freq = emergency_intr_freq;
  172         else
  173                 freq = 1;
  174 
  175         for (cpuid = 0; cpuid < ncpus; ++cpuid)
  176                 systimer_adjust_periodic(&emergency_intr_timer[cpuid], freq);
  177         return 0;
  178 }
  179 
  180 static int
  181 sysctl_emergency_freq(SYSCTL_HANDLER_ARGS)
  182 {
  183         int error, phz, cpuid, freq;
  184 
  185         phz = emergency_intr_freq;
  186         error = sysctl_handle_int(oidp, &phz, 0, req);
  187         if (error || req->newptr == NULL)
  188                 return error;
  189         if (phz <= 0)
  190                 return EINVAL;
  191         else if (phz > EMERGENCY_INTR_POLLING_FREQ_MAX)
  192                 phz = EMERGENCY_INTR_POLLING_FREQ_MAX;
  193 
  194         emergency_intr_freq = phz;
  195         if (emergency_intr_enable)
  196                 freq = emergency_intr_freq;
  197         else
  198                 freq = 1;
  199 
  200         for (cpuid = 0; cpuid < ncpus; ++cpuid)
  201                 systimer_adjust_periodic(&emergency_intr_timer[cpuid], freq);
  202         return 0;
  203 }
  204 
  205 /*
  206  * Register an SWI or INTerrupt handler.
  207  */
  208 void *
  209 register_swi(int intr, inthand2_t *handler, void *arg, const char *name,
  210                 struct lwkt_serialize *serializer, int cpuid)
  211 {
  212     if (intr < FIRST_SOFTINT || intr >= MAX_INTS)
  213         panic("register_swi: bad intr %d", intr);
  214 
  215     if (cpuid < 0)
  216         cpuid = intr % ncpus;
  217     return(register_int(intr, handler, arg, name, serializer, 0, cpuid));
  218 }
  219 
  220 void *
  221 register_swi_mp(int intr, inthand2_t *handler, void *arg, const char *name,
  222                 struct lwkt_serialize *serializer, int cpuid)
  223 {
  224     if (intr < FIRST_SOFTINT || intr >= MAX_INTS)
  225         panic("register_swi: bad intr %d", intr);
  226 
  227     if (cpuid < 0)
  228         cpuid = intr % ncpus;
  229     return(register_int(intr, handler, arg, name, serializer,
  230         INTR_MPSAFE, cpuid));
  231 }
  232 
  233 void *
  234 register_int(int intr, inthand2_t *handler, void *arg, const char *name,
  235                 struct lwkt_serialize *serializer, int intr_flags, int cpuid)
  236 {
  237     struct intr_info *info;
  238     struct intrec **list;
  239     intrec_t rec;
  240     int orig_cpuid;
  241 
  242     KKASSERT(cpuid >= 0 && cpuid < ncpus);
  243 
  244     if (intr < 0 || intr >= MAX_INTS)
  245         panic("register_int: bad intr %d", intr);
  246     if (name == NULL)
  247         name = "???";
  248     info = &intr_info_ary[cpuid][intr];
  249 
  250     /*
  251      * Construct an interrupt handler record
  252      */
  253     rec = kmalloc(sizeof(struct intrec), M_DEVBUF, M_INTWAIT);
  254     rec->name = kmalloc(strlen(name) + 1, M_DEVBUF, M_INTWAIT);
  255     strcpy(rec->name, name);
  256 
  257     rec->info = info;
  258     rec->handler = handler;
  259     rec->argument = arg;
  260     rec->intr = intr;
  261     rec->intr_flags = intr_flags;
  262     rec->next = NULL;
  263     rec->serializer = serializer;
  264 
  265     int_moveto_destcpu(&orig_cpuid, cpuid);
  266 
  267     /*
  268      * Create an emergency polling thread and set up a systimer to wake
  269      * it up.
  270      */
  271     if (emergency_intr_thread[cpuid].td_kstack == NULL) {
  272         lwkt_create(ithread_emergency, NULL, NULL,
  273                     &emergency_intr_thread[cpuid],
  274                     TDF_NOSTART | TDF_INTTHREAD, cpuid, "ithreadE %d",
  275                     cpuid);
  276         systimer_init_periodic_nq(&emergency_intr_timer[cpuid],
  277                     emergency_intr_timer_callback,
  278                     &emergency_intr_thread[cpuid],
  279                     (emergency_intr_enable ? emergency_intr_freq : 1));
  280     }
  281 
  282     /*
  283      * Create an interrupt thread if necessary, leave it in an unscheduled
  284      * state.
  285      */
  286     if (info->i_state == ISTATE_NOTHREAD) {
  287         info->i_state = ISTATE_NORMAL;
  288         info->i_thread = kmalloc(sizeof(struct thread), M_DEVBUF,
  289             M_INTWAIT | M_ZERO);
  290         lwkt_create(ithread_handler, (void *)(intptr_t)intr, NULL,
  291                     info->i_thread, TDF_NOSTART | TDF_INTTHREAD, cpuid,
  292                     "ithread%d %d", intr, cpuid);
  293         if (intr >= FIRST_SOFTINT)
  294             lwkt_setpri(info->i_thread, TDPRI_SOFT_NORM);
  295         else
  296             lwkt_setpri(info->i_thread, TDPRI_INT_MED);
  297         info->i_thread->td_preemptable = lwkt_preempt;
  298     }
  299 
  300     list = &info->i_reclist;
  301 
  302     /*
  303      * Keep track of how many fast and slow interrupts we have.
  304      * Set i_mplock_required if any handler in the chain requires
  305      * the MP lock to operate.
  306      */
  307     if ((intr_flags & INTR_MPSAFE) == 0)
  308         info->i_mplock_required = 1;
  309     if (intr_flags & INTR_CLOCK)
  310         ++info->i_fast;
  311     else
  312         ++info->i_slow;
  313 
  314     /*
  315      * Enable random number generation keying off of this interrupt.
  316      */
  317     if ((intr_flags & INTR_NOENTROPY) == 0 && info->i_random.sc_enabled == 0) {
  318         info->i_random.sc_enabled = 1;
  319         info->i_random.sc_intr = intr;
  320     }
  321 
  322     /*
  323      * Add the record to the interrupt list.
  324      */
  325     crit_enter();
  326     while (*list != NULL)
  327         list = &(*list)->next;
  328     *list = rec;
  329     crit_exit();
  330 
  331     /*
  332      * Update max_installed_hard_intr to make the emergency intr poll
  333      * a bit more efficient.
  334      */
  335     if (intr < FIRST_SOFTINT) {
  336         if (max_installed_hard_intr[cpuid] <= intr)
  337             max_installed_hard_intr[cpuid] = intr + 1;
  338     }
  339 
  340     if (intr >= FIRST_SOFTINT)
  341         swi_info_ary[intr - FIRST_SOFTINT] = info;
  342 
  343     /*
  344      * Setup the machine level interrupt vector
  345      */
  346     if (intr < FIRST_SOFTINT && info->i_slow + info->i_fast == 1)
  347         machintr_intr_setup(intr, intr_flags);
  348 
  349     int_moveto_origcpu(orig_cpuid, cpuid);
  350 
  351     return(rec);
  352 }
  353 
  354 void
  355 unregister_swi(void *id, int intr, int cpuid)
  356 {
  357     if (cpuid < 0)
  358         cpuid = intr % ncpus;
  359 
  360     unregister_int(id, cpuid);
  361 }
  362 
  363 void
  364 unregister_int(void *id, int cpuid)
  365 {
  366     struct intr_info *info;
  367     struct intrec **list;
  368     intrec_t rec;
  369     int intr, orig_cpuid;
  370 
  371     KKASSERT(cpuid >= 0 && cpuid < ncpus);
  372 
  373     intr = ((intrec_t)id)->intr;
  374 
  375     if (intr < 0 || intr >= MAX_INTS)
  376         panic("register_int: bad intr %d", intr);
  377 
  378     info = &intr_info_ary[cpuid][intr];
  379 
  380     int_moveto_destcpu(&orig_cpuid, cpuid);
  381 
  382     /*
  383      * Remove the interrupt descriptor, adjust the descriptor count,
  384      * and teardown the machine level vector if this was the last interrupt.
  385      */
  386     crit_enter();
  387     list = &info->i_reclist;
  388     while ((rec = *list) != NULL) {
  389         if (rec == id)
  390             break;
  391         list = &rec->next;
  392     }
  393     if (rec) {
  394         intrec_t rec0;
  395 
  396         *list = rec->next;
  397         if (rec->intr_flags & INTR_CLOCK)
  398             --info->i_fast;
  399         else
  400             --info->i_slow;
  401         if (intr < FIRST_SOFTINT && info->i_fast + info->i_slow == 0)
  402             machintr_intr_teardown(intr);
  403 
  404         /*
  405          * Clear i_mplock_required if no handlers in the chain require the
  406          * MP lock.
  407          */
  408         for (rec0 = info->i_reclist; rec0; rec0 = rec0->next) {
  409             if ((rec0->intr_flags & INTR_MPSAFE) == 0)
  410                 break;
  411         }
  412         if (rec0 == NULL)
  413             info->i_mplock_required = 0;
  414     }
  415 
  416     if (intr >= FIRST_SOFTINT && info->i_reclist == NULL)
  417         swi_info_ary[intr - FIRST_SOFTINT] = NULL;
  418 
  419     crit_exit();
  420 
  421     int_moveto_origcpu(orig_cpuid, cpuid);
  422 
  423     /*
  424      * Free the record.
  425      */
  426     if (rec != NULL) {
  427         kfree(rec->name, M_DEVBUF);
  428         kfree(rec, M_DEVBUF);
  429     } else {
  430         kprintf("warning: unregister_int: int %d handler for %s not found\n",
  431                 intr, ((intrec_t)id)->name);
  432     }
  433 }
  434 
  435 long
  436 get_interrupt_counter(int intr, int cpuid)
  437 {
  438     struct intr_info *info;
  439 
  440     KKASSERT(cpuid >= 0 && cpuid < ncpus);
  441 
  442     if (intr < 0 || intr >= MAX_INTS)
  443         panic("register_int: bad intr %d", intr);
  444     info = &intr_info_ary[cpuid][intr];
  445     return(info->i_count);
  446 }
  447 
  448 void
  449 register_randintr(int intr)
  450 {
  451     struct intr_info *info;
  452     int cpuid;
  453 
  454     if (intr < 0 || intr >= MAX_INTS)
  455         panic("register_randintr: bad intr %d", intr);
  456 
  457     for (cpuid = 0; cpuid < ncpus; ++cpuid) {
  458         info = &intr_info_ary[cpuid][intr];
  459         info->i_random.sc_intr = intr;
  460         info->i_random.sc_enabled = 1;
  461     }
  462 }
  463 
  464 void
  465 unregister_randintr(int intr)
  466 {
  467     struct intr_info *info;
  468     int cpuid;
  469 
  470     if (intr < 0 || intr >= MAX_INTS)
  471         panic("register_swi: bad intr %d", intr);
  472 
  473     for (cpuid = 0; cpuid < ncpus; ++cpuid) {
  474         info = &intr_info_ary[cpuid][intr];
  475         info->i_random.sc_enabled = -1;
  476     }
  477 }
  478 
  479 int
  480 next_registered_randintr(int intr)
  481 {
  482     struct intr_info *info;
  483 
  484     if (intr < 0 || intr >= MAX_INTS)
  485         panic("register_swi: bad intr %d", intr);
  486 
  487     while (intr < MAX_INTS) {
  488         int cpuid;
  489 
  490         for (cpuid = 0; cpuid < ncpus; ++cpuid) {
  491             info = &intr_info_ary[cpuid][intr];
  492             if (info->i_random.sc_enabled > 0)
  493                 return intr;
  494         }
  495         ++intr;
  496     }
  497     return intr;
  498 }
  499 
  500 /*
  501  * Dispatch an interrupt.  If there's nothing to do we have a stray
  502  * interrupt and can just return, leaving the interrupt masked.
  503  *
  504  * We need to schedule the interrupt and set its i_running bit.  If
  505  * we are not on the interrupt thread's cpu we have to send a message
  506  * to the correct cpu that will issue the desired action (interlocking
  507  * with the interrupt thread's critical section).  We do NOT attempt to
  508  * reschedule interrupts whos i_running bit is already set because
  509  * this would prematurely wakeup a livelock-limited interrupt thread.
  510  *
  511  * i_running is only tested/set on the same cpu as the interrupt thread.
  512  *
  513  * We are NOT in a critical section, which will allow the scheduled
  514  * interrupt to preempt us.  The MP lock might *NOT* be held here.
  515  */
  516 static void
  517 sched_ithd_remote(void *arg)
  518 {
  519     sched_ithd_intern(arg);
  520 }
  521 
  522 static void
  523 sched_ithd_intern(struct intr_info *info)
  524 {
  525     ++info->i_count;
  526     if (info->i_state != ISTATE_NOTHREAD) {
  527         if (info->i_reclist == NULL) {
  528             report_stray_interrupt(info, "sched_ithd");
  529         } else {
  530             if (info->i_thread->td_gd == mycpu) {
  531                 if (info->i_running == 0) {
  532                     info->i_running = 1;
  533                     if (info->i_state != ISTATE_LIVELOCKED)
  534                         lwkt_schedule(info->i_thread); /* MIGHT PREEMPT */
  535                 }
  536             } else {
  537                 lwkt_send_ipiq(info->i_thread->td_gd, sched_ithd_remote, info);
  538             }
  539         }
  540     } else {
  541         report_stray_interrupt(info, "sched_ithd");
  542     }
  543 }
  544 
  545 void
  546 sched_ithd_soft(int intr)
  547 {
  548         struct intr_info *info;
  549 
  550         KKASSERT(intr >= FIRST_SOFTINT && intr < MAX_INTS);
  551 
  552         info = swi_info_ary[intr - FIRST_SOFTINT];
  553         if (info != NULL) {
  554                 sched_ithd_intern(info);
  555         } else {
  556                 kprintf("unregistered softint %d got scheduled on cpu%d\n",
  557                     intr, mycpuid);
  558         }
  559 }
  560 
  561 void
  562 sched_ithd_hard(int intr)
  563 {
  564         KKASSERT(intr >= 0 && intr < MAX_HARDINTS);
  565         sched_ithd_intern(&intr_info_ary[mycpuid][intr]);
  566 }
  567 
  568 #ifdef _KERNEL_VIRTUAL
  569 
  570 void
  571 sched_ithd_hard_virtual(int intr)
  572 {
  573         KKASSERT(intr >= 0 && intr < MAX_HARDINTS);
  574         sched_ithd_intern(&intr_info_ary[0][intr]);
  575 }
  576 
  577 void *
  578 register_int_virtual(int intr, inthand2_t *handler, void *arg, const char *name,
  579     struct lwkt_serialize *serializer, int intr_flags)
  580 {
  581         return register_int(intr, handler, arg, name, serializer, intr_flags, 0);
  582 }
  583 
  584 void
  585 unregister_int_virtual(void *id)
  586 {
  587         unregister_int(id, 0);
  588 }
  589 
  590 #endif  /* _KERN_VIRTUAL */
  591 
  592 static void
  593 report_stray_interrupt(struct intr_info *info, const char *func)
  594 {
  595         ++info->i_straycount;
  596         if (info->i_straycount < 10) {
  597                 if (info->i_errorticks == ticks)
  598                         return;
  599                 info->i_errorticks = ticks;
  600                 kprintf("%s: stray interrupt %d on cpu%d\n",
  601                     func, info->i_intr, mycpuid);
  602         } else if (info->i_straycount == 10) {
  603                 kprintf("%s: %ld stray interrupts %d on cpu%d - "
  604                         "there will be no further reports\n", func,
  605                         info->i_straycount, info->i_intr, mycpuid);
  606         }
  607 }
  608 
  609 /*
  610  * This is run from a periodic SYSTIMER (and thus must be MP safe, the BGL
  611  * might not be held).
  612  */
  613 static void
  614 ithread_livelock_wakeup(systimer_t st, int in_ipi __unused,
  615     struct intrframe *frame __unused)
  616 {
  617     struct intr_info *info;
  618 
  619     info = &intr_info_ary[mycpuid][(int)(intptr_t)st->data];
  620     if (info->i_state != ISTATE_NOTHREAD)
  621         lwkt_schedule(info->i_thread);
  622 }
  623 
  624 /*
  625  * Schedule ithread within fast intr handler
  626  *
  627  * XXX Protect sched_ithd_hard() call with gd_intr_nesting_level?
  628  * Interrupts aren't enabled, but still...
  629  */
  630 static __inline void
  631 ithread_fast_sched(int intr, thread_t td)
  632 {
  633     ++td->td_nest_count;
  634 
  635     /*
  636      * We are already in critical section, exit it now to
  637      * allow preemption.
  638      */
  639     crit_exit_quick(td);
  640     sched_ithd_hard(intr);
  641     crit_enter_quick(td);
  642 
  643     --td->td_nest_count;
  644 }
  645 
  646 /*
  647  * This function is called directly from the ICU or APIC vector code assembly
  648  * to process an interrupt.  The critical section and interrupt deferral
  649  * checks have already been done but the function is entered WITHOUT
  650  * a critical section held.  The BGL may or may not be held.
  651  *
  652  * Must return non-zero if we do not want the vector code to re-enable
  653  * the interrupt (which we don't if we have to schedule the interrupt)
  654  */
  655 int ithread_fast_handler(struct intrframe *frame);
  656 
  657 int
  658 ithread_fast_handler(struct intrframe *frame)
  659 {
  660     int intr;
  661     struct intr_info *info;
  662     struct intrec **list;
  663     int must_schedule;
  664     int got_mplock;
  665     TD_INVARIANTS_DECLARE;
  666     intrec_t rec, nrec;
  667     globaldata_t gd;
  668     thread_t td;
  669 
  670     intr = frame->if_vec;
  671     gd = mycpu;
  672     td = curthread;
  673 
  674     /* We must be in critical section. */
  675     KKASSERT(td->td_critcount);
  676 
  677     info = &intr_info_ary[mycpuid][intr];
  678 
  679     /*
  680      * If we are not processing any FAST interrupts, just schedule the thing.
  681      */
  682     if (info->i_fast == 0) {
  683         ++gd->gd_cnt.v_intr;
  684         ithread_fast_sched(intr, td);
  685         return(1);
  686     }
  687 
  688     /*
  689      * This should not normally occur since interrupts ought to be 
  690      * masked if the ithread has been scheduled or is running.
  691      */
  692     if (info->i_running)
  693         return(1);
  694 
  695     /*
  696      * Bump the interrupt nesting level to process any FAST interrupts.
  697      * Obtain the MP lock as necessary.  If the MP lock cannot be obtained,
  698      * schedule the interrupt thread to deal with the issue instead.
  699      *
  700      * To reduce overhead, just leave the MP lock held once it has been
  701      * obtained.
  702      */
  703     ++gd->gd_intr_nesting_level;
  704     ++gd->gd_cnt.v_intr;
  705     must_schedule = info->i_slow;
  706     got_mplock = 0;
  707 
  708     TD_INVARIANTS_GET(td);
  709     list = &info->i_reclist;
  710 
  711     for (rec = *list; rec; rec = nrec) {
  712         /* rec may be invalid after call */
  713         nrec = rec->next;
  714 
  715         if (rec->intr_flags & INTR_CLOCK) {
  716             if ((rec->intr_flags & INTR_MPSAFE) == 0 && got_mplock == 0) {
  717                 if (try_mplock() == 0) {
  718                     /* Couldn't get the MP lock; just schedule it. */
  719                     must_schedule = 1;
  720                     break;
  721                 }
  722                 got_mplock = 1;
  723             }
  724             if (rec->serializer) {
  725                 must_schedule += lwkt_serialize_handler_try(
  726                                         rec->serializer, rec->handler,
  727                                         rec->argument, frame);
  728             } else {
  729                 rec->handler(rec->argument, frame);
  730             }
  731             TD_INVARIANTS_TEST(td, rec->name);
  732         }
  733     }
  734 
  735     /*
  736      * Cleanup
  737      */
  738     --gd->gd_intr_nesting_level;
  739     if (got_mplock)
  740         rel_mplock();
  741 
  742     /*
  743      * If we had a problem, or mixed fast and slow interrupt handlers are
  744      * registered, schedule the ithread to catch the missed records (it
  745      * will just re-run all of them).  A return value of 0 indicates that
  746      * all handlers have been run and the interrupt can be re-enabled, and
  747      * a non-zero return indicates that the interrupt thread controls
  748      * re-enablement.
  749      */
  750     if (must_schedule > 0)
  751         ithread_fast_sched(intr, td);
  752     else if (must_schedule == 0)
  753         ++info->i_count;
  754     return(must_schedule);
  755 }
  756 
  757 /*
  758  * Interrupt threads run this as their main loop.
  759  *
  760  * The handler begins execution outside a critical section and no MP lock.
  761  *
  762  * The i_running state starts at 0.  When an interrupt occurs, the hardware
  763  * interrupt is disabled and sched_ithd_hard().  The HW interrupt remains
  764  * disabled until all routines have run.  We then call machintr_intr_enable()
  765  * to reenable the HW interrupt and deschedule us until the next interrupt. 
  766  *
  767  * We are responsible for atomically checking i_running.  i_running for our
  768  * irq is only set in the context of our cpu, so a critical section is a
  769  * sufficient interlock.
  770  */
  771 #define LIVELOCK_TIMEFRAME(freq)        ((freq) >> 2)   /* 1/4 second */
  772 
  773 static void
  774 ithread_handler(void *arg)
  775 {
  776     struct intr_info *info;
  777     int use_limit;
  778     __uint32_t lseconds;
  779     int intr, cpuid = mycpuid;
  780     int mpheld;
  781     struct intrec **list;
  782     intrec_t rec, nrec;
  783     globaldata_t gd;
  784     struct systimer ill_timer;  /* enforced freq. timer */
  785     u_int ill_count;            /* interrupt livelock counter */
  786     TD_INVARIANTS_DECLARE;
  787 
  788     ill_count = 0;
  789     intr = (int)(intptr_t)arg;
  790     info = &intr_info_ary[cpuid][intr];
  791     list = &info->i_reclist;
  792 
  793     /*
  794      * The loop must be entered with one critical section held.  The thread
  795      * does not hold the mplock on startup.
  796      */
  797     gd = mycpu;
  798     lseconds = gd->gd_time_seconds;
  799     crit_enter_gd(gd);
  800     mpheld = 0;
  801 
  802     for (;;) {
  803         /*
  804          * The chain is only considered MPSAFE if all its interrupt handlers
  805          * are MPSAFE.  However, if intr_mpsafe has been turned off we
  806          * always operate with the BGL.
  807          */
  808         if (info->i_mplock_required != mpheld) {
  809             if (info->i_mplock_required) {
  810                 KKASSERT(mpheld == 0);
  811                 get_mplock();
  812                 mpheld = 1;
  813             } else {
  814                 KKASSERT(mpheld != 0);
  815                 rel_mplock();
  816                 mpheld = 0;
  817             }
  818         }
  819 
  820         TD_INVARIANTS_GET(gd->gd_curthread);
  821 
  822         /*
  823          * If an interrupt is pending, clear i_running and execute the
  824          * handlers.  Note that certain types of interrupts can re-trigger
  825          * and set i_running again.
  826          *
  827          * Each handler is run in a critical section.  Note that we run both
  828          * FAST and SLOW designated service routines.
  829          */
  830         if (info->i_running) {
  831             ++ill_count;
  832             info->i_running = 0;
  833 
  834             if (*list == NULL)
  835                 report_stray_interrupt(info, "ithread_handler");
  836 
  837             for (rec = *list; rec; rec = nrec) {
  838                 /* rec may be invalid after call */
  839                 nrec = rec->next;
  840                 if (rec->serializer) {
  841                     lwkt_serialize_handler_call(rec->serializer, rec->handler,
  842                                                 rec->argument, NULL);
  843                 } else {
  844                     rec->handler(rec->argument, NULL);
  845                 }
  846                 TD_INVARIANTS_TEST(gd->gd_curthread, rec->name);
  847             }
  848         }
  849 
  850         /*
  851          * This is our interrupt hook to add rate randomness to the random
  852          * number generator.
  853          */
  854         if (info->i_random.sc_enabled > 0)
  855             add_interrupt_randomness(intr);
  856 
  857         /*
  858          * Unmask the interrupt to allow it to trigger again.  This only
  859          * applies to certain types of interrupts (typ level interrupts).
  860          * This can result in the interrupt retriggering, but the retrigger
  861          * will not be processed until we cycle our critical section.
  862          *
  863          * Only unmask interrupts while handlers are installed.  It is
  864          * possible to hit a situation where no handlers are installed
  865          * due to a device driver livelocking and then tearing down its
  866          * interrupt on close (the parallel bus being a good example).
  867          */
  868         if (intr < FIRST_SOFTINT && *list)
  869             machintr_intr_enable(intr);
  870 
  871         /*
  872          * Do a quick exit/enter to catch any higher-priority interrupt
  873          * sources, such as the statclock, so thread time accounting
  874          * will still work.  This may also cause an interrupt to re-trigger.
  875          */
  876         crit_exit_gd(gd);
  877         crit_enter_gd(gd);
  878 
  879         /*
  880          * LIVELOCK STATE MACHINE
  881          */
  882         switch(info->i_state) {
  883         case ISTATE_NORMAL:
  884             /*
  885              * Reset the count each second.
  886              */
  887             if (lseconds != gd->gd_time_seconds) {
  888                 lseconds = gd->gd_time_seconds;
  889                 ill_count = 0;
  890             }
  891 
  892             /*
  893              * If we did not exceed the frequency limit, we are done.  
  894              * If the interrupt has not retriggered we deschedule ourselves.
  895              */
  896             if (ill_count <= livelock_limit) {
  897                 if (info->i_running == 0) {
  898                     lwkt_deschedule_self(gd->gd_curthread);
  899                     lwkt_switch();
  900                 }
  901                 break;
  902             }
  903 
  904             /*
  905              * Otherwise we are livelocked.  Set up a periodic systimer
  906              * to wake the thread up at the limit frequency.
  907              */
  908             kprintf("intr %d on cpu%d at %d/%d hz, livelocked limit engaged!\n",
  909                     intr, cpuid, ill_count, livelock_limit);
  910             info->i_state = ISTATE_LIVELOCKED;
  911             if ((use_limit = livelock_limit) < 100)
  912                 use_limit = 100;
  913             else if (use_limit > 500000)
  914                 use_limit = 500000;
  915             systimer_init_periodic_nq(&ill_timer, ithread_livelock_wakeup,
  916                                       (void *)(intptr_t)intr, use_limit);
  917             /* fall through */
  918         case ISTATE_LIVELOCKED:
  919             /*
  920              * Wait for our periodic timer to go off.  Since the interrupt
  921              * has re-armed it can still set i_running, but it will not
  922              * reschedule us while we are in a livelocked state.
  923              */
  924             lwkt_deschedule_self(gd->gd_curthread);
  925             lwkt_switch();
  926 
  927             /*
  928              * Check once a second to see if the livelock condition no
  929              * longer applies.
  930              */
  931             if (lseconds != gd->gd_time_seconds) {
  932                 lseconds = gd->gd_time_seconds;
  933                 if (ill_count < livelock_lowater) {
  934                     info->i_state = ISTATE_NORMAL;
  935                     systimer_del(&ill_timer);
  936                     kprintf("intr %d on cpu%d at %d/%d hz, livelock removed\n",
  937                             intr, cpuid, ill_count, livelock_lowater);
  938                 } else if (livelock_debug == intr ||
  939                            (bootverbose && cold)) {
  940                     kprintf("intr %d on cpu%d at %d/%d hz, in livelock\n",
  941                             intr, cpuid, ill_count, livelock_lowater);
  942                 }
  943                 ill_count = 0;
  944             }
  945             break;
  946         }
  947     }
  948     /* NOT REACHED */
  949 }
  950 
  951 /*
  952  * Emergency interrupt polling thread.  The thread begins execution
  953  * outside a critical section with the BGL held.
  954  *
  955  * If emergency interrupt polling is enabled, this thread will 
  956  * execute all system interrupts not marked INTR_NOPOLL at the
  957  * specified polling frequency.
  958  *
  959  * WARNING!  This thread runs *ALL* interrupt service routines that
  960  * are not marked INTR_NOPOLL, which basically means everything except
  961  * the 8254 clock interrupt and the ATA interrupt.  It has very high
  962  * overhead and should only be used in situations where the machine
  963  * cannot otherwise be made to work.  Due to the severe performance
  964  * degredation, it should not be enabled on production machines.
  965  */
  966 static void
  967 ithread_emergency(void *arg __unused)
  968 {
  969     globaldata_t gd = mycpu;
  970     struct intr_info *info;
  971     intrec_t rec, nrec;
  972     int intr, cpuid = mycpuid;
  973     TD_INVARIANTS_DECLARE;
  974 
  975     get_mplock();
  976     crit_enter_gd(gd);
  977     TD_INVARIANTS_GET(gd->gd_curthread);
  978 
  979     for (;;) {
  980         for (intr = 0; intr < max_installed_hard_intr[cpuid]; ++intr) {
  981             info = &intr_info_ary[cpuid][intr];
  982             for (rec = info->i_reclist; rec; rec = nrec) {
  983                 /* rec may be invalid after call */
  984                 nrec = rec->next;
  985                 if ((rec->intr_flags & INTR_NOPOLL) == 0) {
  986                     if (rec->serializer) {
  987                         lwkt_serialize_handler_try(rec->serializer,
  988                                                 rec->handler, rec->argument, NULL);
  989                     } else {
  990                         rec->handler(rec->argument, NULL);
  991                     }
  992                     TD_INVARIANTS_TEST(gd->gd_curthread, rec->name);
  993                 }
  994             }
  995         }
  996         lwkt_deschedule_self(gd->gd_curthread);
  997         lwkt_switch();
  998     }
  999     /* NOT REACHED */
 1000 }
 1001 
 1002 /*
 1003  * Systimer callback - schedule the emergency interrupt poll thread
 1004  *                     if emergency polling is enabled.
 1005  */
 1006 static
 1007 void
 1008 emergency_intr_timer_callback(systimer_t info, int in_ipi __unused,
 1009     struct intrframe *frame __unused)
 1010 {
 1011     if (emergency_intr_enable)
 1012         lwkt_schedule(info->data);
 1013 }
 1014 
 1015 /* 
 1016  * Sysctls used by systat and others: hw.intrnames and hw.intrcnt.
 1017  * The data for this machine dependent, and the declarations are in machine
 1018  * dependent code.  The layout of intrnames and intrcnt however is machine
 1019  * independent.
 1020  *
 1021  * We do not know the length of intrcnt and intrnames at compile time, so
 1022  * calculate things at run time.
 1023  */
 1024 
 1025 static int
 1026 sysctl_intrnames(SYSCTL_HANDLER_ARGS)
 1027 {
 1028     struct intr_info *info;
 1029     intrec_t rec;
 1030     int error = 0;
 1031     int len;
 1032     int intr, cpuid;
 1033     char buf[64];
 1034 
 1035     for (cpuid = 0; cpuid < ncpus; ++cpuid) {
 1036         for (intr = 0; error == 0 && intr < MAX_INTS; ++intr) {
 1037             info = &intr_info_ary[cpuid][intr];
 1038 
 1039             len = 0;
 1040             buf[0] = 0;
 1041             for (rec = info->i_reclist; rec; rec = rec->next) {
 1042                 ksnprintf(buf + len, sizeof(buf) - len, "%s%s",
 1043                     (len ? "/" : ""), rec->name);
 1044                 len += strlen(buf + len);
 1045             }
 1046             if (len == 0) {
 1047                 ksnprintf(buf, sizeof(buf), "irq%d", intr);
 1048                 len = strlen(buf);
 1049             }
 1050             error = SYSCTL_OUT(req, buf, len + 1);
 1051         }
 1052     }
 1053     return (error);
 1054 }
 1055 
 1056 SYSCTL_PROC(_hw, OID_AUTO, intrnames, CTLTYPE_OPAQUE | CTLFLAG_RD,
 1057         NULL, 0, sysctl_intrnames, "", "Interrupt Names");
 1058 
 1059 static int
 1060 sysctl_intrcnt_all(SYSCTL_HANDLER_ARGS)
 1061 {
 1062     struct intr_info *info;
 1063     int error = 0;
 1064     int intr, cpuid;
 1065 
 1066     for (cpuid = 0; cpuid < ncpus; ++cpuid) {
 1067         for (intr = 0; intr < MAX_INTS; ++intr) {
 1068             info = &intr_info_ary[cpuid][intr];
 1069 
 1070             error = SYSCTL_OUT(req, &info->i_count, sizeof(info->i_count));
 1071             if (error)
 1072                 goto failed;
 1073         }
 1074     }
 1075 failed:
 1076     return(error);
 1077 }
 1078 
 1079 SYSCTL_PROC(_hw, OID_AUTO, intrcnt_all, CTLTYPE_OPAQUE | CTLFLAG_RD,
 1080         NULL, 0, sysctl_intrcnt_all, "", "Interrupt Counts");
 1081 
 1082 SYSCTL_PROC(_hw, OID_AUTO, intrcnt, CTLTYPE_OPAQUE | CTLFLAG_RD,
 1083         NULL, 0, sysctl_intrcnt_all, "", "Interrupt Counts");
 1084 
 1085 static void
 1086 int_moveto_destcpu(int *orig_cpuid0, int cpuid)
 1087 {
 1088     int orig_cpuid = mycpuid;
 1089 
 1090     if (cpuid != orig_cpuid)
 1091         lwkt_migratecpu(cpuid);
 1092 
 1093     *orig_cpuid0 = orig_cpuid;
 1094 }
 1095 
 1096 static void
 1097 int_moveto_origcpu(int orig_cpuid, int cpuid)
 1098 {
 1099     if (cpuid != orig_cpuid)
 1100         lwkt_migratecpu(orig_cpuid);
 1101 }
 1102 
 1103 static void
 1104 intr_init(void *dummy __unused)
 1105 {
 1106         int cpuid;
 1107 
 1108         kprintf("Initialize MI interrupts\n");
 1109 
 1110         for (cpuid = 0; cpuid < ncpus; ++cpuid) {
 1111                 int intr;
 1112 
 1113                 for (intr = 0; intr < MAX_INTS; ++intr) {
 1114                         struct intr_info *info = &intr_info_ary[cpuid][intr];
 1115 
 1116                         info->i_cpuid = cpuid;
 1117                         info->i_intr = intr;
 1118                 }
 1119         }
 1120 }
 1121 SYSINIT(intr_init, SI_BOOT2_FINISH_PIC, SI_ORDER_ANY, intr_init, NULL);

Cache object: 6534249b4323fd80fdec9d2935ad0a61


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.