Index: sys/kern/subr_epoch.c =================================================================== --- sys/kern/subr_epoch.c +++ sys/kern/subr_epoch.c @@ -234,6 +234,17 @@ } else SLIST_REMOVE_HEAD(&td->td_epochs, et_tlink); } + +/* Used by NOEPOCHASSERT() */ +void +epoch_trace_list(struct thread *td) +{ + epoch_tracker_t iet; + + SLIST_FOREACH(iet, &td->td_epochs, et_tlink) + printf("Epoch %s entered at %s:%d\n", iet->et_epoch->e_name, + iet->et_file, iet->et_line); +} #endif /* EPOCH_TRACE */ static void Index: sys/net/if.c =================================================================== --- sys/net/if.c +++ sys/net/if.c @@ -3582,6 +3582,7 @@ * We are certain we have added something, so call down to the * interface to let them know about it. */ + NOEPOCHASSERT(); if (ifp->if_ioctl != NULL) { (void) (*ifp->if_ioctl)(ifp, SIOCADDMULTI, 0); } Index: sys/sys/epoch.h =================================================================== --- sys/sys/epoch.h +++ sys/sys/epoch.h @@ -83,6 +83,7 @@ void _epoch_enter_preempt(epoch_t epoch, epoch_tracker_t et EPOCH_FILE_LINE); void _epoch_exit_preempt(epoch_t epoch, epoch_tracker_t et EPOCH_FILE_LINE); #ifdef EPOCH_TRACE +void epoch_trace_list(struct thread *); #define epoch_enter_preempt(epoch, et) _epoch_enter_preempt(epoch, et, __FILE__, __LINE__) #define epoch_exit_preempt(epoch, et) _epoch_exit_preempt(epoch, et, __FILE__, __LINE__) #else Index: sys/sys/systm.h =================================================================== --- sys/sys/systm.h +++ sys/sys/systm.h @@ -109,11 +109,27 @@ kassert_panic msg; \ } \ } while (0) -#else +#ifdef EPOCH_TRACE +#define NOEPOCHASSERT() do { \ + if (__predict_false(curthread->td_epochnest > 0)) { \ + epoch_trace_list(curthread); \ + kassert_panic("No epoch assertion failed\n"); \ + } \ +} while (0) +#else /* !EPOCH_TRACE */ +#define NOEPOCHASSERT() do { \ + if (__predict_false(curthread->td_epochnest > 0)) \ + kassert_panic("No epoch assertion failed"); \ +} while (0) +#endif +#else /* !INVARIANTS */ #define KASSERT(exp,msg) do { \ } while (0) #define VNASSERT(exp, vp, msg) do { \ +} while (0) + +#define NOEPOCHASSERT() do { \ } while (0) #endif