xref: /dflybsd-src/sys/dev/drm/linux_workqueue.c (revision 2cecdd68a635a5552cc4c5dde9bf65b3f0b5a262)
1df8db295SFrançois Tigeot /*
2*2cecdd68SFrançois Tigeot  * Copyright (c) 2015-2020 François Tigeot <ftigeot@wolfpond.org>
3df8db295SFrançois Tigeot  * All rights reserved.
4df8db295SFrançois Tigeot  *
5df8db295SFrançois Tigeot  * Redistribution and use in source and binary forms, with or without
6df8db295SFrançois Tigeot  * modification, are permitted provided that the following conditions
7df8db295SFrançois Tigeot  * are met:
8df8db295SFrançois Tigeot  * 1. Redistributions of source code must retain the above copyright
9df8db295SFrançois Tigeot  *    notice unmodified, this list of conditions, and the following
10df8db295SFrançois Tigeot  *    disclaimer.
11df8db295SFrançois Tigeot  * 2. Redistributions in binary form must reproduce the above copyright
12df8db295SFrançois Tigeot  *    notice, this list of conditions and the following disclaimer in the
13df8db295SFrançois Tigeot  *    documentation and/or other materials provided with the distribution.
14df8db295SFrançois Tigeot  *
15df8db295SFrançois Tigeot  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16df8db295SFrançois Tigeot  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17df8db295SFrançois Tigeot  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18df8db295SFrançois Tigeot  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19df8db295SFrançois Tigeot  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20df8db295SFrançois Tigeot  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21df8db295SFrançois Tigeot  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22df8db295SFrançois Tigeot  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23df8db295SFrançois Tigeot  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24df8db295SFrançois Tigeot  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25df8db295SFrançois Tigeot  */
26df8db295SFrançois Tigeot 
27df8db295SFrançois Tigeot #include <drm/drmP.h>
28df8db295SFrançois Tigeot #include <linux/workqueue.h>
29df8db295SFrançois Tigeot 
30df8db295SFrançois Tigeot struct workqueue_struct *system_wq;
31*2cecdd68SFrançois Tigeot struct workqueue_struct *system_highpri_wq;
32df8db295SFrançois Tigeot struct workqueue_struct *system_long_wq;
3396b26154SFrançois Tigeot struct workqueue_struct *system_unbound_wq;
34*2cecdd68SFrançois Tigeot struct workqueue_struct *system_power_efficient_wq;
35df8db295SFrançois Tigeot 
36df8db295SFrançois Tigeot static int init_workqueues(void *arg)
37df8db295SFrançois Tigeot {
38df8db295SFrançois Tigeot 	system_wq = alloc_workqueue("system_wq", 0, 1);
39*2cecdd68SFrançois Tigeot 	system_highpri_wq = alloc_workqueue("system_highpri_wq", 0, 1);
40df8db295SFrançois Tigeot 	system_long_wq = alloc_workqueue("system_long_wq", 0, 1);
4196b26154SFrançois Tigeot 	system_unbound_wq = alloc_workqueue("system_unbound_wq", 0, 1);
42*2cecdd68SFrançois Tigeot 	system_power_efficient_wq = alloc_workqueue("system_power_efficient_wq", 0, 1);
43df8db295SFrançois Tigeot 
44df8db295SFrançois Tigeot 	return 0;
45df8db295SFrançois Tigeot }
46f5e8ad19SImre Vadász 
47f5e8ad19SImre Vadász static int destroy_workqueues(void *arg)
48f5e8ad19SImre Vadász {
49f5e8ad19SImre Vadász 	destroy_workqueue(system_wq);
50*2cecdd68SFrançois Tigeot 	destroy_workqueue(system_highpri_wq);
51f5e8ad19SImre Vadász 	destroy_workqueue(system_long_wq);
5296b26154SFrançois Tigeot 	destroy_workqueue(system_unbound_wq);
53*2cecdd68SFrançois Tigeot 	destroy_workqueue(system_power_efficient_wq);
54f5e8ad19SImre Vadász 
55f5e8ad19SImre Vadász 	return 0;
56f5e8ad19SImre Vadász }
57f5e8ad19SImre Vadász 
58d6aa1cc5SFrançois Tigeot struct workqueue_struct *
59d6aa1cc5SFrançois Tigeot _create_workqueue_common(char *name, int cpus)
60d6aa1cc5SFrançois Tigeot {
61d6aa1cc5SFrançois Tigeot 	struct workqueue_struct *wq;
62d6aa1cc5SFrançois Tigeot 
63d6aa1cc5SFrançois Tigeot 	wq = kmalloc(sizeof(*wq), M_DRM, M_WAITOK);
64d6aa1cc5SFrançois Tigeot 	wq->taskqueue = taskqueue_create((name), M_WAITOK,
65d6aa1cc5SFrançois Tigeot 	    taskqueue_thread_enqueue,  &wq->taskqueue);
66d6aa1cc5SFrançois Tigeot 	taskqueue_start_threads(&wq->taskqueue, cpus,
67d6aa1cc5SFrançois Tigeot 				TDPRI_KERN_DAEMON, -1, "%s", name);
68d6aa1cc5SFrançois Tigeot 
69d6aa1cc5SFrançois Tigeot 	return (wq);
70d6aa1cc5SFrançois Tigeot }
71d6aa1cc5SFrançois Tigeot 
72d6aa1cc5SFrançois Tigeot void
73d6aa1cc5SFrançois Tigeot destroy_workqueue(struct workqueue_struct *wq)
74d6aa1cc5SFrançois Tigeot {
75d6aa1cc5SFrançois Tigeot 	taskqueue_free(wq->taskqueue);
76d6aa1cc5SFrançois Tigeot 	kfree(wq);
77d6aa1cc5SFrançois Tigeot }
78d6aa1cc5SFrançois Tigeot 
79f5e8ad19SImre Vadász SYSINIT(linux_workqueue_init, SI_SUB_DRIVERS, SI_ORDER_MIDDLE, init_workqueues, NULL);
80f5e8ad19SImre Vadász SYSUNINIT(linux_workqueue_destroy, SI_SUB_DRIVERS, SI_ORDER_MIDDLE, destroy_workqueues, NULL);
815dfe0225SFrançois Tigeot 
825dfe0225SFrançois Tigeot bool
835dfe0225SFrançois Tigeot flush_delayed_work(struct delayed_work *dwork)
845dfe0225SFrançois Tigeot {
855dfe0225SFrançois Tigeot 	callout_drain(&dwork->timer);
865dfe0225SFrançois Tigeot 	return flush_work(&dwork->work);
875dfe0225SFrançois Tigeot }
885ef31fe9SFrançois Tigeot 
895ef31fe9SFrançois Tigeot void
905ef31fe9SFrançois Tigeot drain_workqueue(struct workqueue_struct *wq)
915ef31fe9SFrançois Tigeot {
925ef31fe9SFrançois Tigeot 	lockmgr(&wq->flags_lock, LK_EXCLUSIVE);
935ef31fe9SFrançois Tigeot 	wq->is_draining = true;
945ef31fe9SFrançois Tigeot 	lockmgr(&wq->flags_lock, LK_RELEASE);
955ef31fe9SFrançois Tigeot 
965ef31fe9SFrançois Tigeot 	flush_taskqueue(wq->taskqueue);
975ef31fe9SFrançois Tigeot 
985ef31fe9SFrançois Tigeot 	lockmgr(&wq->flags_lock, LK_EXCLUSIVE);
995ef31fe9SFrançois Tigeot 	wq->is_draining = false;
1005ef31fe9SFrançois Tigeot 	lockmgr(&wq->flags_lock, LK_RELEASE);
1015ef31fe9SFrançois Tigeot }
102