intr: Per-cpu MI interrupt information array
authorSepherosa Ziehau <sephe@dragonflybsd.org>
Thu, 15 Dec 2011 05:47:26 +0000 (13:47 +0800)
committerSepherosa Ziehau <sephe@dragonflybsd.org>
Thu, 15 Dec 2011 06:29:45 +0000 (14:29 +0800)
- Interrupt information is only recorded in its target CPU's interrupt
  information array.
- Interrupt threads, emergency polling threads, interrupt livelock
  processing and hardware interrupt threads scheduling only access
  the interrupt information of the CPU they are running on; they have
  already been locked to the interrupt's target CPU.
- Location of SWI information is saved in a global array swi_info_ary,
  since scheduling SWI does not necessarily happens on the CPU that
  SWI thread is running, we need a quick and correct way find the SWI
  information.
- Factor out sched_ithd_intern, which accept interrupt information
  (struct intr_info) instead of interrupt number.  Split the original
  sched_ithd() into sched_ithd_soft(), which schedules SWI thread, and
  sched_ithd_hard() which schedules hardware interrupt thread.
- vmstat(8) interrupt reporting w/ -v is augmented to print the interrupts'
  target CPU.

This paves way to the per-cpu MD interrupt description table

sys/kern/kern_intr.c
sys/platform/pc32/acpica5/acpi_fadt.c
sys/platform/pc32/i386/ipl.s
sys/platform/pc32/isa/clock.c
sys/platform/pc64/acpica5/acpi_fadt.c
sys/platform/pc64/isa/clock.c
sys/platform/pc64/x86_64/ipl.s
sys/platform/vkernel/platform/machintr.c
sys/platform/vkernel64/platform/machintr.c
sys/sys/interrupt.h
usr.bin/vmstat/vmstat.c

index 685644d..1d21b53 100644 (file)
@@ -45,7 +45,7 @@
 #include <sys/thread2.h>
 #include <sys/mplock2.h>
 
-struct info_info;
+struct intr_info;
 
 typedef struct intrec {
     struct intrec *next;
@@ -70,7 +70,12 @@ struct intr_info {
        int             i_state;
        int             i_errorticks;
        unsigned long   i_straycount;
-} intr_info_ary[MAX_INTS];
+       int             i_cpuid;
+       int             i_intr;
+};
+
+static struct intr_info intr_info_ary[MAXCPU][MAX_INTS];
+static struct intr_info *swi_info_ary[MAX_SOFTINTS];
 
 static int max_installed_hard_intr[MAXCPU];
 
@@ -117,11 +122,10 @@ static int sysctl_emergency_enable(SYSCTL_HANDLER_ARGS);
 static void emergency_intr_timer_callback(systimer_t, int, struct intrframe *);
 static void ithread_handler(void *arg);
 static void ithread_emergency(void *arg);
-static void report_stray_interrupt(int intr, struct intr_info *info);
+static void report_stray_interrupt(struct intr_info *info, const char *func);
 static void int_moveto_destcpu(int *, int);
 static void int_moveto_origcpu(int, int);
-
-int intr_info_size = NELEM(intr_info_ary);
+static void sched_ithd_intern(struct intr_info *info);
 
 static struct systimer emergency_intr_timer[MAXCPU];
 static struct thread emergency_intr_thread[MAXCPU];
@@ -241,7 +245,7 @@ register_int(int intr, inthand2_t *handler, void *arg, const char *name,
        panic("register_int: bad intr %d", intr);
     if (name == NULL)
        name = "???";
-    info = &intr_info_ary[intr];
+    info = &intr_info_ary[cpuid][intr];
 
     /*
      * Construct an interrupt handler record
@@ -267,7 +271,7 @@ register_int(int intr, inthand2_t *handler, void *arg, const char *name,
     if (emergency_intr_thread[cpuid].td_kstack == NULL) {
        lwkt_create(ithread_emergency, NULL, NULL,
                    &emergency_intr_thread[cpuid],
-                   TDF_NOSTART | TDF_INTTHREAD, cpuid, "ithread emerg %d",
+                   TDF_NOSTART | TDF_INTTHREAD, cpuid, "ithreadE %d",
                    cpuid);
        systimer_init_periodic_nq(&emergency_intr_timer[cpuid],
                    emergency_intr_timer_callback,
@@ -283,7 +287,7 @@ register_int(int intr, inthand2_t *handler, void *arg, const char *name,
        info->i_state = ISTATE_NORMAL;
        lwkt_create(ithread_handler, (void *)(intptr_t)intr, NULL,
                    &info->i_thread, TDF_NOSTART | TDF_INTTHREAD, cpuid,
-                   "ithread %d", intr);
+                   "ithread%d %d", intr, cpuid);
        if (intr >= FIRST_SOFTINT)
            lwkt_setpri(&info->i_thread, TDPRI_SOFT_NORM);
        else
@@ -331,6 +335,9 @@ register_int(int intr, inthand2_t *handler, void *arg, const char *name,
            max_installed_hard_intr[cpuid] = intr + 1;
     }
 
+    if (intr >= FIRST_SOFTINT)
+       swi_info_ary[intr - FIRST_SOFTINT] = info;
+
     /*
      * Setup the machine level interrupt vector
      */
@@ -366,7 +373,7 @@ unregister_int(void *id, int cpuid)
     if (intr < 0 || intr >= MAX_INTS)
        panic("register_int: bad intr %d", intr);
 
-    info = &intr_info_ary[intr];
+    info = &intr_info_ary[cpuid][intr];
 
     int_moveto_destcpu(&orig_cpuid, cpuid);
 
@@ -404,6 +411,9 @@ unregister_int(void *id, int cpuid)
            info->i_mplock_required = 0;
     }
 
+    if (intr >= FIRST_SOFTINT && info->i_reclist == NULL)
+       swi_info_ary[intr - FIRST_SOFTINT] = NULL;
+
     crit_exit();
 
     int_moveto_origcpu(orig_cpuid, cpuid);
@@ -421,13 +431,15 @@ unregister_int(void *id, int cpuid)
 }
 
 long
-get_interrupt_counter(int intr)
+get_interrupt_counter(int intr, int cpuid)
 {
     struct intr_info *info;
 
+    KKASSERT(cpuid >= 0 && cpuid < ncpus);
+
     if (intr < 0 || intr >= MAX_INTS)
        panic("register_int: bad intr %d", intr);
-    info = &intr_info_ary[intr];
+    info = &intr_info_ary[cpuid][intr];
     return(info->i_count);
 }
 
@@ -435,23 +447,31 @@ void
 register_randintr(int intr)
 {
     struct intr_info *info;
+    int cpuid;
 
     if (intr < 0 || intr >= MAX_INTS)
        panic("register_randintr: bad intr %d", intr);
-    info = &intr_info_ary[intr];
-    info->i_random.sc_intr = intr;
-    info->i_random.sc_enabled = 1;
+
+    for (cpuid = 0; cpuid < ncpus; ++cpuid) {
+       info = &intr_info_ary[cpuid][intr];
+       info->i_random.sc_intr = intr;
+       info->i_random.sc_enabled = 1;
+    }
 }
 
 void
 unregister_randintr(int intr)
 {
     struct intr_info *info;
+    int cpuid;
 
     if (intr < 0 || intr >= MAX_INTS)
        panic("register_swi: bad intr %d", intr);
-    info = &intr_info_ary[intr];
-    info->i_random.sc_enabled = -1;
+
+    for (cpuid = 0; cpuid < ncpus; ++cpuid) {
+       info = &intr_info_ary[cpuid][intr];
+       info->i_random.sc_enabled = -1;
+    }
 }
 
 int
@@ -461,13 +481,18 @@ next_registered_randintr(int intr)
 
     if (intr < 0 || intr >= MAX_INTS)
        panic("register_swi: bad intr %d", intr);
+
     while (intr < MAX_INTS) {
-       info = &intr_info_ary[intr];
-       if (info->i_random.sc_enabled > 0)
-           break;
+       int cpuid;
+
+       for (cpuid = 0; cpuid < ncpus; ++cpuid) {
+           info = &intr_info_ary[cpuid][intr];
+           if (info->i_random.sc_enabled > 0)
+               return intr;
+       }
        ++intr;
     }
-    return(intr);
+    return intr;
 }
 
 /*
@@ -491,22 +516,18 @@ next_registered_randintr(int intr)
 static void
 sched_ithd_remote(void *arg)
 {
-    sched_ithd((int)(intptr_t)arg);
+    sched_ithd_intern(arg);
 }
 
 #endif
 
-void
-sched_ithd(int intr)
+static void
+sched_ithd_intern(struct intr_info *info)
 {
-    struct intr_info *info;
-
-    info = &intr_info_ary[intr];
-
     ++info->i_count;
     if (info->i_state != ISTATE_NOTHREAD) {
        if (info->i_reclist == NULL) {
-           report_stray_interrupt(intr, info);
+           report_stray_interrupt(info, "sched_ithd");
        } else {
 #ifdef SMP
            if (info->i_thread.td_gd == mycpu) {
@@ -516,8 +537,7 @@ sched_ithd(int intr)
                        lwkt_schedule(&info->i_thread); /* MIGHT PREEMPT */
                }
            } else {
-               lwkt_send_ipiq(info->i_thread.td_gd, 
-                               sched_ithd_remote, (void *)(intptr_t)intr);
+               lwkt_send_ipiq(info->i_thread.td_gd, sched_ithd_remote, info);
            }
 #else
            if (info->i_running == 0) {
@@ -528,24 +548,47 @@ sched_ithd(int intr)
 #endif
        }
     } else {
-       report_stray_interrupt(intr, info);
+       report_stray_interrupt(info, "sched_ithd");
     }
 }
 
+void
+sched_ithd_soft(int intr)
+{
+       struct intr_info *info;
+
+       KKASSERT(intr >= FIRST_SOFTINT && intr < MAX_INTS);
+
+       info = swi_info_ary[intr - FIRST_SOFTINT];
+       if (info != NULL) {
+               sched_ithd_intern(info);
+       } else {
+               kprintf("unregistered softint %d got scheduled on cpu%d\n",
+                   intr, mycpuid);
+       }
+}
+
+void
+sched_ithd_hard(int intr)
+{
+       KKASSERT(intr >= 0 && intr < MAX_HARDINTS);
+       sched_ithd_intern(&intr_info_ary[mycpuid][intr]);
+}
+
 static void
-report_stray_interrupt(int intr, struct intr_info *info)
+report_stray_interrupt(struct intr_info *info, const char *func)
 {
        ++info->i_straycount;
        if (info->i_straycount < 10) {
                if (info->i_errorticks == ticks)
                        return;
                info->i_errorticks = ticks;
-               kprintf("sched_ithd: stray interrupt %d on cpu %d\n",
-                       intr, mycpuid);
+               kprintf("%s: stray interrupt %d on cpu%d\n",
+                   func, info->i_intr, mycpuid);
        } else if (info->i_straycount == 10) {
-               kprintf("sched_ithd: %ld stray interrupts %d on cpu %d - "
-                       "there will be no further reports\n",
-                       info->i_straycount, intr, mycpuid);
+               kprintf("%s: %ld stray interrupts %d on cpu%d - "
+                       "there will be no further reports\n", func,
+                       info->i_straycount, info->i_intr, mycpuid);
        }
 }
 
@@ -559,7 +602,7 @@ ithread_livelock_wakeup(systimer_t st, int in_ipi __unused,
 {
     struct intr_info *info;
 
-    info = &intr_info_ary[(int)(intptr_t)st->data];
+    info = &intr_info_ary[mycpuid][(int)(intptr_t)st->data];
     if (info->i_state != ISTATE_NOTHREAD)
        lwkt_schedule(&info->i_thread);
 }
@@ -567,7 +610,7 @@ ithread_livelock_wakeup(systimer_t st, int in_ipi __unused,
 /*
  * Schedule ithread within fast intr handler
  *
- * XXX Protect sched_ithd() call with gd_intr_nesting_level?
+ * XXX Protect sched_ithd_hard() call with gd_intr_nesting_level?
  * Interrupts aren't enabled, but still...
  */
 static __inline void
@@ -580,7 +623,7 @@ ithread_fast_sched(int intr, thread_t td)
      * allow preemption.
      */
     crit_exit_quick(td);
-    sched_ithd(intr);
+    sched_ithd_hard(intr);
     crit_enter_quick(td);
 
     --td->td_nest_count;
@@ -619,7 +662,7 @@ ithread_fast_handler(struct intrframe *frame)
     /* We must be in critical section. */
     KKASSERT(td->td_critcount);
 
-    info = &intr_info_ary[intr];
+    info = &intr_info_ary[mycpuid][intr];
 
     /*
      * If we are not processing any FAST interrupts, just schedule the thing.
@@ -711,9 +754,9 @@ ithread_fast_handler(struct intrframe *frame)
  * The handler begins execution outside a critical section and no MP lock.
  *
  * The i_running state starts at 0.  When an interrupt occurs, the hardware
- * interrupt is disabled and sched_ithd() The HW interrupt remains disabled
- * until all routines have run.  We then call ithread_done() to reenable 
- * the HW interrupt and deschedule us until the next interrupt. 
+ * interrupt is disabled and sched_ithd_hard() The HW interrupt remains
+ * disabled until all routines have run.  We then call ithread_done() to
+ * reenable the HW interrupt and deschedule us until the next interrupt. 
  *
  * We are responsible for atomically checking i_running and ithread_done()
  * is responsible for atomically checking for platform-specific delayed
@@ -728,7 +771,7 @@ ithread_handler(void *arg)
     struct intr_info *info;
     int use_limit;
     __uint32_t lseconds;
-    int intr;
+    int intr, cpuid = mycpuid;
     int mpheld;
     struct intrec **list;
     intrec_t rec, nrec;
@@ -739,7 +782,7 @@ ithread_handler(void *arg)
 
     ill_count = 0;
     intr = (int)(intptr_t)arg;
-    info = &intr_info_ary[intr];
+    info = &intr_info_ary[cpuid][intr];
     list = &info->i_reclist;
 
     /*
@@ -786,7 +829,7 @@ ithread_handler(void *arg)
            info->i_running = 0;
 
            if (*list == NULL)
-               report_stray_interrupt(intr, info);
+               report_stray_interrupt(info, "ithread_handler");
 
            for (rec = *list; rec; rec = nrec) {
                /* rec may be invalid after call */
@@ -859,8 +902,8 @@ ithread_handler(void *arg)
             * Otherwise we are livelocked.  Set up a periodic systimer
             * to wake the thread up at the limit frequency.
             */
-           kprintf("intr %d at %d/%d hz, livelocked limit engaged!\n",
-                  intr, ill_count, livelock_limit);
+           kprintf("intr %d on cpu%d at %d/%d hz, livelocked limit engaged!\n",
+                   intr, cpuid, ill_count, livelock_limit);
            info->i_state = ISTATE_LIVELOCKED;
            if ((use_limit = livelock_limit) < 100)
                use_limit = 100;
@@ -887,12 +930,12 @@ ithread_handler(void *arg)
                if (ill_count < livelock_lowater) {
                    info->i_state = ISTATE_NORMAL;
                    systimer_del(&ill_timer);
-                   kprintf("intr %d at %d/%d hz, livelock removed\n",
-                          intr, ill_count, livelock_lowater);
+                   kprintf("intr %d on cpu%d at %d/%d hz, livelock removed\n",
+                           intr, cpuid, ill_count, livelock_lowater);
                } else if (livelock_debug == intr ||
                           (bootverbose && cold)) {
-                   kprintf("intr %d at %d/%d hz, in livelock\n",
-                          intr, ill_count, livelock_lowater);
+                   kprintf("intr %d on cpu%d at %d/%d hz, in livelock\n",
+                           intr, cpuid, ill_count, livelock_lowater);
                }
                ill_count = 0;
            }
@@ -932,7 +975,7 @@ ithread_emergency(void *arg __unused)
 
     for (;;) {
        for (intr = 0; intr < max_installed_hard_intr[cpuid]; ++intr) {
-           info = &intr_info_ary[intr];
+           info = &intr_info_ary[cpuid][intr];
            for (rec = info->i_reclist; rec; rec = nrec) {
                /* rec may be invalid after call */
                nrec = rec->next;
@@ -969,14 +1012,7 @@ emergency_intr_timer_callback(systimer_t info, int in_ipi __unused,
 int
 ithread_cpuid(int intr)
 {
-       const struct intr_info *info;
-
-       KKASSERT(intr >= 0 && intr < MAX_INTS);
-       info = &intr_info_ary[intr];
-
-       if (info->i_state == ISTATE_NOTHREAD)
-               return -1;
-       return info->i_thread.td_gd->gd_cpuid;
+       return machintr_intr_cpuid(intr);
 }
 
 /* 
@@ -996,29 +1032,30 @@ sysctl_intrnames(SYSCTL_HANDLER_ARGS)
     intrec_t rec;
     int error = 0;
     int len;
-    int intr;
+    int intr, cpuid;
     char buf[64];
 
-    for (intr = 0; error == 0 && intr < MAX_INTS; ++intr) {
-       info = &intr_info_ary[intr];
+    for (cpuid = 0; cpuid < ncpus; ++cpuid) {
+       for (intr = 0; error == 0 && intr < MAX_INTS; ++intr) {
+           info = &intr_info_ary[cpuid][intr];
 
-       len = 0;
-       buf[0] = 0;
-       for (rec = info->i_reclist; rec; rec = rec->next) {
-           ksnprintf(buf + len, sizeof(buf) - len, "%s%s", 
-               (len ? "/" : ""), rec->name);
-           len += strlen(buf + len);
-       }
-       if (len == 0) {
-           ksnprintf(buf, sizeof(buf), "irq%d", intr);
-           len = strlen(buf);
+           len = 0;
+           buf[0] = 0;
+           for (rec = info->i_reclist; rec; rec = rec->next) {
+               ksnprintf(buf + len, sizeof(buf) - len, "%s%s",
+                   (len ? "/" : ""), rec->name);
+               len += strlen(buf + len);
+           }
+           if (len == 0) {
+               ksnprintf(buf, sizeof(buf), "irq%d", intr);
+               len = strlen(buf);
+           }
+           error = SYSCTL_OUT(req, buf, len + 1);
        }
-       error = SYSCTL_OUT(req, buf, len + 1);
     }
     return (error);
 }
 
-
 SYSCTL_PROC(_hw, OID_AUTO, intrnames, CTLTYPE_OPAQUE | CTLFLAG_RD,
        NULL, 0, sysctl_intrnames, "", "Interrupt Names");
 
@@ -1027,14 +1064,16 @@ sysctl_intrcnt_all(SYSCTL_HANDLER_ARGS)
 {
     struct intr_info *info;
     int error = 0;
-    int intr;
+    int intr, cpuid;
 
-    for (intr = 0; intr < MAX_INTS; ++intr) {
-       info = &intr_info_ary[intr];
+    for (cpuid = 0; cpuid < ncpus; ++cpuid) {
+       for (intr = 0; intr < MAX_INTS; ++intr) {
+           info = &intr_info_ary[cpuid][intr];
 
-       error = SYSCTL_OUT(req, &info->i_count, sizeof(info->i_count));
-       if (error)
+           error = SYSCTL_OUT(req, &info->i_count, sizeof(info->i_count));
+           if (error)
                goto failed;
+       }
     }
 failed:
     return(error);
@@ -1063,3 +1102,23 @@ int_moveto_origcpu(int orig_cpuid, int cpuid)
     if (cpuid != orig_cpuid)
        lwkt_migratecpu(orig_cpuid);
 }
+
+static void
+intr_init(void *dummy __unused)
+{
+       int cpuid;
+
+       kprintf("Initialize MI interrupts\n");
+
+       for (cpuid = 0; cpuid < ncpus; ++cpuid) {
+               int intr;
+
+               for (intr = 0; intr < MAX_INTS; ++intr) {
+                       struct intr_info *info = &intr_info_ary[cpuid][intr];
+
+                       info->i_cpuid = cpuid;
+                       info->i_intr = intr;
+               }
+       }
+}
+SYSINIT(intr_init, SI_BOOT2_FINISH_PIC, SI_ORDER_ANY, intr_init, NULL);
index 6822bea..1942138 100644 (file)
@@ -204,7 +204,7 @@ acpi_sci_config(void)
                    intr_str_trigger(mode->sci_trig),
                    intr_str_polarity(mode->sci_pola));
 
-               last_cnt = get_interrupt_counter(acpi_sci_irq);
+               last_cnt = get_interrupt_counter(acpi_sci_irq, 0);
 
                machintr_intr_config(acpi_sci_irq,
                    mode->sci_trig, mode->sci_pola);
@@ -218,7 +218,7 @@ acpi_sci_config(void)
 
                unregister_int(sci_desc, 0);
 
-               if (get_interrupt_counter(acpi_sci_irq) - last_cnt < 20) {
+               if (get_interrupt_counter(acpi_sci_irq, 0) - last_cnt < 20) {
                        acpi_sci_trig = mode->sci_trig;
                        acpi_sci_pola = mode->sci_pola;
 
index 6c6d06d..05bf5a2 100644 (file)
@@ -272,7 +272,7 @@ doreti_soft:
        pushl   %ecx
        incl    TD_NEST_COUNT(%ebx)     /* prevent doreti/splz nesting */
        decl    TD_CRITCOUNT(%ebx)      /* so we can preempt */
-       call    sched_ithd              /* YYY must pull in imasks */
+       call    sched_ithd_soft         /* YYY must pull in imasks */
        incl    TD_CRITCOUNT(%ebx)
        decl    TD_NEST_COUNT(%ebx)
        addl    $4,%esp
@@ -445,7 +445,7 @@ splz_soft:
        pushl   %ecx
        decl    TD_CRITCOUNT(%ebx)
        incl    TD_NEST_COUNT(%ebx)     /* prevent doreti/splz nesting */
-       call    sched_ithd              /* YYY must pull in imasks */
+       call    sched_ithd_soft         /* YYY must pull in imasks */
        incl    TD_CRITCOUNT(%ebx)
        decl    TD_NEST_COUNT(%ebx)     /* prevent doreti/splz nesting */
        addl    $4,%esp
index 633e335..6cfed11 100644 (file)
@@ -1012,7 +1012,7 @@ i8254_ioapic_trial(int irq, struct cputimer_intr *cti)
        KKASSERT(sys_cputimer == &i8254_cputimer);
        KKASSERT(cti == &i8254_cputimer_intr);
 
-       lastcnt = get_interrupt_counter(irq);
+       lastcnt = get_interrupt_counter(irq, mycpuid);
 
        /*
         * Force an 8254 Timer0 interrupt and wait 1/100s for
@@ -1025,7 +1025,7 @@ i8254_ioapic_trial(int irq, struct cputimer_intr *cti)
        while (sys_cputimer->count() - base < sys_cputimer->freq / 100)
                ; /* nothing */
 
-       if (get_interrupt_counter(irq) - lastcnt == 0)
+       if (get_interrupt_counter(irq, mycpuid) - lastcnt == 0)
                return ENOENT;
        return 0;
 }
index 6822bea..1942138 100644 (file)
@@ -204,7 +204,7 @@ acpi_sci_config(void)
                    intr_str_trigger(mode->sci_trig),
                    intr_str_polarity(mode->sci_pola));
 
-               last_cnt = get_interrupt_counter(acpi_sci_irq);
+               last_cnt = get_interrupt_counter(acpi_sci_irq, 0);
 
                machintr_intr_config(acpi_sci_irq,
                    mode->sci_trig, mode->sci_pola);
@@ -218,7 +218,7 @@ acpi_sci_config(void)
 
                unregister_int(sci_desc, 0);
 
-               if (get_interrupt_counter(acpi_sci_irq) - last_cnt < 20) {
+               if (get_interrupt_counter(acpi_sci_irq, 0) - last_cnt < 20) {
                        acpi_sci_trig = mode->sci_trig;
                        acpi_sci_pola = mode->sci_pola;
 
index 308377a..d408b16 100644 (file)
@@ -1019,7 +1019,7 @@ i8254_ioapic_trial(int irq, struct cputimer_intr *cti)
        KKASSERT(sys_cputimer == &i8254_cputimer);
        KKASSERT(cti == &i8254_cputimer_intr);
 
-       lastcnt = get_interrupt_counter(irq);
+       lastcnt = get_interrupt_counter(irq, mycpuid);
 
        /*
         * Force an 8254 Timer0 interrupt and wait 1/100s for
@@ -1032,7 +1032,7 @@ i8254_ioapic_trial(int irq, struct cputimer_intr *cti)
        while (sys_cputimer->count() - base < sys_cputimer->freq / 100)
                ; /* nothing */
 
-       if (get_interrupt_counter(irq) - lastcnt == 0)
+       if (get_interrupt_counter(irq, mycpuid) - lastcnt == 0)
                return ENOENT;
        return 0;
 }
index a16a35c..984fa92 100644 (file)
@@ -279,7 +279,7 @@ doreti_soft:
        movl    %ecx,%edi               /* argument to C call */
        incl    TD_NEST_COUNT(%rbx)     /* prevent doreti/splz nesting */
        decl    TD_CRITCOUNT(%rbx)      /* so we can preempt */
-       call    sched_ithd              /* YYY must pull in imasks */
+       call    sched_ithd_soft         /* YYY must pull in imasks */
        incl    TD_CRITCOUNT(%rbx)
        decl    TD_NEST_COUNT(%rbx)
        popq    %rax
@@ -438,7 +438,7 @@ splz_soft:
        movl    %ecx,%edi               /* C argument */
        incl    TD_NEST_COUNT(%rbx)     /* prevent doreti/splz nesting */
        decl    TD_CRITCOUNT(%rbx)
-       call    sched_ithd              /* YYY must pull in imasks */
+       call    sched_ithd_soft         /* YYY must pull in imasks */
        incl    TD_CRITCOUNT(%rbx)
        decl    TD_NEST_COUNT(%rbx)     /* prevent doreti/splz nesting */
        popq    %rax
index c3cffde..bb7a41a 100644 (file)
@@ -139,12 +139,12 @@ splz(void)
                                --irq;
                                atomic_clear_int(&gd->gd_spending, 1 << irq);
                                irq += FIRST_SOFTINT;
-                               sched_ithd(irq);
+                               sched_ithd_soft(irq);
                        }
                        while ((irq = ffs(gd->gd_fpending)) != 0) {
                                --irq;
                                atomic_clear_int(&gd->gd_fpending, 1 << irq);
-                               sched_ithd(irq);
+                               sched_ithd_hard(irq);
                        }
                }
                crit_exit_noyield(td);
@@ -154,7 +154,7 @@ splz(void)
 /*
  * Allows an unprotected signal handler or mailbox to signal an interrupt
  *
- * For sched_ithd() to properly preempt via lwkt_schedule() we cannot
+ * For sched_ithd_hard() to properly preempt via lwkt_schedule() we cannot
  * enter a critical section here.  We use td_nest_count instead.
  */
 void
@@ -169,7 +169,7 @@ signalintr(int intr)
        } else {
                ++td->td_nest_count;
                atomic_clear_int(&gd->gd_fpending, 1 << intr);
-               sched_ithd(intr);
+               sched_ithd_hard(intr);
                --td->td_nest_count;
        }
 }
index f12e975..a0ad5ca 100644 (file)
@@ -139,12 +139,12 @@ splz(void)
                                --irq;
                                atomic_clear_int(&gd->gd_spending, 1 << irq);
                                irq += FIRST_SOFTINT;
-                               sched_ithd(irq);
+                               sched_ithd_soft(irq);
                        }
                        while ((irq = ffs(gd->gd_fpending)) != 0) {
                                --irq;
                                atomic_clear_int(&gd->gd_fpending, 1 << irq);
-                               sched_ithd(irq);
+                               sched_ithd_hard(irq);
                        }
                }
                crit_exit_noyield(td);
@@ -154,7 +154,7 @@ splz(void)
 /*
  * Allows an unprotected signal handler or mailbox to signal an interrupt
  *
- * For sched_ithd() to properly preempt via lwkt_schedule() we cannot
+ * For sched_ithd_hard() to properly preempt via lwkt_schedule() we cannot
  * enter a critical section here.  We use td_nest_count instead.
  */
 void
@@ -169,7 +169,7 @@ signalintr(int intr)
        } else {
                ++td->td_nest_count;
                atomic_clear_int(&gd->gd_fpending, 1 << intr);
-               sched_ithd(intr);
+               sched_ithd_hard(intr);
                --td->td_nest_count;
        }
 }
index c9fe033..82eb646 100644 (file)
@@ -116,14 +116,15 @@ void *register_int(int intr, inthand2_t *handler, void *arg,
                            const char *name,
                            struct lwkt_serialize *serializer, int flags,
                            int cpuid);
-long get_interrupt_counter(int intr);
+long get_interrupt_counter(int intr, int cpuid);
 
 void unregister_swi(void *id, int intr, int cpuid);
 void unregister_int(void *id, int cpuid);
 void register_randintr(int intr);
 void unregister_randintr(int intr);
 int next_registered_randintr(int intr);
-void sched_ithd(int intr);     /* procedure called from MD */
+void sched_ithd_soft(int intr);        /* procedure called from MD */
+void sched_ithd_hard(int intr);        /* procedure called from MD */
 int ithread_cpuid(int intr);
 
 extern char    eintrnames[];   /* end of intrnames[] */
index bae5d1d..1fb0e8d 100644 (file)
@@ -47,6 +47,7 @@
 #include <sys/ioctl.h>
 #include <sys/sysctl.h>
 #include <sys/vmmeter.h>
+#include <sys/interrupt.h>
 
 #include <vm/vm_param.h>
 
@@ -743,14 +744,14 @@ dointr(void)
        intrcnt = calloc(nintr, sizeof(*intrcnt));
        if (intrcnt == NULL)
                err(1, "malloc");
-       sysctlbyname("hw.intrcnt_all", intrcnt, &size, NULL, 0);
+       sysctlbyname("hw.intrcnt", intrcnt, &size, NULL, 0);
 
        nwidth = 21;
        for (i = 0; i < nintr; ++i) {
                if (nwidth < (int)strlen(intrname[i]))
                        nwidth = (int)strlen(intrname[i]);
        }
-       if (verbose) nwidth += 8;
+       if (verbose) nwidth += 12;
 
        printf("%-*.*s %11s %10s\n",
                nwidth, nwidth, "interrupt", "total", "rate");
@@ -764,7 +765,9 @@ dointr(void)
                        infop = intrname[i];
                        if (verbose && named) {
                                snprintf(irqinfo, sizeof(irqinfo),
-                                        "irq%zd: %s", i, intrname[i]);
+                                        "irq%-3zd %3zd: %s",
+                                        i % MAX_INTS, i / MAX_INTS,
+                                        intrname[i]);
                                infop = irqinfo;
                        }
                        printf("%-*.*s %11lu %10lu\n",