Index: sys/kern/subr_gtaskqueue.c =================================================================== --- sys/kern/subr_gtaskqueue.c +++ sys/kern/subr_gtaskqueue.c @@ -675,11 +675,15 @@ struct taskqgroup { struct taskqgroup_cpu tqg_queue[MAXCPU]; struct mtx tqg_lock; + void (*adjust_func)(void*); char * tqg_name; int tqg_adjusting; int tqg_stride; int tqg_cnt; + int tqg_flags; }; +#define TQG_NEED_ADJUST 0x1 +#define TQG_ADJUSTED 0x2 struct taskq_bind_task { struct gtask bt_task; @@ -786,6 +790,14 @@ gtask->gt_name = name; gtask->gt_irq = irq; gtask->gt_cpu = -1; + + mtx_lock(&qgroup->tqg_lock); + qgroup->tqg_flags |= TQG_NEED_ADJUST; + mtx_unlock(&qgroup->tqg_lock); + + if (tqg_smp_started && !(qgroup->tqg_flags & TQG_ADJUSTED)) + qgroup->adjust_func(NULL); + mtx_lock(&qgroup->tqg_lock); qid = taskqgroup_find(qgroup, uniq); qgroup->tqg_queue[qid].tgc_cnt++; @@ -1062,6 +1074,28 @@ return (error); } +void +taskqgroup_set_adjust(struct taskqgroup *qgroup, void (*adjust_func)(void*)) +{ + qgroup-> adjust_func = adjust_func; +} + +int +taskqgroup_adjust_once(struct taskqgroup *qgroup, int cnt, int stride, bool ithread, int pri) +{ + int error = 0; + + mtx_lock(&qgroup->tqg_lock); + if ((qgroup->tqg_flags & (TQG_ADJUSTED|TQG_NEED_ADJUST)) == TQG_NEED_ADJUST) { + qgroup->tqg_flags |= TQG_ADJUSTED; + error = _taskqgroup_adjust(qgroup, cnt, stride, ithread, pri); + MPASS(error == 0); + } + mtx_unlock(&qgroup->tqg_lock); + + return (error); +} + struct taskqgroup * taskqgroup_create(char *name) { Index: sys/net/iflib.c =================================================================== --- sys/net/iflib.c +++ sys/net/iflib.c @@ -1409,7 +1409,7 @@ iflib_started = 1; } -SYSINIT(iflib_record_started, SI_SUB_SMP + 1, SI_ORDER_FIRST, +SYSINIT(iflib_record_started, SI_SUB_SMP + 1, SI_ORDER_LAST, iflib_record_started, NULL); #endif @@ -5184,7 +5184,7 @@ struct grouptask *gtask; gtask = &ctx->ifc_admin_task; - MPASS(gtask->gt_taskqueue != NULL); + MPASS(gtask != NULL && gtask->gt_taskqueue != NULL); #endif GROUPTASK_ENQUEUE(&ctx->ifc_admin_task); Index: sys/sys/gtaskqueue.h =================================================================== --- sys/sys/gtaskqueue.h +++ sys/sys/gtaskqueue.h @@ -59,6 +59,8 @@ struct taskqgroup *taskqgroup_create(char *name); void taskqgroup_destroy(struct taskqgroup *qgroup); int taskqgroup_adjust(struct taskqgroup *qgroup, int cnt, int stride, bool ithread, int pri); +int taskqgroup_adjust_once(struct taskqgroup *qgroup, int cnt, int stride, bool ithread, int pri); +void taskqgroup_set_adjust(struct taskqgroup *qgroup, void (*adjust_func)(void*)); #define TASK_ENQUEUED 0x1 #define TASK_SKIP_WAKEUP 0x2 @@ -86,22 +88,23 @@ struct taskqgroup *qgroup_##name; \ \ static void \ -taskqgroup_define_##name(void *arg) \ +taskqgroup_adjust_##name(void *arg) \ { \ - qgroup_##name = taskqgroup_create(#name); \ + taskqgroup_adjust_once(qgroup_##name, (cnt), (stride), (intr), (pri)); \ } \ \ -SYSINIT(taskqgroup_##name, SI_SUB_TASKQ, SI_ORDER_FIRST, \ - taskqgroup_define_##name, NULL); \ +SYSINIT(taskqgroup_adj_##name, SI_SUB_SMP, SI_ORDER_ANY, \ + taskqgroup_adjust_##name, NULL); \ \ static void \ -taskqgroup_adjust_##name(void *arg) \ +taskqgroup_define_##name(void *arg) \ { \ - taskqgroup_adjust(qgroup_##name, (cnt), (stride), (intr), (pri)); \ + qgroup_##name = taskqgroup_create(#name); \ + taskqgroup_set_adjust(qgroup_##name, taskqgroup_adjust_##name); \ } \ - \ -SYSINIT(taskqgroup_adj_##name, SI_SUB_SMP, SI_ORDER_ANY, \ - taskqgroup_adjust_##name, NULL) +SYSINIT(taskqgroup_##name, SI_SUB_TASKQ, SI_ORDER_FIRST, \ + taskqgroup_define_##name, NULL) +