Index: sys/kern/kern_intr.c =================================================================== --- sys/kern/kern_intr.c +++ sys/kern/kern_intr.c @@ -48,7 +48,6 @@ #include #include #include -#include #include #include #include @@ -95,9 +94,6 @@ SYSCTL_INT(_hw, OID_AUTO, intr_storm_threshold, CTLFLAG_RWTUN, &intr_storm_threshold, 0, "Number of consecutive interrupts before storm protection is enabled"); -static int intr_epoch_batch = 1000; -SYSCTL_INT(_hw, OID_AUTO, intr_epoch_batch, CTLFLAG_RWTUN, &intr_epoch_batch, - 0, "Maximum interrupt handler executions without re-entering epoch(9)"); static TAILQ_HEAD(, intr_event) event_list = TAILQ_HEAD_INITIALIZER(event_list); static struct mtx event_lock; @@ -591,8 +587,6 @@ ih->ih_flags |= IH_MPSAFE; if (flags & INTR_ENTROPY) ih->ih_flags |= IH_ENTROPY; - if (flags & INTR_TYPE_NET) - ih->ih_flags |= IH_NET; /* We can only have one exclusive handler in a event. */ mtx_lock(&ie->ie_lock); @@ -940,6 +934,15 @@ return (0); } +static void +intr_event_schedule_handlers(struct intr_event *ie) +{ + struct intr_handler *ih; + + CK_SLIST_FOREACH(ih, &ie->ie_handlers, ih_next) + atomic_store_rel_int(&ih->ih_need, 1); +} + static int intr_event_schedule_thread(struct intr_event *ie) { @@ -971,6 +974,8 @@ KASSERT(td->td_proc != NULL, ("ithread %s has no process", ie->ie_name)); + intr_event_schedule_handlers(ie); + /* * Set it_need to tell the thread to keep running if it is already * running. Then, lock the thread and see if we actually need to @@ -1063,7 +1068,7 @@ * running it will execute this handler on the next pass. Otherwise, * it will execute it the next time it runs. */ - ih->ih_need = 1; + atomic_store_rel_int(&ih->ih_need, 1); if (!(flags & SWI_DELAY)) { VM_CNT_INC(v_soft); @@ -1085,6 +1090,13 @@ return (intr_event_remove_handler(cookie)); } +bool +intr_handler_needs_execution(struct intr_handler *ih) +{ + + return (atomic_cmpset_int(&ih->ih_need, 1, 0)); +} + static void intr_event_execute_handlers(struct proc *p, struct intr_event *ie) { @@ -1138,8 +1150,7 @@ * means that there is no request to execute handlers, * so a retry of the cmpset is not needed. */ - if ((ie->ie_flags & IE_SOFT) != 0 && - atomic_cmpset_int(&ih->ih_need, 1, 0) == 0) + if (intr_handler_needs_execution(ih) == false) continue; /* Execute this handler. */ @@ -1202,12 +1213,11 @@ static void ithread_loop(void *arg) { - struct epoch_tracker et; struct intr_thread *ithd; struct intr_event *ie; struct thread *td; struct proc *p; - int wake, epoch_count; + int wake; td = curthread; p = td->td_proc; @@ -1242,21 +1252,8 @@ * that the load of ih_need in ithread_execute_handlers() * is ordered after the load of it_need here. */ - if (ie->ie_hflags & IH_NET) { - epoch_count = 0; - NET_EPOCH_ENTER(et); - } - while (atomic_cmpset_acq_int(&ithd->it_need, 1, 0) != 0) { + while (atomic_cmpset_acq_int(&ithd->it_need, 1, 0) != 0) ithread_execute_handlers(p, ie); - if ((ie->ie_hflags & IH_NET) && - ++epoch_count >= intr_epoch_batch) { - NET_EPOCH_EXIT(et); - epoch_count = 0; - NET_EPOCH_ENTER(et); - } - } - if (ie->ie_hflags & IH_NET) - NET_EPOCH_EXIT(et); WITNESS_WARN(WARN_PANIC, NULL, "suspending ithread"); mtx_assert(&Giant, MA_NOTOWNED); Index: sys/sys/interrupt.h =================================================================== --- sys/sys/interrupt.h +++ sys/sys/interrupt.h @@ -58,7 +58,6 @@ }; /* Interrupt handle flags kept in ih_flags */ -#define IH_NET 0x00000001 /* Network. */ #define IH_EXCLUSIVE 0x00000002 /* Exclusive interrupt. */ #define IH_ENTROPY 0x00000004 /* Device is a good entropy source. */ #define IH_DEAD 0x00000008 /* Handler should be removed. */ @@ -192,6 +191,7 @@ int intr_event_resume_handler(void *cookie); int intr_getaffinity(int irq, int mode, void *mask); void *intr_handler_source(void *cookie); +bool intr_handler_needs_execution(struct intr_handler *); int intr_setaffinity(int irq, int mode, void *mask); void _intr_drain(int irq); /* Linux compat only. */ int swi_add(struct intr_event **eventp, const char *name,