intrcnt: Fix long standing interrupt name/count array mismatch
authorSepherosa Ziehau <sephe@dragonflybsd.org>
Sun, 10 Apr 2011 11:18:17 +0000 (19:18 +0800)
committerSepherosa Ziehau <sephe@dragonflybsd.org>
Sun, 10 Apr 2011 11:30:26 +0000 (19:30 +0800)
hw.intrnames always returns all interrupts' name, while hw.intrcnt
only returns count of interrupts that get installed.  This
mismatching cause utilities like vmstat(8) to report wrong interrupt
counts.

Keep the old symantic of hw.intrcnt and add hw.intrcnt_all, which
returns count of all interrupts.  Let vmstat(8) and systat(1) use
hw.intrcnt_all.

sys/kern/kern_intr.c
usr.bin/systat/vmstat.c
usr.bin/vmstat/vmstat.c

index 31860a1..7d9fa22 100644 (file)
@@ -1077,6 +1077,27 @@ failed:
 SYSCTL_PROC(_hw, OID_AUTO, intrcnt, CTLTYPE_OPAQUE | CTLFLAG_RD,
        NULL, 0, sysctl_intrcnt, "", "Interrupt Counts");
 
+static int
+sysctl_intrcnt_all(SYSCTL_HANDLER_ARGS)
+{
+    struct intr_info *info;
+    int error = 0;
+    int intr;
+
+    for (intr = 0; intr < MAX_INTS; ++intr) {
+       info = &intr_info_ary[intr];
+
+       error = SYSCTL_OUT(req, &info->i_count, sizeof(info->i_count));
+       if (error)
+               goto failed;
+    }
+failed:
+    return(error);
+}
+
+SYSCTL_PROC(_hw, OID_AUTO, intrcnt_all, CTLTYPE_OPAQUE | CTLFLAG_RD,
+       NULL, 0, sysctl_intrcnt_all, "", "Interrupt Counts");
+
 static void
 int_moveto_destcpu(int *orig_cpuid0, int *cpuid0, int intr)
 {
index 6d4e6fe..c4d4bed 100644 (file)
@@ -780,7 +780,7 @@ getinfo(struct Info *ls)
 
        if (nintr) {
                size = nintr * sizeof(ls->intrcnt[0]);
-               sysctlbyname("hw.intrcnt", ls->intrcnt, &size, NULL, 0);
+               sysctlbyname("hw.intrcnt_all", ls->intrcnt, &size, NULL, 0);
        }
        size = sizeof(ls->Total);
        if (sysctlbyname("vm.vmtotal", &ls->Total, &size, NULL, 0) < 0) {
index 7755821..ac5cbb3 100644 (file)
@@ -743,7 +743,7 @@ dointr(void)
        intrcnt = calloc(nintr, sizeof(*intrcnt));
        if (intrcnt == NULL)
                err(1, "malloc");
-       sysctlbyname("hw.intrcnt", intrcnt, &size, NULL, 0);
+       sysctlbyname("hw.intrcnt_all", intrcnt, &size, NULL, 0);
 
        nwidth = 21;
        for (i = 0; i < nintr; ++i) {