]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
exit: Implement kthread_exit
authorEric W. Biederman <ebiederm@xmission.com>
Mon, 22 Nov 2021 16:27:36 +0000 (10:27 -0600)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 10 Apr 2024 14:18:55 +0000 (16:18 +0200)
[ Upstream commit bbda86e988d4c124e4cfa816291cbd583ae8bfb1 ]

The way the per task_struct exit_code is used by kernel threads is not
quite compatible how it is used by userspace applications.  The low
byte of the userspace exit_code value encodes the exit signal.  While
kthreads just use the value as an int holding ordinary kernel function
exit status like -EPERM.

Add kthread_exit to clearly separate the two kinds of uses.

Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
Stable-dep-of: ca3574bd653a ("exit: Rename module_put_and_exit to module_put_and_kthread_exit")
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
include/linux/kthread.h
kernel/kthread.c
tools/objtool/check.c

index db47aae7c481bddbd150cc972bf8aa496e0831fa..8e21bd13c36dd44ea9603939fa7fefbb9c1e653a 100644 (file)
@@ -95,6 +95,7 @@ void *kthread_probe_data(struct task_struct *k);
 int kthread_park(struct task_struct *k);
 void kthread_unpark(struct task_struct *k);
 void kthread_parkme(void);
+void kthread_exit(long result) __noreturn;
 
 int kthreadd(void *unused);
 extern struct task_struct *kthreadd_task;
index e319a1b62586e9298b5ca3325a96d17e37ebb5c5..4cc6897b7ca40223bc44b0219fafca0f9760dfae 100644 (file)
@@ -268,6 +268,21 @@ void kthread_parkme(void)
 }
 EXPORT_SYMBOL_GPL(kthread_parkme);
 
+/**
+ * kthread_exit - Cause the current kthread return @result to kthread_stop().
+ * @result: The integer value to return to kthread_stop().
+ *
+ * While kthread_exit can be called directly, it exists so that
+ * functions which do some additional work in non-modular code such as
+ * module_put_and_kthread_exit can be implemented.
+ *
+ * Does not return.
+ */
+void __noreturn kthread_exit(long result)
+{
+       do_exit(result);
+}
+
 static int kthread(void *_create)
 {
        /* Copy data: it's on kthread's stack */
@@ -285,13 +300,13 @@ static int kthread(void *_create)
        done = xchg(&create->done, NULL);
        if (!done) {
                kfree(create);
-               do_exit(-EINTR);
+               kthread_exit(-EINTR);
        }
 
        if (!self) {
                create->result = ERR_PTR(-ENOMEM);
                complete(done);
-               do_exit(-ENOMEM);
+               kthread_exit(-ENOMEM);
        }
 
        self->threadfn = threadfn;
@@ -318,7 +333,7 @@ static int kthread(void *_create)
                __kthread_parkme(self);
                ret = threadfn(data);
        }
-       do_exit(ret);
+       kthread_exit(ret);
 }
 
 /* called from kernel_clone() to get node information for about to be created task */
@@ -628,7 +643,7 @@ EXPORT_SYMBOL_GPL(kthread_park);
  * instead of calling wake_up_process(): the thread will exit without
  * calling threadfn().
  *
- * If threadfn() may call do_exit() itself, the caller must ensure
+ * If threadfn() may call kthread_exit() itself, the caller must ensure
  * task_struct can't go away.
  *
  * Returns the result of threadfn(), or %-EINTR if wake_up_process()
index c3bb96e5bfa64239c7055a9b80ff83ff7e755bf2..f066837d8e1aa3a9da2bcb1a68379e939336156b 100644 (file)
@@ -169,6 +169,7 @@ static bool __dead_end_function(struct objtool_file *file, struct symbol *func,
                "panic",
                "do_exit",
                "do_task_dead",
+               "kthread_exit",
                "make_task_dead",
                "__module_put_and_exit",
                "complete_and_exit",