Skip to content

Commit 0ed2455

Browse files
committed
kern/intr: implement specialized SWI class
The event compatibility implementation is targeted for compatibility for source not converted to devices. Notably architectures being maintained outside the main tree. SWIs can have lower overhead by removing the full compatibility.
1 parent ad1c581 commit 0ed2455

File tree

1 file changed

+37
-4
lines changed

1 file changed

+37
-4
lines changed

sys/kern/kern_intr.c

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1138,18 +1138,39 @@ intr_event_schedule_thread(struct intr_event *ie, struct trapframe *frame)
11381138
return (0);
11391139
}
11401140

1141+
/*
1142+
* Pseudo-PIC implementation for SWIs swi_add(). Lower overhead than
1143+
* intr_event_create()'s full implementation.
1144+
*/
1145+
1146+
static void
1147+
swi_event_func(device_t pic, interrupt_t *intr)
1148+
{
1149+
}
1150+
11411151
/*
11421152
* Allow interrupt event binding for software interrupt handlers -- a no-op,
11431153
* since interrupts are generated in software rather than being directed by
11441154
* a PIC.
11451155
*/
11461156
static int
1147-
swi_assign_cpu(void *arg, int cpu)
1157+
swi_event_assign(device_t pic, interrupt_t *intr, u_int cpu)
11481158
{
11491159

11501160
return (0);
11511161
}
11521162

1163+
static device_method_t swi_event_methods[] = {
1164+
DEVMETHOD(intr_event_pre_ithread, swi_event_func),
1165+
DEVMETHOD(intr_event_post_ithread, swi_event_func),
1166+
DEVMETHOD(intr_event_post_filter, swi_event_func),
1167+
DEVMETHOD(intr_event_assign_cpu, swi_event_assign),
1168+
1169+
DEVMETHOD_END
1170+
};
1171+
1172+
PRIVATE_DEFINE_CLASSN(swi_event, swi_event_class, swi_event_methods, 0);
1173+
11531174
/*
11541175
* Add a software interrupt handler to a specified event. If a given event
11551176
* is not specified, then a new event is created.
@@ -1170,10 +1191,22 @@ swi_add(struct intr_event **eventp, const char *name, driver_intr_t handler,
11701191
if (!(ie->ie_flags & IE_SOFT))
11711192
return (EINVAL);
11721193
} else {
1173-
error = intr_event_create(&ie, NULL, IE_SOFT, 0,
1174-
NULL, NULL, NULL, swi_assign_cpu, "swi%d:", pri);
1175-
if (error)
1194+
static device_t handler = NULL;
1195+
1196+
if (__predict_false(handler == NULL)) {
1197+
handler = bus_generic_add_child(root_bus,
1198+
BUS_PASS_ORDER_FIRST, "swi-event", 0);
1199+
device_set_driver(handler, &swi_event_class);
1200+
}
1201+
1202+
ie = malloc(sizeof(struct intr_event), M_ITHREAD,
1203+
M_WAITOK | M_ZERO);
1204+
error = intr_event_init_(ie, handler, 0, IE_SOFT, "swi%d:",
1205+
pri);
1206+
if (error) {
1207+
free(ie, M_ITHREAD);
11761208
return (error);
1209+
}
11771210
if (eventp != NULL)
11781211
*eventp = ie;
11791212
}

0 commit comments

Comments
 (0)