xref: /f-stack/freebsd/sys/gtaskqueue.h (revision 22ce4aff)
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