Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F107123263
D38437.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
3 KB
Referenced Files
None
Subscribers
None
D38437.diff
View Options
diff --git a/sys/kern/subr_intr.c b/sys/kern/subr_intr.c
--- a/sys/kern/subr_intr.c
+++ b/sys/kern/subr_intr.c
@@ -42,6 +42,7 @@
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/bitstring.h>
#include <sys/bus.h>
#include <sys/conf.h>
#include <sys/cpuset.h>
@@ -152,7 +153,8 @@
char *intrnames;
size_t sintrcnt;
size_t sintrnames;
-static u_int intrcnt_index;
+int nintrcnt;
+static bitstr_t *intrcnt_bitmap;
static struct intr_irqsrc *intr_map_get_isrc(u_int res_id);
static void intr_map_set_isrc(u_int res_id, struct intr_irqsrc *isrc);
@@ -166,7 +168,6 @@
static void
intr_irq_init(void *dummy __unused)
{
- u_int intrcnt_count;
SLIST_INIT(&pic_list);
mtx_init(&pic_list_lock, "intr pic list", NULL, MTX_DEF);
@@ -177,17 +178,21 @@
* - 2 counters for each I/O interrupt.
* - MAXCPU counters for each IPI counters for SMP.
*/
- intrcnt_count = intr_nirq * 2;
+ nintrcnt = intr_nirq * 2;
#ifdef SMP
- intrcnt_count += INTR_IPI_COUNT * MAXCPU;
+ nintrcnt += INTR_IPI_COUNT * MAXCPU;
#endif
- intrcnt = mallocarray(intrcnt_count, sizeof(u_long), M_INTRNG,
+ intrcnt = mallocarray(nintrcnt, sizeof(u_long), M_INTRNG,
M_WAITOK | M_ZERO);
- intrnames = mallocarray(intrcnt_count, INTRNAME_LEN, M_INTRNG,
+ intrnames = mallocarray(nintrcnt, INTRNAME_LEN, M_INTRNG,
M_WAITOK | M_ZERO);
- sintrcnt = intrcnt_count * sizeof(u_long);
- sintrnames = intrcnt_count * INTRNAME_LEN;
+ sintrcnt = nintrcnt * sizeof(u_long);
+ sintrnames = nintrcnt * INTRNAME_LEN;
+
+ /* Allocate the bitmap tracking counter allocations. */
+ intrcnt_bitmap = bit_alloc(nintrcnt, M_INTRNG, M_WAITOK | M_ZERO);
+
irq_sources = mallocarray(intr_nirq, sizeof(struct intr_irqsrc*),
M_INTRNG, M_WAITOK | M_ZERO);
}
@@ -266,13 +271,17 @@
static void
isrc_setup_counters(struct intr_irqsrc *isrc)
{
- u_int index;
+ int index;
+
+ mtx_assert(&isrc_table_lock, MA_OWNED);
/*
- * XXX - it does not work well with removable controllers and
- * interrupt sources !!!
+ * Allocate two counter values, the second tracking "stray" interrupts.
*/
- index = atomic_fetchadd_int(&intrcnt_index, 2);
+ bit_ffc_area(intrcnt_bitmap, nintrcnt, 2, &index);
+ if (index == -1)
+ panic("Failed to allocate 2 counters. Array exhausted?");
+ bit_nset(intrcnt_bitmap, index, index + 1);
isrc->isrc_index = index;
isrc->isrc_count = &intrcnt[index];
isrc_update_name(isrc, NULL);
@@ -284,8 +293,11 @@
static void
isrc_release_counters(struct intr_irqsrc *isrc)
{
+ int idx = isrc->isrc_index;
- panic("%s: not implemented", __func__);
+ mtx_assert(&isrc_table_lock, MA_OWNED);
+
+ bit_nclear(intrcnt_bitmap, idx, idx + 1);
}
#ifdef SMP
@@ -298,11 +310,25 @@
u_int index, i;
char str[INTRNAME_LEN];
- index = atomic_fetchadd_int(&intrcnt_index, MAXCPU);
+ mtx_lock(&isrc_table_lock);
+
+ /*
+ * We should never have a problem finding MAXCPU contiguous counters,
+ * in practice. Interrupts will be allocated sequentially during boot,
+ * so the array should fill from low to high index. Once reserved, the
+ * IPI counters will never be released. Similarly, we will not need to
+ * allocate more IPIs once the system is running.
+ */
+ bit_ffc_area(intrcnt_bitmap, nintrcnt, MAXCPU, &index);
+ if (index == -1)
+ panic("Failed to allocate %d counters. Array exhausted?",
+ MAXCPU);
+ bit_nset(intrcnt_bitmap, index, index + MAXCPU - 1);
for (i = 0; i < MAXCPU; i++) {
snprintf(str, INTRNAME_LEN, "cpu%d:%s", i, name);
intrcnt_setname(str, index + i);
}
+ mtx_unlock(&isrc_table_lock);
return (&intrcnt[index]);
}
#endif
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Jan 11, 11:42 AM (19 h, 59 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15753429
Default Alt Text
D38437.diff (3 KB)
Attached To
Mode
D38437: intrng: track counter allocation with a bitmap
Attached
Detach File
Event Timeline
Log In to Comment