svn commit: r245637 - in head/sys/arm: arm include
Ian Lepore
ian at FreeBSD.org
Sat Jan 19 00:50:14 UTC 2013
Author: ian
Date: Sat Jan 19 00:50:12 2013
New Revision: 245637
URL: http://svnweb.freebsd.org/changeset/base/245637
Log:
Eliminate the need for an intermediate array of indices into the arrays of
interrupt counts and names, by making the names into an array of fixed-length
strings that can be directly indexed. This eliminates extra memory accesses
on every interrupt to increment the counts.
As a side effect, it also fixes a bug that would corrupt the names data
if a name was longer than MAXCOMLEN, which led to incorrect vmstat -i output.
Approved by: cognet (mentor)
Modified:
head/sys/arm/arm/intr.c
head/sys/arm/arm/machdep.c
head/sys/arm/include/intr.h
Modified: head/sys/arm/arm/intr.c
==============================================================================
--- head/sys/arm/arm/intr.c Sat Jan 19 00:37:17 2013 (r245636)
+++ head/sys/arm/arm/intr.c Sat Jan 19 00:50:12 2013 (r245637)
@@ -50,23 +50,40 @@ __FBSDID("$FreeBSD$");
#include <machine/intr.h>
#include <machine/cpu.h>
+#define INTRNAME_LEN (MAXCOMLEN + 1)
+
typedef void (*mask_fn)(void *);
static struct intr_event *intr_events[NIRQ];
-static int intrcnt_tab[NIRQ];
-static int intrcnt_index = 0;
-static int last_printed = 0;
void arm_handler_execute(struct trapframe *, int);
void (*arm_post_filter)(void *) = NULL;
+/*
+ * Pre-format intrnames into an array of fixed-size strings containing spaces.
+ * This allows us to avoid the need for an intermediate table of indices into
+ * the names and counts arrays, while still meeting the requirements and
+ * assumptions of vmstat(8) and the kdb "show intrcnt" command, the two
+ * consumers of this data.
+ */
+void
+arm_intrnames_init()
+{
+ int i;
+
+ memset(intrnames, ' ', NIRQ * INTRNAME_LEN);
+ for (i = 0; i < NIRQ; ++i)
+ intrnames[i * INTRNAME_LEN - 1] = 0;
+}
+
void
arm_setup_irqhandler(const char *name, driver_filter_t *filt,
void (*hand)(void*), void *arg, int irq, int flags, void **cookiep)
{
struct intr_event *event;
int error;
+ char namebuf[INTRNAME_LEN];
if (irq < 0 || irq >= NIRQ)
return;
@@ -78,14 +95,9 @@ arm_setup_irqhandler(const char *name, d
if (error)
return;
intr_events[irq] = event;
- last_printed +=
- snprintf(intrnames + last_printed,
- MAXCOMLEN + 1,
- "irq%d: %s", irq, name);
- last_printed++;
- intrcnt_tab[irq] = intrcnt_index;
- intrcnt_index++;
-
+ snprintf(namebuf, sizeof(namebuf), "irq%d: %s", irq, name);
+ sprintf(intrnames + INTRNAME_LEN * irq, "%-*s",
+ INTRNAME_LEN - 1, namebuf);
}
intr_event_add_handler(event, name, filt, hand, arg,
intr_priority(flags), flags, cookiep);
@@ -122,7 +134,7 @@ arm_handler_execute(struct trapframe *fr
PCPU_INC(cnt.v_intr);
i = -1;
while ((i = arm_get_next_irq(i)) != -1) {
- intrcnt[intrcnt_tab[i]]++;
+ intrcnt[i]++;
event = intr_events[i];
if (intr_event_handle(event, frame) != 0) {
/* XXX: Log stray IRQs */
Modified: head/sys/arm/arm/machdep.c
==============================================================================
--- head/sys/arm/arm/machdep.c Sat Jan 19 00:37:17 2013 (r245636)
+++ head/sys/arm/arm/machdep.c Sat Jan 19 00:50:12 2013 (r245637)
@@ -1474,6 +1474,7 @@ initarm(struct arm_boot_params *abp)
init_proc0(kernelstack.pv_va);
+ arm_intrnames_init();
arm_vector_init(ARM_VECTORS_HIGH, ARM_VEC_ALL);
arm_dump_avail_init(memsize, sizeof(dump_avail) / sizeof(dump_avail[0]));
pmap_bootstrap(freemempos, pmap_bootstrap_lastaddr, &kernel_l1pt);
Modified: head/sys/arm/include/intr.h
==============================================================================
--- head/sys/arm/include/intr.h Sat Jan 19 00:37:17 2013 (r245636)
+++ head/sys/arm/include/intr.h Sat Jan 19 00:50:12 2013 (r245637)
@@ -70,6 +70,7 @@
int arm_get_next_irq(int);
void arm_mask_irq(uintptr_t);
void arm_unmask_irq(uintptr_t);
+void arm_intrnames_init(void);
void arm_setup_irqhandler(const char *, int (*)(void*), void (*)(void*),
void *, int, int, void **);
int arm_remove_irqhandler(int, void *);
More information about the svn-src-head
mailing list