xref: /dragonfly/sys/sys/gtaskqueue.h (revision fab26bfa)
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