1*fab26bfaSMatthew Dillon /*- 2*fab26bfaSMatthew Dillon * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3*fab26bfaSMatthew Dillon * 4*fab26bfaSMatthew Dillon * Copyright (c) 2014 Jeffrey Roberson <jeff@freebsd.org> 5*fab26bfaSMatthew Dillon * Copyright (c) 2016 Matthew Macy <mmacy@mattmacy.io> 6*fab26bfaSMatthew Dillon * All rights reserved. 7*fab26bfaSMatthew Dillon * 8*fab26bfaSMatthew Dillon * Redistribution and use in source and binary forms, with or without 9*fab26bfaSMatthew Dillon * modification, are permitted provided that the following conditions 10*fab26bfaSMatthew Dillon * are met: 11*fab26bfaSMatthew Dillon * 1. Redistributions of source code must retain the above copyright 12*fab26bfaSMatthew Dillon * notice, this list of conditions and the following disclaimer. 13*fab26bfaSMatthew Dillon * 2. Redistributions in binary form must reproduce the above copyright 14*fab26bfaSMatthew Dillon * notice, this list of conditions and the following disclaimer in the 15*fab26bfaSMatthew Dillon * documentation and/or other materials provided with the distribution. 16*fab26bfaSMatthew Dillon * 17*fab26bfaSMatthew Dillon * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18*fab26bfaSMatthew Dillon * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19*fab26bfaSMatthew Dillon * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20*fab26bfaSMatthew Dillon * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21*fab26bfaSMatthew Dillon * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22*fab26bfaSMatthew Dillon * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23*fab26bfaSMatthew Dillon * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24*fab26bfaSMatthew Dillon * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25*fab26bfaSMatthew Dillon * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26*fab26bfaSMatthew Dillon * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27*fab26bfaSMatthew Dillon * SUCH DAMAGE. 28*fab26bfaSMatthew Dillon * 29*fab26bfaSMatthew Dillon * $FreeBSD$ 30*fab26bfaSMatthew Dillon */ 31*fab26bfaSMatthew Dillon 32*fab26bfaSMatthew Dillon #ifndef _SYS_GTASKQUEUE_H_ 33*fab26bfaSMatthew Dillon #define _SYS_GTASKQUEUE_H_ 34*fab26bfaSMatthew Dillon 35*fab26bfaSMatthew Dillon #ifndef _KERNEL 36*fab26bfaSMatthew Dillon #error "no user-serviceable parts inside" 37*fab26bfaSMatthew Dillon #endif 38*fab26bfaSMatthew Dillon 39*fab26bfaSMatthew Dillon #include <sys/bus.h> 40*fab26bfaSMatthew Dillon #include <sys/types.h> 41*fab26bfaSMatthew Dillon #include <sys/taskqueue.h> 42*fab26bfaSMatthew Dillon 43*fab26bfaSMatthew Dillon struct gtaskqueue; 44*fab26bfaSMatthew Dillon struct taskqgroup; 45*fab26bfaSMatthew Dillon 46*fab26bfaSMatthew Dillon #define TASK_ENQUEUED 0x1 47*fab26bfaSMatthew Dillon #define TASK_NOENQUEUE 0x2 48*fab26bfaSMatthew Dillon #define TASK_NETWORK 0x4 49*fab26bfaSMatthew Dillon 50*fab26bfaSMatthew Dillon #define TASK_IS_NET(ta) ((ta)->ta_flags & TASK_NETWORK) 51*fab26bfaSMatthew Dillon 52*fab26bfaSMatthew Dillon typedef void gtask_fn_t(void *context); 53*fab26bfaSMatthew Dillon 54*fab26bfaSMatthew Dillon struct gtask { 55*fab26bfaSMatthew Dillon STAILQ_ENTRY(gtask) ta_link; /* (q) link for queue */ 56*fab26bfaSMatthew Dillon uint16_t ta_flags; /* (q) state flags */ 57*fab26bfaSMatthew Dillon u_short ta_priority; /* (c) Priority */ 58*fab26bfaSMatthew Dillon gtask_fn_t *ta_func; /* (c) task handler */ 59*fab26bfaSMatthew Dillon void *ta_context; /* (c) argument for handler */ 60*fab26bfaSMatthew Dillon }; 61*fab26bfaSMatthew Dillon 62*fab26bfaSMatthew Dillon #define GROUPTASK_NAMELEN 32 63*fab26bfaSMatthew Dillon 64*fab26bfaSMatthew Dillon /* 65*fab26bfaSMatthew Dillon * Taskqueue groups. Manages dynamic thread groups and irq binding for 66*fab26bfaSMatthew Dillon * device and other tasks. 67*fab26bfaSMatthew Dillon */ 68*fab26bfaSMatthew Dillon struct grouptask { 69*fab26bfaSMatthew Dillon struct gtask gt_task; 70*fab26bfaSMatthew Dillon void *gt_taskqueue; 71*fab26bfaSMatthew Dillon LIST_ENTRY(grouptask) gt_list; 72*fab26bfaSMatthew Dillon void *gt_uniq; 73*fab26bfaSMatthew Dillon char gt_name[GROUPTASK_NAMELEN]; 74*fab26bfaSMatthew Dillon device_t gt_dev; 75*fab26bfaSMatthew Dillon struct resource *gt_irq; 76*fab26bfaSMatthew Dillon int gt_cpu; 77*fab26bfaSMatthew Dillon }; 78*fab26bfaSMatthew Dillon 79*fab26bfaSMatthew Dillon void gtaskqueue_block(struct gtaskqueue *queue); 80*fab26bfaSMatthew Dillon void gtaskqueue_unblock(struct gtaskqueue *queue); 81*fab26bfaSMatthew Dillon 82*fab26bfaSMatthew Dillon int gtaskqueue_cancel(struct gtaskqueue *queue, struct gtask *gtask); 83*fab26bfaSMatthew Dillon void gtaskqueue_drain(struct gtaskqueue *queue, struct gtask *task); 84*fab26bfaSMatthew Dillon void gtaskqueue_drain_all(struct gtaskqueue *queue); 85*fab26bfaSMatthew Dillon 86*fab26bfaSMatthew Dillon void grouptask_block(struct grouptask *grouptask); 87*fab26bfaSMatthew Dillon void grouptask_unblock(struct grouptask *grouptask); 88*fab26bfaSMatthew Dillon int grouptaskqueue_enqueue(struct gtaskqueue *queue, struct gtask *task); 89*fab26bfaSMatthew Dillon 90*fab26bfaSMatthew Dillon void taskqgroup_attach(struct taskqgroup *qgroup, struct grouptask *grptask, 91*fab26bfaSMatthew Dillon void *uniq, device_t dev, struct resource *irq, const char *name); 92*fab26bfaSMatthew Dillon int taskqgroup_attach_cpu(struct taskqgroup *qgroup, 93*fab26bfaSMatthew Dillon struct grouptask *grptask, void *uniq, int cpu, device_t dev, 94*fab26bfaSMatthew Dillon struct resource *irq, const char *name); 95*fab26bfaSMatthew Dillon void taskqgroup_detach(struct taskqgroup *qgroup, struct grouptask *gtask); 96*fab26bfaSMatthew Dillon struct taskqgroup *taskqgroup_create(const char *name, int cnt, int stride); 97*fab26bfaSMatthew Dillon void taskqgroup_destroy(struct taskqgroup *qgroup); 98*fab26bfaSMatthew Dillon void taskqgroup_bind(struct taskqgroup *qgroup); 99*fab26bfaSMatthew Dillon void taskqgroup_drain_all(struct taskqgroup *qgroup); 100*fab26bfaSMatthew Dillon 101*fab26bfaSMatthew Dillon #define GTASK_INIT(gtask, flags, priority, func, context) do { \ 102*fab26bfaSMatthew Dillon (gtask)->ta_flags = (flags); \ 103*fab26bfaSMatthew Dillon (gtask)->ta_priority = (priority); \ 104*fab26bfaSMatthew Dillon (gtask)->ta_func = (func); \ 105*fab26bfaSMatthew Dillon (gtask)->ta_context = (context); \ 106*fab26bfaSMatthew Dillon } while (0) 107*fab26bfaSMatthew Dillon 108*fab26bfaSMatthew Dillon #define GROUPTASK_INIT(gtask, priority, func, context) \ 109*fab26bfaSMatthew Dillon GTASK_INIT(&(gtask)->gt_task, 0, priority, func, context) 110*fab26bfaSMatthew Dillon 111*fab26bfaSMatthew Dillon #define GROUPTASK_ENQUEUE(gtask) \ 112*fab26bfaSMatthew Dillon grouptaskqueue_enqueue((gtask)->gt_taskqueue, &(gtask)->gt_task) 113*fab26bfaSMatthew Dillon 114*fab26bfaSMatthew Dillon #define TASKQGROUP_DECLARE(name) \ 115*fab26bfaSMatthew Dillon extern struct taskqgroup *qgroup_##name 116*fab26bfaSMatthew Dillon 117*fab26bfaSMatthew Dillon #define TASKQGROUP_DEFINE(name, cnt, stride) \ 118*fab26bfaSMatthew Dillon \ 119*fab26bfaSMatthew Dillon struct taskqgroup *qgroup_##name; \ 120*fab26bfaSMatthew Dillon \ 121*fab26bfaSMatthew Dillon static void \ 122*fab26bfaSMatthew Dillon taskqgroup_define_##name(void *arg) \ 123*fab26bfaSMatthew Dillon { \ 124*fab26bfaSMatthew Dillon qgroup_##name = taskqgroup_create(#name, (cnt), (stride)); \ 125*fab26bfaSMatthew Dillon } \ 126*fab26bfaSMatthew Dillon SYSINIT(taskqgroup_##name, SI_BOOT2_TASKQ, SI_ORDER_FIRST, \ 127*fab26bfaSMatthew Dillon taskqgroup_define_##name, NULL); \ 128*fab26bfaSMatthew Dillon \ 129*fab26bfaSMatthew Dillon static void \ 130*fab26bfaSMatthew Dillon taskqgroup_bind_##name(void *arg) \ 131*fab26bfaSMatthew Dillon { \ 132*fab26bfaSMatthew Dillon taskqgroup_bind(qgroup_##name); \ 133*fab26bfaSMatthew Dillon } \ 134*fab26bfaSMatthew Dillon SYSINIT(taskqgroup_bind_##name, SI_BOOT2_TASKQ, SI_ORDER_ANY, \ 135*fab26bfaSMatthew Dillon taskqgroup_bind_##name, NULL) 136*fab26bfaSMatthew Dillon 137*fab26bfaSMatthew Dillon TASKQGROUP_DECLARE(softirq); 138*fab26bfaSMatthew Dillon 139*fab26bfaSMatthew Dillon #endif /* !_SYS_GTASKQUEUE_H_ */ 140