linux/kernel/kthread.c
<<
>>
Prefs
   1/* Kernel thread helper functions.
   2 *   Copyright (C) 2004 IBM Corporation, Rusty Russell.
   3 *
   4 * Creation is done via kthreadd, so that we get a clean environment
   5 * even if we're invoked from userspace (think modprobe, hotplug cpu,
   6 * etc.).
   7 */
   8#include <linux/sched.h>
   9#include <linux/kthread.h>
  10#include <linux/completion.h>
  11#include <linux/err.h>
  12#include <linux/unistd.h>
  13#include <linux/file.h>
  14#include <linux/module.h>
  15#include <linux/mutex.h>
  16#include <trace/sched.h>
  17
  18#define KTHREAD_NICE_LEVEL (-5)
  19
  20static DEFINE_SPINLOCK(kthread_create_lock);
  21static LIST_HEAD(kthread_create_list);
  22struct task_struct *kthreadd_task;
  23
  24struct kthread_create_info
  25{
  26        /* Information passed to kthread() from kthreadd. */
  27        int (*threadfn)(void *data);
  28        void *data;
  29        struct completion started;
  30
  31        /* Result passed back to kthread_create() from kthreadd. */
  32        struct task_struct *result;
  33        struct completion done;
  34
  35        struct list_head list;
  36};
  37
  38struct kthread_stop_info
  39{
  40        struct task_struct *k;
  41        int err;
  42        struct completion done;
  43};
  44
  45/* Thread stopping is done by setthing this var: lock serializes
  46 * multiple kthread_stop calls. */
  47static DEFINE_MUTEX(kthread_stop_lock);
  48static struct kthread_stop_info kthread_stop_info;
  49
  50/**
  51 * kthread_should_stop - should this kthread return now?
  52 *
  53 * When someone calls kthread_stop() on your kthread, it will be woken
  54 * and this will return true.  You should then return, and your return
  55 * value will be passed through to kthread_stop().
  56 */
  57int kthread_should_stop(void)
  58{
  59        return (kthread_stop_info.k == current);
  60}
  61EXPORT_SYMBOL(kthread_should_stop);
  62
  63static int kthread(void *_create)
  64{
  65        struct kthread_create_info *create = _create;
  66        int (*threadfn)(void *data);
  67        void *data;
  68        int ret = -EINTR;
  69
  70        /* Copy data: it's on kthread's stack */
  71        threadfn = create->threadfn;
  72        data = create->data;
  73
  74        /* OK, tell user we're spawned, wait for stop or wakeup */
  75        __set_current_state(TASK_UNINTERRUPTIBLE);
  76        complete(&create->started);
  77        schedule();
  78
  79        if (!kthread_should_stop())
  80                ret = threadfn(data);
  81
  82        /* It might have exited on its own, w/o kthread_stop.  Check. */
  83        if (kthread_should_stop()) {
  84                kthread_stop_info.err = ret;
  85                complete(&kthread_stop_info.done);
  86        }
  87        return 0;
  88}
  89
  90static void create_kthread(struct kthread_create_info *create)
  91{
  92        int pid;
  93
  94        /* We want our own signal handler (we take no signals by default). */
  95        pid = kernel_thread(kthread, create, CLONE_FS | CLONE_FILES | SIGCHLD);
  96        if (pid < 0) {
  97                create->result = ERR_PTR(pid);
  98        } else {
  99                struct sched_param param = { .sched_priority = 0 };
 100                wait_for_completion(&create->started);
 101                read_lock(&tasklist_lock);
 102                create->result = find_task_by_pid_ns(pid, &init_pid_ns);
 103                read_unlock(&tasklist_lock);
 104                /*
 105                 * root may have changed our (kthreadd's) priority or CPU mask.
 106                 * The kernel thread should not inherit these properties.
 107                 */
 108                sched_setscheduler(create->result, SCHED_NORMAL, &param);
 109                set_user_nice(create->result, KTHREAD_NICE_LEVEL);
 110                set_cpus_allowed_ptr(create->result, CPU_MASK_ALL_PTR);
 111        }
 112        complete(&create->done);
 113}
 114
 115/**
 116 * kthread_create - create a kthread.
 117 * @threadfn: the function to run until signal_pending(current).
 118 * @data: data ptr for @threadfn.
 119 * @namefmt: printf-style name for the thread.
 120 *
 121 * Description: This helper function creates and names a kernel
 122 * thread.  The thread will be stopped: use wake_up_process() to start
 123 * it.  See also kthread_run(), kthread_create_on_cpu().
 124 *
 125 * When woken, the thread will run @threadfn() with @data as its
 126 * argument. @threadfn() can either call do_exit() directly if it is a
 127 * standalone thread for which noone will call kthread_stop(), or
 128 * return when 'kthread_should_stop()' is true (which means
 129 * kthread_stop() has been called).  The return value should be zero
 130 * or a negative error number; it will be passed to kthread_stop().
 131 *
 132 * Returns a task_struct or ERR_PTR(-ENOMEM).
 133 */
 134struct task_struct *kthread_create(int (*threadfn)(void *data),
 135                                   void *data,
 136                                   const char namefmt[],
 137                                   ...)
 138{
 139        struct kthread_create_info create;
 140
 141        create.threadfn = threadfn;
 142        create.data = data;
 143        init_completion(&create.started);
 144        init_completion(&create.done);
 145
 146        spin_lock(&kthread_create_lock);
 147        list_add_tail(&create.list, &kthread_create_list);
 148        spin_unlock(&kthread_create_lock);
 149
 150        wake_up_process(kthreadd_task);
 151        wait_for_completion(&create.done);
 152
 153        if (!IS_ERR(create.result)) {
 154                va_list args;
 155                va_start(args, namefmt);
 156                vsnprintf(create.result->comm, sizeof(create.result->comm),
 157                          namefmt, args);
 158                va_end(args);
 159        }
 160        return create.result;
 161}
 162EXPORT_SYMBOL(kthread_create);
 163
 164/**
 165 * kthread_bind - bind a just-created kthread to a cpu.
 166 * @k: thread created by kthread_create().
 167 * @cpu: cpu (might not be online, must be possible) for @k to run on.
 168 *
 169 * Description: This function is equivalent to set_cpus_allowed(),
 170 * except that @cpu doesn't need to be online, and the thread must be
 171 * stopped (i.e., just returned from kthread_create()).
 172 */
 173void kthread_bind(struct task_struct *k, unsigned int cpu)
 174{
 175        /* Must have done schedule() in kthread() before we set_task_cpu */
 176        if (!wait_task_inactive(k, TASK_UNINTERRUPTIBLE)) {
 177                WARN_ON(1);
 178                return;
 179        }
 180        set_task_cpu(k, cpu);
 181        k->cpus_allowed = cpumask_of_cpu(cpu);
 182        k->rt.nr_cpus_allowed = 1;
 183        k->flags |= PF_THREAD_BOUND;
 184}
 185EXPORT_SYMBOL(kthread_bind);
 186
 187/**
 188 * kthread_stop - stop a thread created by kthread_create().
 189 * @k: thread created by kthread_create().
 190 *
 191 * Sets kthread_should_stop() for @k to return true, wakes it, and
 192 * waits for it to exit.  Your threadfn() must not call do_exit()
 193 * itself if you use this function!  This can also be called after
 194 * kthread_create() instead of calling wake_up_process(): the thread
 195 * will exit without calling threadfn().
 196 *
 197 * Returns the result of threadfn(), or %-EINTR if wake_up_process()
 198 * was never called.
 199 */
 200int kthread_stop(struct task_struct *k)
 201{
 202        int ret;
 203
 204        mutex_lock(&kthread_stop_lock);
 205
 206        /* It could exit after stop_info.k set, but before wake_up_process. */
 207        get_task_struct(k);
 208
 209        trace_sched_kthread_stop(k);
 210
 211        /* Must init completion *before* thread sees kthread_stop_info.k */
 212        init_completion(&kthread_stop_info.done);
 213        smp_wmb();
 214
 215        /* Now set kthread_should_stop() to true, and wake it up. */
 216        kthread_stop_info.k = k;
 217        wake_up_process(k);
 218        put_task_struct(k);
 219
 220        /* Once it dies, reset stop ptr, gather result and we're done. */
 221        wait_for_completion(&kthread_stop_info.done);
 222        kthread_stop_info.k = NULL;
 223        ret = kthread_stop_info.err;
 224        mutex_unlock(&kthread_stop_lock);
 225
 226        trace_sched_kthread_stop_ret(ret);
 227
 228        return ret;
 229}
 230EXPORT_SYMBOL(kthread_stop);
 231
 232int kthreadd(void *unused)
 233{
 234        struct task_struct *tsk = current;
 235
 236        /* Setup a clean context for our children to inherit. */
 237        set_task_comm(tsk, "kthreadd");
 238        ignore_signals(tsk);
 239        set_user_nice(tsk, KTHREAD_NICE_LEVEL);
 240        set_cpus_allowed_ptr(tsk, CPU_MASK_ALL_PTR);
 241
 242        current->flags |= PF_NOFREEZE | PF_FREEZER_NOSIG;
 243
 244        for (;;) {
 245                set_current_state(TASK_INTERRUPTIBLE);
 246                if (list_empty(&kthread_create_list))
 247                        schedule();
 248                __set_current_state(TASK_RUNNING);
 249
 250                spin_lock(&kthread_create_lock);
 251                while (!list_empty(&kthread_create_list)) {
 252                        struct kthread_create_info *create;
 253
 254                        create = list_entry(kthread_create_list.next,
 255                                            struct kthread_create_info, list);
 256                        list_del_init(&create->list);
 257                        spin_unlock(&kthread_create_lock);
 258
 259                        create_kthread(create);
 260
 261                        spin_lock(&kthread_create_lock);
 262                }
 263                spin_unlock(&kthread_create_lock);
 264        }
 265
 266        return 0;
 267}
 268
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.