Blame view

kernel/kthread.c 6.59 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
  /* Kernel thread helper functions.
   *   Copyright (C) 2004 IBM Corporation, Rusty Russell.
   *
73c279927   Eric W. Biederman   kthread: don't de...
4
   * Creation is done via kthreadd, so that we get a clean environment
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5
6
7
8
9
10
11
   * even if we're invoked from userspace (think modprobe, hotplug cpu,
   * etc.).
   */
  #include <linux/sched.h>
  #include <linux/kthread.h>
  #include <linux/completion.h>
  #include <linux/err.h>
58568d2a8   Miao Xie   cpuset,mm: update...
12
  #include <linux/cpuset.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
13
14
15
  #include <linux/unistd.h>
  #include <linux/file.h>
  #include <linux/module.h>
97d1f15b7   Arjan van de Ven   [PATCH] sem2mutex...
16
  #include <linux/mutex.h>
ad8d75fff   Steven Rostedt   tracing/events: m...
17
  #include <trace/events/sched.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
18

73c279927   Eric W. Biederman   kthread: don't de...
19
20
21
  static DEFINE_SPINLOCK(kthread_create_lock);
  static LIST_HEAD(kthread_create_list);
  struct task_struct *kthreadd_task;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
22
23
24
  
  struct kthread_create_info
  {
73c279927   Eric W. Biederman   kthread: don't de...
25
  	/* Information passed to kthread() from kthreadd. */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
26
27
  	int (*threadfn)(void *data);
  	void *data;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
28

73c279927   Eric W. Biederman   kthread: don't de...
29
  	/* Result passed back to kthread_create() from kthreadd. */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
30
31
  	struct task_struct *result;
  	struct completion done;
65f27f384   David Howells   WorkStruct: Pass ...
32

73c279927   Eric W. Biederman   kthread: don't de...
33
  	struct list_head list;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
34
  };
63706172f   Oleg Nesterov   kthreads: rework ...
35
36
37
  struct kthread {
  	int should_stop;
  	struct completion exited;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
38
  };
63706172f   Oleg Nesterov   kthreads: rework ...
39
40
  #define to_kthread(tsk)	\
  	container_of((tsk)->vfork_done, struct kthread, exited)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
41

9e37bd301   Randy Dunlap   [PATCH] kthread: ...
42
43
44
  /**
   * kthread_should_stop - should this kthread return now?
   *
72fd4a35a   Robert P. J. Day   [PATCH] Numerous ...
45
   * When someone calls kthread_stop() on your kthread, it will be woken
9e37bd301   Randy Dunlap   [PATCH] kthread: ...
46
47
48
   * and this will return true.  You should then return, and your return
   * value will be passed through to kthread_stop().
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
49
50
  int kthread_should_stop(void)
  {
63706172f   Oleg Nesterov   kthreads: rework ...
51
  	return to_kthread(current)->should_stop;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
52
53
  }
  EXPORT_SYMBOL(kthread_should_stop);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
54
55
  static int kthread(void *_create)
  {
63706172f   Oleg Nesterov   kthreads: rework ...
56
  	/* Copy data: it's on kthread's stack */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
57
  	struct kthread_create_info *create = _create;
63706172f   Oleg Nesterov   kthreads: rework ...
58
59
60
61
  	int (*threadfn)(void *data) = create->threadfn;
  	void *data = create->data;
  	struct kthread self;
  	int ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
62

63706172f   Oleg Nesterov   kthreads: rework ...
63
64
65
  	self.should_stop = 0;
  	init_completion(&self.exited);
  	current->vfork_done = &self.exited;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
66

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
67
  	/* OK, tell user we're spawned, wait for stop or wakeup */
a076e4bca   Oleg Nesterov   freezer: fix kthr...
68
  	__set_current_state(TASK_UNINTERRUPTIBLE);
3217ab97f   Vitaliy Gusev   kthread: Don't lo...
69
  	create->result = current;
cdd140bdd   Oleg Nesterov   kthreads: simplif...
70
  	complete(&create->done);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
71
  	schedule();
63706172f   Oleg Nesterov   kthreads: rework ...
72
73
  	ret = -EINTR;
  	if (!self.should_stop)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
74
  		ret = threadfn(data);
63706172f   Oleg Nesterov   kthreads: rework ...
75
76
  	/* we can't just return, we must preserve "self" on stack */
  	do_exit(ret);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
77
  }
73c279927   Eric W. Biederman   kthread: don't de...
78
  static void create_kthread(struct kthread_create_info *create)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
79
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
80
81
82
83
  	int pid;
  
  	/* We want our own signal handler (we take no signals by default). */
  	pid = kernel_thread(kthread, create, CLONE_FS | CLONE_FILES | SIGCHLD);
cdd140bdd   Oleg Nesterov   kthreads: simplif...
84
  	if (pid < 0) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
85
  		create->result = ERR_PTR(pid);
cdd140bdd   Oleg Nesterov   kthreads: simplif...
86
87
  		complete(&create->done);
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
88
  }
9e37bd301   Randy Dunlap   [PATCH] kthread: ...
89
90
91
92
93
94
95
96
  /**
   * kthread_create - create a kthread.
   * @threadfn: the function to run until signal_pending(current).
   * @data: data ptr for @threadfn.
   * @namefmt: printf-style name for the thread.
   *
   * Description: This helper function creates and names a kernel
   * thread.  The thread will be stopped: use wake_up_process() to start
301ba0457   Anton Blanchard   kthread, sched: R...
97
   * it.  See also kthread_run().
9e37bd301   Randy Dunlap   [PATCH] kthread: ...
98
99
   *
   * When woken, the thread will run @threadfn() with @data as its
72fd4a35a   Robert P. J. Day   [PATCH] Numerous ...
100
   * argument. @threadfn() can either call do_exit() directly if it is a
9e37bd301   Randy Dunlap   [PATCH] kthread: ...
101
102
103
104
105
106
107
   * standalone thread for which noone will call kthread_stop(), or
   * return when 'kthread_should_stop()' is true (which means
   * kthread_stop() has been called).  The return value should be zero
   * or a negative error number; it will be passed to kthread_stop().
   *
   * Returns a task_struct or ERR_PTR(-ENOMEM).
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
108
109
110
111
112
113
  struct task_struct *kthread_create(int (*threadfn)(void *data),
  				   void *data,
  				   const char namefmt[],
  				   ...)
  {
  	struct kthread_create_info create;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
114
115
116
  
  	create.threadfn = threadfn;
  	create.data = data;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
117
  	init_completion(&create.done);
73c279927   Eric W. Biederman   kthread: don't de...
118
119
120
  
  	spin_lock(&kthread_create_lock);
  	list_add_tail(&create.list, &kthread_create_list);
73c279927   Eric W. Biederman   kthread: don't de...
121
  	spin_unlock(&kthread_create_lock);
cbd9b67bd   Dmitry Adamushko   kthread: call wak...
122
  	wake_up_process(kthreadd_task);
73c279927   Eric W. Biederman   kthread: don't de...
123
  	wait_for_completion(&create.done);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
124
  	if (!IS_ERR(create.result)) {
1c99315bb   Oleg Nesterov   kthread: move sch...
125
  		struct sched_param param = { .sched_priority = 0 };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
126
  		va_list args;
1c99315bb   Oleg Nesterov   kthread: move sch...
127

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
128
129
130
131
  		va_start(args, namefmt);
  		vsnprintf(create.result->comm, sizeof(create.result->comm),
  			  namefmt, args);
  		va_end(args);
1c99315bb   Oleg Nesterov   kthread: move sch...
132
133
134
135
136
  		/*
  		 * root may have changed our (kthreadd's) priority or CPU mask.
  		 * The kernel thread should not inherit these properties.
  		 */
  		sched_setscheduler_nocheck(create.result, SCHED_NORMAL, &param);
1c99315bb   Oleg Nesterov   kthread: move sch...
137
  		set_cpus_allowed_ptr(create.result, cpu_all_mask);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
138
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
139
140
141
  	return create.result;
  }
  EXPORT_SYMBOL(kthread_create);
9e37bd301   Randy Dunlap   [PATCH] kthread: ...
142
  /**
881232b70   Peter Zijlstra   sched: Move kthre...
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
   * kthread_bind - bind a just-created kthread to a cpu.
   * @p: thread created by kthread_create().
   * @cpu: cpu (might not be online, must be possible) for @k to run on.
   *
   * Description: This function is equivalent to set_cpus_allowed(),
   * except that @cpu doesn't need to be online, and the thread must be
   * stopped (i.e., just returned from kthread_create()).
   */
  void kthread_bind(struct task_struct *p, unsigned int cpu)
  {
  	/* Must have done schedule() in kthread() before we set_task_cpu */
  	if (!wait_task_inactive(p, TASK_UNINTERRUPTIBLE)) {
  		WARN_ON(1);
  		return;
  	}
  
  	p->cpus_allowed = cpumask_of_cpu(cpu);
  	p->rt.nr_cpus_allowed = 1;
  	p->flags |= PF_THREAD_BOUND;
  }
  EXPORT_SYMBOL(kthread_bind);
  
  /**
9e37bd301   Randy Dunlap   [PATCH] kthread: ...
166
167
168
169
   * kthread_stop - stop a thread created by kthread_create().
   * @k: thread created by kthread_create().
   *
   * Sets kthread_should_stop() for @k to return true, wakes it, and
9ae260270   Oleg Nesterov   update the commen...
170
171
172
173
174
175
   * waits for it to exit. This can also be called after kthread_create()
   * instead of calling wake_up_process(): the thread will exit without
   * calling threadfn().
   *
   * If threadfn() may call do_exit() itself, the caller must ensure
   * task_struct can't go away.
9e37bd301   Randy Dunlap   [PATCH] kthread: ...
176
177
178
179
   *
   * Returns the result of threadfn(), or %-EINTR if wake_up_process()
   * was never called.
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
180
181
  int kthread_stop(struct task_struct *k)
  {
63706172f   Oleg Nesterov   kthreads: rework ...
182
  	struct kthread *kthread;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
183
  	int ret;
0a16b6075   Mathieu Desnoyers   tracing, sched: L...
184
  	trace_sched_kthread_stop(k);
63706172f   Oleg Nesterov   kthreads: rework ...
185
  	get_task_struct(k);
0a16b6075   Mathieu Desnoyers   tracing, sched: L...
186

63706172f   Oleg Nesterov   kthreads: rework ...
187
188
189
190
191
192
193
194
  	kthread = to_kthread(k);
  	barrier(); /* it might have exited */
  	if (k->vfork_done != NULL) {
  		kthread->should_stop = 1;
  		wake_up_process(k);
  		wait_for_completion(&kthread->exited);
  	}
  	ret = k->exit_code;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
195

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
196
  	put_task_struct(k);
0a16b6075   Mathieu Desnoyers   tracing, sched: L...
197
  	trace_sched_kthread_stop_ret(ret);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
198
199
  	return ret;
  }
52e92e578   Adrian Bunk   [PATCH] remove ke...
200
  EXPORT_SYMBOL(kthread_stop);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
201

e804a4a4d   Satyam Sharma   kthread: silence ...
202
  int kthreadd(void *unused)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
203
  {
73c279927   Eric W. Biederman   kthread: don't de...
204
  	struct task_struct *tsk = current;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
205

e804a4a4d   Satyam Sharma   kthread: silence ...
206
  	/* Setup a clean context for our children to inherit. */
73c279927   Eric W. Biederman   kthread: don't de...
207
  	set_task_comm(tsk, "kthreadd");
10ab825bd   Oleg Nesterov   change kernel thr...
208
  	ignore_signals(tsk);
1a2142afa   Rusty Russell   cpumask: remove d...
209
  	set_cpus_allowed_ptr(tsk, cpu_all_mask);
5ab116c93   Miao Xie   cpuset: fix the p...
210
  	set_mems_allowed(node_states[N_HIGH_MEMORY]);
73c279927   Eric W. Biederman   kthread: don't de...
211

ebb12db51   Rafael J. Wysocki   Freezer: Introduc...
212
  	current->flags |= PF_NOFREEZE | PF_FREEZER_NOSIG;
73c279927   Eric W. Biederman   kthread: don't de...
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
  
  	for (;;) {
  		set_current_state(TASK_INTERRUPTIBLE);
  		if (list_empty(&kthread_create_list))
  			schedule();
  		__set_current_state(TASK_RUNNING);
  
  		spin_lock(&kthread_create_lock);
  		while (!list_empty(&kthread_create_list)) {
  			struct kthread_create_info *create;
  
  			create = list_entry(kthread_create_list.next,
  					    struct kthread_create_info, list);
  			list_del_init(&create->list);
  			spin_unlock(&kthread_create_lock);
  
  			create_kthread(create);
  
  			spin_lock(&kthread_create_lock);
  		}
  		spin_unlock(&kthread_create_lock);
  	}
  
  	return 0;
  }