]> git.proxmox.com Git - mirror_zfs.git/blame - modules/spl/spl-taskq.c
Be careful to never use any of the debug infrastructure either
[mirror_zfs.git] / modules / spl / spl-taskq.c
CommitLineData
f4b37741 1#include <sys/taskq.h>
f1ca4da6 2
937879f1
BB
3#ifdef DEBUG_SUBSYSTEM
4#undef DEBUG_SUBSYSTEM
5#endif
6
7#define DEBUG_SUBSYSTEM S_TASKQ
8
f1ca4da6
BB
9/*
10 * Task queue interface
11 *
12 * The taskq_work_wrapper functions are used to manage the work_structs
13 * which must be submitted to linux. The shim layer allocates a wrapper
14 * structure for all items which contains a pointer to itself as well as
15 * the real work to be performed. When the work item run the generic
16 * handle is called which calls the real work function and then using
17 * the self pointer frees the work_struct.
18 */
19typedef struct taskq_work_wrapper {
20 struct work_struct tww_work;
21 task_func_t tww_func;
22 void * tww_priv;
23} taskq_work_wrapper_t;
24
25static void
26taskq_work_handler(void *priv)
27{
28 taskq_work_wrapper_t *tww = priv;
29
937879f1
BB
30 ASSERT(tww);
31 ASSERT(tww->tww_func);
f1ca4da6
BB
32
33 /* Call the real function and free the wrapper */
34 tww->tww_func(tww->tww_priv);
35 kfree(tww);
36}
37
38/* XXX - All flags currently ignored */
39taskqid_t
40__taskq_dispatch(taskq_t *tq, task_func_t func, void *priv, uint_t flags)
41{
42 struct workqueue_struct *wq = tq;
43 taskq_work_wrapper_t *tww;
44 int rc;
937879f1 45 ENTRY;
f1ca4da6 46
937879f1
BB
47 ASSERT(tq);
48 ASSERT(func);
f1ca4da6 49
0a6fd143
BB
50 /* Use GFP_ATOMIC since this may be called in interrupt context */
51 tww = (taskq_work_wrapper_t *)kmalloc(sizeof(*tww), GFP_ATOMIC);
f1ca4da6 52 if (!tww)
937879f1 53 RETURN((taskqid_t)0);
f1ca4da6
BB
54
55 INIT_WORK(&(tww->tww_work), taskq_work_handler, tww);
56 tww->tww_func = func;
57 tww->tww_priv = priv;
58
59 rc = queue_work(wq, &(tww->tww_work));
60 if (!rc) {
61 kfree(tww);
937879f1 62 RETURN((taskqid_t)0);
f1ca4da6
BB
63 }
64
937879f1 65 RETURN((taskqid_t)wq);
f1ca4da6 66}
f1b59d26 67EXPORT_SYMBOL(__taskq_dispatch);
f1ca4da6
BB
68
69/* XXX - Most args ignored until we decide if it's worth the effort
70 * to emulate the solaris notion of dynamic thread pools. For
71 * now we simply serialize everything through one thread which
72 * may come back to bite us as a performance issue.
73 * pri - Ignore priority
74 * min - Ignored until this is a dynamic thread pool
75 * max - Ignored until this is a dynamic thread pool
76 * flags - Ignored until this is a dynamic thread_pool
77 */
78taskq_t *
79__taskq_create(const char *name, int nthreads, pri_t pri,
80 int minalloc, int maxalloc, uint_t flags)
81{
f1b59d26 82 /* NOTE: Linux workqueue names are limited to 10 chars */
937879f1
BB
83 ENTRY;
84 RETURN(create_singlethread_workqueue(name));
f1ca4da6 85}
f1b59d26 86EXPORT_SYMBOL(__taskq_create);
b123971f
BB
87
88void
89__taskq_destroy(taskq_t *tq)
90{
937879f1 91 ENTRY;
b123971f 92 destroy_workqueue(tq);
937879f1 93 EXIT;
b123971f
BB
94}
95EXPORT_SYMBOL(__taskq_destroy);
96
97void
98__taskq_wait(taskq_t *tq)
99{
937879f1 100 ENTRY;
b123971f 101 flush_workqueue(tq);
937879f1 102 EXIT;
b123971f
BB
103}
104EXPORT_SYMBOL(__taskq_wait);