Index: sys/kern/subr_epoch.c =================================================================== --- sys/kern/subr_epoch.c +++ sys/kern/subr_epoch.c @@ -322,23 +322,36 @@ thread_unlock(td); } +/* + * NOTE: epoch_alloc() and epoch_free() should only be called from + * SYSINIT() and SYSUNINIT(), due to internal serialization + * requirements. + */ epoch_t epoch_alloc(const char *name, int flags) { epoch_t epoch; + int i; if (__predict_false(!inited)) panic("%s called too early in boot", __func__); epoch = malloc(sizeof(struct epoch), M_EPOCH, M_ZERO | M_WAITOK); ck_epoch_init(&epoch->e_epoch); epoch_ctor(epoch); - MPASS(epoch_count < MAX_EPOCHS - 2); + + for (i = 0; i != epoch_count; i++) { + if (allepochs[i] == NULL) + break; + } + MPASS(i < MAX_EPOCHS - 2); epoch->e_flags = flags; - epoch->e_idx = epoch_count; + epoch->e_idx = i; epoch->e_name = name; sx_init(&epoch->e_drain_sx, "epoch-drain-sx"); mtx_init(&epoch->e_drain_mtx, "epoch-drain-mtx", NULL, MTX_DEF); - allepochs[epoch_count++] = epoch; + allepochs[i++] = epoch; + if (i > epoch_count) + epoch_count = i; return (epoch); }