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