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/cpuset.h>
  13#include <linux/unistd.h>
  14#include <linux/file.h>
  15#include <linux/module.h>
  16#include <linux/mutex.h>
  17#include <trace/events/sched.h>
  18
  19static DEFINE_SPINLOCK(kthread_create_lock);
  20static LIST_HEAD(kthread_create_list);
  21struct task_struct *kthreadd_task;
  22
  23struct kthread_create_info
  24{
  25        /* Information passed to kthread() from kthreadd. */
  26        int (*threadfn)(void *data);
  27        void *data;
  28
  29        /* Result passed back to kthread_create() from kthreadd. */
  30        struct task_struct *result;
  31        struct completion done;
  32
  33        struct list_head list;
  34};
  35
  36struct kthread {
  37        int should_stop;
  38        struct completion exited;
  39};
  40
  41#define to_kthread(tsk) \
  42        container_of((tsk)->vfork_done, struct kthread, exited)
  43
  44/**
  45 * kthread_should_stop - should this kthread return now?
  46 *
  47 * When someone calls kthread_stop() on your kthread, it will be woken
  48 * and this will return true.  You should then return, and your return
  49 * value will be passed through to kthread_stop().
  50 */
  51int kthread_should_stop(void)
  52{
  53        return to_kthread(current)->should_stop;
  54}
  55EXPORT_SYMBOL(kthread_should_stop);
  56
  57static int kthread(void *_create)
  58{
  59        /* Copy data: it's on kthread's stack */
  60        struct kthread_create_info *create = _create;
  61        int (*threadfn)(void *data) = create->threadfn;
  62        void *data = create->data;
  63        struct kthread self;
  64        int ret;
  65
  66        self.should_stop = 0;
  67        init_completion(&self.exited);
  68        current->vfork_done = &self.exited;
  69
  70        /* OK, tell user we're spawned, wait for stop or wakeup */
  71        __set_current_state(TASK_UNINTERRUPTIBLE);
  72        create->result = current;
  73        complete(&create->done);
  74        schedule();
  75
  76        ret = -EINTR;
  77        if (!self.should_stop)
  78                ret = threadfn(data);
  79
  80        /* we can't just return, we must preserve "self" on stack */
  81        do_exit(ret);
  82}
  83
  84static void create_kthread(struct kthread_create_info *create)
  85{
  86        int pid;
  87
  88        /* We want our own signal handler (we take no signals by default). */
  89        pid = kernel_thread(kthread, create, CLONE_FS | CLONE_FILES | SIGCHLD);
  90        if (pid < 0) {
  91                create->result = ERR_PTR(pid);
  92                complete(&create->done);
  93        }
  94}
  95
  96/**
  97 * kthread_create - create a kthread.
  98 * @threadfn: the function to run until signal_pending(current).
  99 * @data: data ptr for @threadfn.
 100 * @namefmt: printf-style name for the thread.
 101 *
 102 * Description: This helper function creates and names a kernel
 103 * thread.  The thread will be stopped: use wake_up_process() to start
 104 * it.  See also kthread_run(), kthread_create_on_cpu().
 105 *
 106 * When woken, the thread will run @threadfn() with @data as its
 107 * argument. @threadfn() can either call do_exit() directly if it is a
 108 * standalone thread for which noone will call kthread_stop(), or
 109 * return when 'kthread_should_stop()' is true (which means
 110 * kthread_stop() has been called).  The return value should be zero
 111 * or a negative error number; it will be passed to kthread_stop().
 112 *
 113 * Returns a task_struct or ERR_PTR(-ENOMEM).
 114 */
 115struct task_struct *kthread_create(int (*threadfn)(void *data),
 116                                   void *data,
 117                                   const char namefmt[],
 118                                   ...)
 119{
 120        struct kthread_create_info create;
 121
 122        create.threadfn = threadfn;
 123        create.data = data;
 124        init_completion(&create.done);
 125
 126        spin_lock(&kthread_create_lock);
 127        list_add_tail(&create.list, &kthread_create_list);
 128        spin_unlock(&kthread_create_lock);
 129
 130        wake_up_process(kthreadd_task);
 131        wait_for_completion(&create.done);
 132
 133        if (!IS_ERR(create.result)) {
 134                struct sched_param param = { .sched_priority = 0 };
 135                va_list args;
 136
 137                va_start(args, namefmt);
 138                vsnprintf(create.result->comm, sizeof(create.result->comm),
 139                          namefmt, args);
 140                va_end(args);
 141                /*
 142                 * root may have changed our (kthreadd's) priority or CPU mask.
 143                 * The kernel thread should not inherit these properties.
 144                 */
 145                sched_setscheduler_nocheck(create.result, SCHED_NORMAL, &param);
 146                set_cpus_allowed_ptr(create.result, cpu_all_mask);
 147        }
 148        return create.result;
 149}
 150EXPORT_SYMBOL(kthread_create);
 151
 152/**
 153 * kthread_stop - stop a thread created by kthread_create().
 154 * @k: thread created by kthread_create().
 155 *
 156 * Sets kthread_should_stop() for @k to return true, wakes it, and
 157 * waits for it to exit. This can also be called after kthread_create()
 158 * instead of calling wake_up_process(): the thread will exit without
 159 * calling threadfn().
 160 *
 161 * If threadfn() may call do_exit() itself, the caller must ensure
 162 * task_struct can't go away.
 163 *
 164 * Returns the result of threadfn(), or %-EINTR if wake_up_process()
 165 * was never called.
 166 */
 167int kthread_stop(struct task_struct *k)
 168{
 169        struct kthread *kthread;
 170        int ret;
 171
 172        trace_sched_kthread_stop(k);
 173        get_task_struct(k);
 174
 175        kthread = to_kthread(k);
 176        barrier(); /* it might have exited */
 177        if (k->vfork_done != NULL) {
 178                kthread->should_stop = 1;
 179                wake_up_process(k);
 180                wait_for_completion(&kthread->exited);
 181        }
 182        ret = k->exit_code;
 183
 184        put_task_struct(k);
 185        trace_sched_kthread_stop_ret(ret);
 186
 187        return ret;
 188}
 189EXPORT_SYMBOL(kthread_stop);
 190
 191int kthreadd(void *unused)
 192{
 193        struct task_struct *tsk = current;
 194
 195        /* Setup a clean context for our children to inherit. */
 196        set_task_comm(tsk, "kthreadd");
 197        ignore_signals(tsk);
 198        set_cpus_allowed_ptr(tsk, cpu_all_mask);
 199        set_mems_allowed(node_possible_map);
 200
 201        current->flags |= PF_NOFREEZE | PF_FREEZER_NOSIG;
 202
 203        for (;;) {
 204                set_current_state(TASK_INTERRUPTIBLE);
 205                if (list_empty(&kthread_create_list))
 206                        schedule();
 207                __set_current_state(TASK_RUNNING);
 208
 209                spin_lock(&kthread_create_lock);
 210                while (!list_empty(&kthread_create_list)) {
 211                        struct kthread_create_info *create;
 212
 213                        create = list_entry(kthread_create_list.next,
 214                                            struct kthread_create_info, list);
 215                        list_del_init(&create->list);
 216                        spin_unlock(&kthread_create_lock);
 217
 218                        create_kthread(create);
 219
 220                        spin_lock(&kthread_create_lock);
 221                }
 222                spin_unlock(&kthread_create_lock);
 223        }
 224
 225        return 0;
 226}
 227