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