gtask
STAILQ_ENTRY(gtask) ta_link; /* (q) link for queue */
grouptaskqueue_enqueue((gtask)->gt_taskqueue, &(gtask)->gt_task)
struct gtask gt_task;
int gtaskqueue_cancel(struct gtaskqueue *queue, struct gtask *gtask);
void gtaskqueue_drain(struct gtaskqueue *queue, struct gtask *task);
int grouptaskqueue_enqueue(struct gtaskqueue *queue, struct gtask *task);
void taskqgroup_detach(struct taskqgroup *qgroup, struct grouptask *gtask);
void taskqgroup_config_gtask_init(void *ctx, struct grouptask *gtask,
void taskqgroup_config_gtask_deinit(struct grouptask *gtask);
#define GTASK_INIT(gtask, flags, priority, func, context) do { \
(gtask)->ta_flags = flags; \
(gtask)->ta_priority = (priority); \
(gtask)->ta_func = (func); \
(gtask)->ta_context = (context); \
#define GROUPTASK_INIT(gtask, priority, func, context) \
GTASK_INIT(&(gtask)->gt_task, TASK_SKIP_WAKEUP, priority, func, context)
#define GROUPTASK_ENQUEUE(gtask) \
struct grouptask *gtask = info->ifi_task;
GROUPTASK_ENQUEUE(gtask);
struct grouptask *gtask = info->ifi_task;
GROUPTASK_ENQUEUE(gtask);
int qid, struct grouptask *gtask, struct taskqgroup *tqg, void *uniq,
err = taskqgroup_attach_cpu(tqg, gtask, uniq, cpuid, dev,
struct grouptask *gtask;
gtask = &subctx->ifc_rxqs[qid].ifr_task;
NET_GROUPTASK_INIT(gtask, 0, fn, q);
info->ifi_task = gtask;
NET_GROUPTASK_INIT(gtask, 0, fn, q);
err = iflib_irq_set_affinity(ctx, irq, type, qid, gtask, tqg, q,
taskqgroup_attach(tqg, gtask, q, dev, irq->ii_res, name);
struct grouptask *gtask;
gtask = &ctx->ifc_txqs[qid].ift_task;
GROUPTASK_INIT(gtask, 0, fn, q);
gtask = &ctx->ifc_rxqs[qid].ifr_task;
NET_GROUPTASK_INIT(gtask, 0, fn, q);
gtask = &ctx->ifc_rxqs[qid].ifr_task;
NET_GROUPTASK_INIT(gtask, 0, fn, q);
gtask = NULL;
info->ifi_task = gtask;
err = iflib_irq_set_affinity(ctx, irq, type, qid, gtask, tqg, q,
taskqgroup_attach(tqg, gtask, q, dev, irq->ii_res, name);
struct grouptask *gtask;
gtask = &ctx->ifc_txqs[qid].ift_task;
GROUPTASK_INIT(gtask, 0, fn, q);
gtask = &ctx->ifc_rxqs[qid].ifr_task;
NET_GROUPTASK_INIT(gtask, 0, fn, q);
err = iflib_irq_set_affinity(ctx, irq, type, qid, gtask, tqg, q, name);
taskqgroup_attach(tqg, gtask, q, dev, irq ? irq->ii_res : NULL,
struct grouptask *gtask;
gtask = &rxq->ifr_task;
info->ifi_task = gtask;
NET_GROUPTASK_INIT(gtask, 0, _task_fn_rx, rxq);
taskqgroup_attach(qgroup_if_io_tqg, gtask, rxq, dev, res, name);
while ((gtask = LIST_FIRST(>ask_head))) {
LIST_REMOVE(gtask, gt_list);
if (gtask->gt_cpu == -1)
taskqgroup_attach_deferred(qgroup, gtask);
else if (taskqgroup_attach_cpu_deferred(qgroup, gtask))
taskqgroup_attach_deferred(qgroup, gtask);
LIST_FOREACH(gtask, &qgroup->tqg_queue[i].tgc_tasks, gt_list)
MPASS(gtask->gt_taskqueue != NULL);
taskqgroup_config_gtask_init(void *ctx, struct grouptask *gtask, gtask_fn_t *fn,
GROUPTASK_INIT(gtask, 0, fn, ctx);
taskqgroup_attach(qgroup_config, gtask, gtask, NULL, NULL, name);
taskqgroup_config_gtask_deinit(struct grouptask *gtask)
taskqgroup_detach(qgroup_config, gtask);
gtask_dump(struct gtask *gtask)
gtask, gtask->ta_flags, gtask->ta_priority, gtask->ta_func, gtask->ta_context);
struct gtask *gtask = &grouptask->gt_task;
gtask_dump(gtask);
gtask->ta_flags |= TASK_NOENQUEUE;
gtaskqueue_drain_locked(queue, gtask);
struct gtask *gtask = &grouptask->gt_task;
gtask_dump(gtask);
gtask->ta_flags &= ~TASK_NOENQUEUE;
grouptaskqueue_enqueue(struct gtaskqueue *queue, struct gtask *gtask)
gtask_dump(gtask);
if (gtask->ta_flags & TASK_ENQUEUED) {
if (gtask->ta_flags & TASK_NOENQUEUE) {
STAILQ_INSERT_TAIL(&queue->tq_queue, gtask, ta_link);
gtask->ta_flags |= TASK_ENQUEUED;
struct gtask t_barrier;
struct gtask *gtask;
gtask = STAILQ_FIRST(&queue->tq_queue);
KASSERT(gtask != NULL, ("task is NULL"));
gtask->ta_flags &= ~TASK_ENQUEUED;
tb.tb_running = gtask;
KASSERT(gtask->ta_func != NULL, ("task->ta_func is NULL"));
gtask->ta_func(gtask->ta_context);
wakeup(gtask);
task_is_running(struct gtaskqueue *queue, struct gtask *gtask)
if (tb->tb_running == gtask)
gtaskqueue_cancel_locked(struct gtaskqueue *queue, struct gtask *gtask)
if (gtask->ta_flags & TASK_ENQUEUED)
STAILQ_REMOVE(&queue->tq_queue, gtask, gtask, ta_link);
gtask->ta_flags &= ~TASK_ENQUEUED;
return (task_is_running(queue, gtask) ? EBUSY : 0);
gtaskqueue_cancel(struct gtaskqueue *queue, struct gtask *gtask)
error = gtaskqueue_cancel_locked(queue, gtask);
gtaskqueue_drain_locked(struct gtaskqueue *queue, struct gtask *gtask)
while ((gtask->ta_flags & TASK_ENQUEUED) || task_is_running(queue, gtask))
TQ_SLEEP(queue, gtask, &queue->tq_mutex, PWAIT, "-", 0);
gtaskqueue_drain(struct gtaskqueue *queue, struct gtask *gtask)
gtaskqueue_drain_locked(queue, gtask);
static int task_is_running(struct gtaskqueue *queue, struct gtask *gtask);
static void gtaskqueue_drain_locked(struct gtaskqueue *queue, struct gtask *gtask);
struct gtask bt_task;
struct gtask *tb_running;
static struct gtask * const TB_DRAIN_WAITER = (struct gtask *)0x1;
taskqgroup_attach(struct taskqgroup *qgroup, struct grouptask *gtask,
gtask->gt_uniq = uniq;
snprintf(gtask->gt_name, GROUPTASK_NAMELEN, "%s", name ? name : "grouptask");
gtask->gt_dev = dev;
gtask->gt_irq = irq;
gtask->gt_cpu = -1;
LIST_INSERT_HEAD(&qgroup->tqg_queue[qid].tgc_tasks, gtask, gt_list);
gtask->gt_taskqueue = qgroup->tqg_queue[qid].tgc_taskq;
gtask->gt_cpu = cpu;
__func__, gtask->gt_name, error);
STAILQ_HEAD(, gtask) tq_queue;
taskqgroup_attach_deferred(struct taskqgroup *qgroup, struct grouptask *gtask)
qid = taskqgroup_find(qgroup, gtask->gt_uniq);
if (gtask->gt_dev != NULL && gtask->gt_irq != NULL) {
error = bus_bind_intr(gtask->gt_dev, gtask->gt_irq, cpu);
__func__, gtask->gt_name, error);
LIST_INSERT_HEAD(&qgroup->tqg_queue[qid].tgc_tasks, gtask, gt_list);
gtask->gt_taskqueue = qgroup->tqg_queue[qid].tgc_taskq;
taskqgroup_attach_cpu(struct taskqgroup *qgroup, struct grouptask *gtask,
gtask->gt_uniq = uniq;
snprintf(gtask->gt_name, GROUPTASK_NAMELEN, "%s", name ? name : "grouptask");
gtask->gt_dev = dev;
gtask->gt_irq = irq;
gtask->gt_cpu = cpu;
printf("%s: qid not found for %s cpu=%d\n", __func__, gtask->gt_name, cpu);
LIST_INSERT_HEAD(&qgroup->tqg_queue[qid].tgc_tasks, gtask, gt_list);
gtask->gt_taskqueue = qgroup->tqg_queue[qid].tgc_taskq;
__func__, gtask->gt_name, error);
taskqgroup_attach_cpu_deferred(struct taskqgroup *qgroup, struct grouptask *gtask)
dev = gtask->gt_dev;
irq = gtask->gt_irq;
cpu = gtask->gt_cpu;
printf("%s: qid not found for %s cpu=%d\n", __func__, gtask->gt_name, cpu);
LIST_INSERT_HEAD(&qgroup->tqg_queue[qid].tgc_tasks, gtask, gt_list);
gtask->gt_taskqueue = qgroup->tqg_queue[qid].tgc_taskq;
__func__, gtask->gt_name, error);
taskqgroup_detach(struct taskqgroup *qgroup, struct grouptask *gtask)
grouptask_block(gtask);
if (qgroup->tqg_queue[i].tgc_taskq == gtask->gt_taskqueue)
panic("%s: task %s not in group", __func__, gtask->gt_name);
LIST_REMOVE(gtask, gt_list);
gtask->gt_taskqueue = NULL;
gtask->gt_task.ta_flags &= ~TASK_NOENQUEUE;
struct taskq_bind_task *gtask = (struct taskq_bind_task *)ctx;
CPU_SET(gtask->bt_cpuid, &mask);
sched_bind(curthread, gtask->bt_cpuid);
free(gtask, M_DEVBUF);
struct taskq_bind_task *gtask;
gtask = malloc(sizeof (*gtask), M_DEVBUF, M_WAITOK);
GTASK_INIT(>ask->bt_task, 0, 0, taskqgroup_binder, gtask);
gtask->bt_cpuid = qgroup->tqg_queue[i].tgc_cpu;
>ask->bt_task);
struct grouptask *gtask;
while ((gtask = LIST_FIRST(&qgroup->tqg_queue[i].tgc_tasks))) {
LIST_REMOVE(gtask, gt_list);
LIST_INSERT_HEAD(>ask_head, gtask, gt_list);