Module Name: src
Committed By: thorpej
Date: Mon Jan 15 02:13:16 UTC 2024
Modified Files:
src/sys/arch/m68k/include: intr.h
src/sys/arch/m68k/m68k: m68k_intr.c
Log Message:
Add the "ISR priority" notion that's used on some m68k platforms:
/*
* Some devices are particularly sensitive to interrupt
* handling latency. Unbuffered serial ports, for example,
* can lose data if their interrupts aren't handled with
* reasonable speed. For this reason, we sort interrupt
* handlers by an abstract "ISR" priority, inserting higher-
* priority interrupts before lower-priority interrupts.
*/
(...within the same shared auto-vectored interrupt list.)
To generate a diff of this commit:
cvs rdiff -u -r1.1 -r1.2 src/sys/arch/m68k/include/intr.h
cvs rdiff -u -r1.3 -r1.4 src/sys/arch/m68k/m68k/m68k_intr.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/arch/m68k/include/intr.h
diff -u src/sys/arch/m68k/include/intr.h:1.1 src/sys/arch/m68k/include/intr.h:1.2
--- src/sys/arch/m68k/include/intr.h:1.1 Sun Jan 14 22:32:32 2024
+++ src/sys/arch/m68k/include/intr.h Mon Jan 15 02:13:16 2024
@@ -1,4 +1,4 @@
-/* $NetBSD: intr.h,v 1.1 2024/01/14 22:32:32 thorpej Exp $ */
+/* $NetBSD: intr.h,v 1.2 2024/01/15 02:13:16 thorpej Exp $ */
/*-
* Copyright (c) 2023, 2024 The NetBSD Foundation, Inc.
@@ -49,6 +49,18 @@
#define IPL_HIGH 7 /* blocks all interrupts */
#define NIPL 8
+/*
+ * Abstract ISR priorities. These allow sorting of latency-sensitive
+ * devices earlier on the shared auto-vectored interrupt lists.
+ */
+#define ISRPRI_BIO 0 /* a block I/O device */
+#define ISRPRI_MISC 0 /* misc. devices */
+#define ISRPRI_NET 1 /* a network interface */
+#define ISRPRI_TTY 2 /* a serial port */
+#define ISRPRI_DISPLAY 2 /* display devices / framebuffers */
+#define ISRPRI_TTYNOBUF 3 /* a particularly bad serial port */
+#define ISRPRI_AUDIO 4 /* audio devices */
+
#if defined(_KERNEL) || defined(_KMEMUSER)
typedef struct {
uint16_t _psl; /* physical manifestation of logical IPL_* */
@@ -108,6 +120,7 @@ struct m68k_intrhand {
struct evcnt *ih_evcnt;
int ih_ipl; /* m68k IPL, not IPL_* */
int ih_vec;
+ int ih_isrpri;
};
LIST_HEAD(m68k_intrhand_list, m68k_intrhand);
Index: src/sys/arch/m68k/m68k/m68k_intr.c
diff -u src/sys/arch/m68k/m68k/m68k_intr.c:1.3 src/sys/arch/m68k/m68k/m68k_intr.c:1.4
--- src/sys/arch/m68k/m68k/m68k_intr.c:1.3 Mon Jan 15 00:37:08 2024
+++ src/sys/arch/m68k/m68k/m68k_intr.c Mon Jan 15 02:13:16 2024
@@ -1,4 +1,4 @@
-/* $NetBSD: m68k_intr.c,v 1.3 2024/01/15 00:37:08 thorpej Exp $ */
+/* $NetBSD: m68k_intr.c,v 1.4 2024/01/15 02:13:16 thorpej Exp $ */
/*-
* Copyright (c) 1996, 2023, 2024 The NetBSD Foundation, Inc.
@@ -34,7 +34,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: m68k_intr.c,v 1.3 2024/01/15 00:37:08 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: m68k_intr.c,v 1.4 2024/01/15 02:13:16 thorpej Exp $");
#define _M68K_INTR_PRIVATE
@@ -208,7 +208,7 @@ m68k_intr_init(const struct m68k_ih_allo
*/
void *
m68k_intr_establish(int (*func)(void *), void *arg, struct evcnt *ev,
- int vec, int ipl, int isrpri __unused, int flags __unused)
+ int vec, int ipl, int isrpri, int flags __unused)
{
struct m68k_intrhand *ih;
int s;
@@ -242,6 +242,7 @@ m68k_intr_establish(int (*func)(void *),
ih->ih_arg = arg;
ih->ih_vec = vec;
ih->ih_ipl = ipl;
+ ih->ih_isrpri = isrpri;
if ((ih->ih_evcnt = ev) == NULL) {
ih->ih_evcnt = &bitbucket;
}
@@ -260,8 +261,32 @@ m68k_intr_establish(int (*func)(void *),
}
#endif
+ /*
+ * Some devices are particularly sensitive to interrupt
+ * handling latency. Unbuffered serial ports, for example,
+ * can lose data if their interrupts aren't handled with
+ * reasonable speed. For this reason, we sort interrupt
+ * handlers by an abstract "ISR" priority, inserting higher-
+ * priority interrupts before lower-priority interrupts.
+ */
+ struct m68k_intrhand_list * const list = &m68k_intrhands_autovec[ipl];
+ struct m68k_intrhand *curih;
+
s = splhigh();
- LIST_INSERT_HEAD(&m68k_intrhands_autovec[ipl], ih, ih_link);
+ if (LIST_EMPTY(list)) {
+ LIST_INSERT_HEAD(list, ih, ih_link);
+ goto done;
+ }
+ for (curih = LIST_FIRST(list);
+ LIST_NEXT(curih, ih_link) != NULL;
+ curih = LIST_NEXT(curih, ih_link)) {
+ if (ih->ih_isrpri > curih->ih_isrpri) {
+ LIST_INSERT_BEFORE(curih, ih, ih_link);
+ goto done;
+ }
+ }
+ LIST_INSERT_AFTER(curih, ih, ih_link);
+ done:
splx(s);
return ih;