1
/*********************************************************
2
* Copyright (C) 2008 VMware, Inc. All rights reserved.
4
* This program is free software; you can redistribute it and/or modify it
5
* under the terms of the GNU General Public License as published by the
6
* Free Software Foundation version 2 and no later version.
8
* This program is distributed in the hope that it will be useful, but
9
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
10
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13
* You should have received a copy of the GNU General Public License along
14
* with this program; if not, write to the Free Software Foundation, Inc.,
15
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17
*********************************************************/
19
#ifndef __COMPAT_KTHREAD_H__
20
# define __COMPAT_KTHREAD_H__
23
* The kthread interface for managing kernel threads appeared in 2.6.4, but was
24
* only exported for module use in 2.6.7.
27
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 7)
28
# include <linux/kthread.h>
30
# define COMPAT_KTHREAD_DECLARE_STOP_INFO()
31
# define compat_kthread_stop(_tsk) kthread_stop(_tsk)
32
# define compat_kthread_should_stop() kthread_should_stop()
33
# define compat_kthread_run(_fn, _data, _namefmt, ...) \
34
kthread_run(_fn, _data, _namefmt, ## __VA_ARGS__)
35
# define compat_kthread_create(_fn, _data, _namefmt, ...) \
36
kthread_create(_fn, _data, _namefmt, ## __VA_ARGS__)
40
* When the kthread interface isn't available, we do our best to emulate it,
41
* with a few notable exceptions:
43
* 1: We use semaphores instead of mutexes for locking, because mutexes aren't
44
* available in kernels where kthread isn't available.
45
* 2: The real kthread interface uses the kthreadd kernel_thread to broker the
46
* creation of new kernel threads. This makes sense because kthreadd is part
47
* of the kernel, but doesn't make sense at all in the context of an
48
* individual module. So in our emulation, thread creation occurs in the
49
* context of a kthread_create call.
50
* 3: Because kthreadd is responsible for creating kernel threads in the real
51
* kthread interface, there's no need to explicitly reparent any of them. We
52
* aren't using kthreadd, so we call daemonize to reparent, which also sets
53
* the name of the new kernel thread. That's why we don't set the name as
54
* the real kthread interface does (within kthread_create). Furthermore, to
55
* get the name to daemonize, we're forced to pass it through the
56
* kthread_start_info struct.
57
* 4: Since our interface isn't in the kernel proper, we can't make use of
58
* get_task_struct/put_task_struct so as to acquire references to kernel
59
* threads that we're managing. To prevent races, we use an extra completion
60
* when stopping kernel threads. See the comments in compat_kthread_stop for
63
* Like the real kthread interface, ours must be globally available so that we
64
* can emulate functions like kthread_should_stop without using different
68
# include "compat_completion.h"
69
# include "compat_kernel.h"
70
# include "compat_sched.h"
72
struct compat_kthread_start_info {
75
compat_completion created;
76
char comm[TASK_COMM_LEN];
79
struct compat_kthread_stop_info {
80
struct semaphore lock;
81
struct task_struct *task;
82
compat_completion woken;
83
compat_completion stopped;
87
extern struct compat_kthread_stop_info compat_kthread_stop_info;
89
# define COMPAT_KTHREAD_DECLARE_STOP_INFO() \
90
struct compat_kthread_stop_info compat_kthread_stop_info = { \
91
.lock = __SEMAPHORE_INITIALIZER(compat_kthread_stop_info.lock, 1), \
97
compat_kthread_should_stop(void)
99
return (compat_kthread_stop_info.task == current);
104
compat_kthread_stop(struct task_struct *_task)
108
down(&compat_kthread_stop_info.lock);
111
* We use a write memory barrier to ensure that all CPUs see _task after
112
* the completions have been initialized.
114
* There's a race between kernel threads managed by kthread and the upcoming
115
* call to wake_up_process. If the kernel thread wakes up after we set task
116
* but before the call to wake_up_process, the thread's call to
117
* compat_kthread_should_stop will return true and the thread will exit. At
118
* that point, the call to wake_up_process will be on a dead task_struct.
120
* XXX: The real kthread interface protects against this race by grabbing
121
* and releasing a reference to _task. We don't have that luxury, because
122
* there is a range of kernels where put_task_struct isn't exported to
123
* modules. In fact, no other modules call get_task_struct or
124
* put_task_struct, so to do so from this context may be unwise. Instead,
125
* we'll use an extra completion to ensure that the kernel thread only exits
126
* after wake_up_process has been called.
128
compat_init_completion(&compat_kthread_stop_info.woken);
129
compat_init_completion(&compat_kthread_stop_info.stopped);
132
compat_kthread_stop_info.task = _task;
133
wake_up_process(_task);
134
compat_complete(&compat_kthread_stop_info.woken);
136
compat_wait_for_completion(&compat_kthread_stop_info.stopped);
137
compat_kthread_stop_info.task = NULL;
138
ret = compat_kthread_stop_info.ret;
139
up(&compat_kthread_stop_info.lock);
144
# define compat_kthread_run(_fn, _data, _namefmt, ...) \
146
struct task_struct *tsk; \
147
tsk = compat_kthread_create(_fn, _data, _namefmt, ## __VA_ARGS__); \
148
if (!IS_ERR(tsk)) { \
149
wake_up_process(tsk); \
156
compat_kthread(void *_data)
159
struct compat_kthread_start_info *info;
160
int (*fn)(void *data);
163
info = (struct compat_kthread_start_info *)_data;
167
compat_daemonize(info->comm);
168
__set_current_state(TASK_UNINTERRUPTIBLE);
169
compat_complete(&info->created);
172
if (!compat_kthread_should_stop()) {
176
if (compat_kthread_should_stop()) {
177
compat_wait_for_completion(&compat_kthread_stop_info.woken);
178
compat_kthread_stop_info.ret = ret;
179
compat_complete_and_exit(&compat_kthread_stop_info.stopped, 0);
186
static inline struct task_struct *
187
compat_kthread_create(int (*_fn)(void *data),
189
const char _namefmt[],
193
struct task_struct *task = NULL;
194
struct compat_kthread_start_info info;
199
compat_init_completion(&info.created);
200
va_start(args, _namefmt);
201
vsnprintf(info.comm, sizeof info.comm, _namefmt, args);
203
pid = kernel_thread(compat_kthread, &info, CLONE_KERNEL);
205
compat_wait_for_completion(&info.created);
208
* find_task_by_pid must be called with tasklist_lock held or under
209
* rcu_read_lock. As the latter doesn't exist in old kernels, we use the
210
* former for convenience.
212
read_lock(&tasklist_lock);
213
task = find_task_by_pid(pid);
214
read_unlock(&tasklist_lock);
216
/* XXX: Do we need to get a reference on task? */
223
#endif /* __COMPAT_KTHREAD_H__ */