diff options
author | jake <jake@FreeBSD.org> | 2001-10-20 16:03:41 +0000 |
---|---|---|
committer | jake <jake@FreeBSD.org> | 2001-10-20 16:03:41 +0000 |
commit | 21fd58664dc89376f0ffdc3776d8febdcd12b36c (patch) | |
tree | 72d78be332c715f67ae5951e37f9d475b006b19b /sys/sparc64 | |
parent | c2c8a8c21ac2bb655b852cee3f1bce43666b2019 (diff) | |
download | FreeBSD-src-21fd58664dc89376f0ffdc3776d8febdcd12b36c.zip FreeBSD-src-21fd58664dc89376f0ffdc3776d8febdcd12b36c.tar.gz |
Change the stray count in struct intr_vector to a vector number that can
be used to index tables of counters.
Remove intr_dispatch() inline, it is implemented directly in tl*_intr now.
Count stray interrupts in a table of counters like intrcnt.
Disable interrupts briefly when setting up the interrupt vector table.
We must disable interrupts completely, not just raise the pil.
Pass pointers to the intr_vector structures rather than a vector number
to sched_ithd and intr_stray.
Diffstat (limited to 'sys/sparc64')
-rw-r--r-- | sys/sparc64/include/intr_machdep.h | 10 | ||||
-rw-r--r-- | sys/sparc64/sparc64/intr_machdep.c | 74 |
2 files changed, 42 insertions, 42 deletions
diff --git a/sys/sparc64/include/intr_machdep.h b/sys/sparc64/include/intr_machdep.h index 8f1f938..01546e4 100644 --- a/sys/sparc64/include/intr_machdep.h +++ b/sys/sparc64/include/intr_machdep.h @@ -68,23 +68,17 @@ struct intr_queue { struct ithd; struct intr_vector { - iv_func_t *iv_func; /* must be first */ + iv_func_t *iv_func; void *iv_arg; struct ithd *iv_ithd; u_int iv_pri; - int iv_stray; + u_int iv_vec; }; extern struct intr_handler intr_handlers[]; extern struct intr_queue intr_queues[]; extern struct intr_vector intr_vectors[]; -static __inline void -intr_dispatch(int level, struct trapframe *tf) -{ - intr_handlers[level].ih_func(tf); -} - void intr_setup(int level, ih_func_t *ihf, int pri, iv_func_t *ivf, void *iva); void intr_init(void); diff --git a/sys/sparc64/sparc64/intr_machdep.c b/sys/sparc64/sparc64/intr_machdep.c index 3c26be0..40186a1 100644 --- a/sys/sparc64/sparc64/intr_machdep.c +++ b/sys/sparc64/sparc64/intr_machdep.c @@ -74,20 +74,18 @@ #include <sys/pcpu.h> #include <sys/vmmeter.h> - #include <machine/frame.h> #include <machine/globals.h> #include <machine/intr_machdep.h> - -#define NCPU MAXCPU - #define MAX_STRAY_LOG 5 struct intr_handler intr_handlers[NPIL]; -struct intr_queue intr_queues[NCPU]; +struct intr_queue intr_queues[MAXCPU]; struct intr_vector intr_vectors[NIV]; +u_long intr_stray_count[NIV]; + /* protect the intr_vectors table */ static struct mtx intr_table_lock; @@ -104,14 +102,14 @@ intr_dequeue(struct trapframe *tf) u_long tail; crit = critical_enter(); - iq = PCPU_GET(iq); + iq = PCPU_PTR(iq); for (head = iq->iq_head;; head = next) { for (tail = iq->iq_tail; tail != head;) { iqe = &iq->iq_queue[tail]; - /* XXX: add per-vector counts... */ - atomic_add_int(&cnt.v_intr, 1); - if (iqe->iqe_func != NULL) - iqe->iqe_func(iqe->iqe_arg); + atomic_add_long(&intrcnt[iqe->iqe_vec], 1); + KASSERT(iqe->iqe_func != NULL, + ("intr_dequeue: iqe->iqe_func NULL")); + iqe->iqe_func(iqe->iqe_arg); tail = (tail + 1) & IQ_MASK; } iq->iq_tail = tail; @@ -125,26 +123,33 @@ intr_dequeue(struct trapframe *tf) void intr_setup(int pri, ih_func_t *ihf, int vec, iv_func_t *ivf, void *iva) { + u_long ps; + + ps = rdpr(pstate); + if (ps & PSTATE_IE) + wrpr(pstate, ps, PSTATE_IE); if (vec != -1) { intr_vectors[vec].iv_func = ivf; intr_vectors[vec].iv_arg = iva; intr_vectors[vec].iv_pri = pri; + intr_vectors[vec].iv_vec = vec; } intr_handlers[pri].ih_func = ihf; + wrpr(pstate, ps, 0); } static void intr_stray(void *cookie) { - int vec; + struct intr_vector *iv; - vec = (int)(uintptr_t)cookie; - if (intr_vectors[vec].iv_stray < MAX_STRAY_LOG) { - printf("stray interrupt %d\n", vec); - atomic_add_int(&intr_vectors[vec].iv_stray, 1); - if (intr_vectors[vec].iv_stray == MAX_STRAY_LOG) + iv = cookie; + if (intr_stray_count[iv->iv_vec] < MAX_STRAY_LOG) { + printf("stray interrupt %d\n", iv->iv_vec); + atomic_add_long(&intr_stray_count[iv->iv_vec], 1); + if (intr_stray_count[iv->iv_vec] >= MAX_STRAY_LOG) printf("got %d stray interrupt %d's: not logging " - "anymore\n", MAX_STRAY_LOG, vec); + "anymore\n", MAX_STRAY_LOG, iv->iv_vec); } } @@ -164,23 +169,24 @@ intr_init() static void sched_ithd(void *cookie) { - int vec; + struct intr_vector *iv; int error; - vec = (uintptr_t)cookie; + iv = cookie; #ifdef notyet - error = ithread_schedule(intr_vectors[vec].iv_ithd); + error = ithread_schedule(iv->iv_ithd); #else - error = ithread_schedule(intr_vectors[vec].iv_ithd, 0); + error = ithread_schedule(iv->iv_ithd, 0); #endif if (error == EINVAL) - intr_stray(cookie); + intr_stray(iv); } int inthand_add(const char *name, int vec, void (*handler)(void *), void *arg, int flags, void **cookiep) { + struct intr_vector *iv; struct ithd *ithd; /* descriptor for the IRQ */ int errcode = 0; int created_ithd = 0; @@ -189,8 +195,9 @@ inthand_add(const char *name, int vec, void (*handler)(void *), void *arg, * Work around a race where more than one CPU may be registering * handlers on the same IRQ at the same time. */ + iv = &intr_vectors[vec]; mtx_lock_spin(&intr_table_lock); - ithd = intr_vectors[vec].iv_ithd; + ithd = iv->iv_ithd; mtx_unlock_spin(&intr_table_lock); if (ithd == NULL) { errcode = ithread_create(&ithd, vec, 0, NULL, NULL, "intr%d:", @@ -198,15 +205,15 @@ inthand_add(const char *name, int vec, void (*handler)(void *), void *arg, if (errcode) return (errcode); mtx_lock_spin(&intr_table_lock); - if (intr_vectors[vec].iv_ithd == NULL) { - intr_vectors[vec].iv_ithd = ithd; + if (iv->iv_ithd == NULL) { + iv->iv_ithd = ithd; created_ithd++; mtx_unlock_spin(&intr_table_lock); } else { struct ithd *orphan; orphan = ithd; - ithd = intr_vectors[vec].iv_ithd; + ithd = iv->iv_ithd; mtx_unlock_spin(&intr_table_lock); ithread_destroy(orphan); } @@ -216,8 +223,7 @@ inthand_add(const char *name, int vec, void (*handler)(void *), void *arg, ithread_priority(flags), flags, cookiep); if ((flags & INTR_FAST) == 0 || errcode) { - intr_setup(PIL_ITHREAD, intr_dequeue, vec, sched_ithd, - (void *)(uintptr_t)vec); + intr_setup(PIL_ITHREAD, intr_dequeue, vec, sched_ithd, iv); errcode = 0; } @@ -227,7 +233,7 @@ inthand_add(const char *name, int vec, void (*handler)(void *), void *arg, if (flags & INTR_FAST) intr_setup(PIL_FAST, intr_dequeue, vec, handler, arg); - intr_vectors[vec].iv_stray = 0; + intr_stray_count[vec] = 0; /* XXX: name is not yet used. */ return (0); } @@ -235,6 +241,7 @@ inthand_add(const char *name, int vec, void (*handler)(void *), void *arg, int inthand_remove(int vec, void *cookie) { + struct intr_vector *iv; int error; error = ithread_remove_handler(cookie); @@ -243,13 +250,12 @@ inthand_remove(int vec, void *cookie) * XXX: maybe this should be done regardless of whether * ithread_remove_handler() succeeded? */ + iv = &intr_vectors[vec]; mtx_lock_spin(&intr_table_lock); - if (intr_vectors[vec].iv_ithd == NULL) { - intr_setup(PIL_ITHREAD, intr_dequeue, vec, intr_stray, - (void *)(uintptr_t)vec); + if (iv->iv_ithd == NULL) { + intr_setup(PIL_ITHREAD, intr_dequeue, vec, intr_stray, iv); } else { - intr_setup(PIL_LOW, intr_dequeue, vec, sched_ithd, - (void *)(uintptr_t)vec); + intr_setup(PIL_LOW, intr_dequeue, vec, sched_ithd, iv); } mtx_unlock_spin(&intr_table_lock); } |