@@ -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 */
11461156static 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