signals: introduce kernel_sigaction()
authorOleg Nesterov <oleg@redhat.com>
Fri, 6 Jun 2014 21:37:00 +0000 (14:37 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 6 Jun 2014 23:08:12 +0000 (16:08 -0700)
Now that allow_signal() is really trivial we can unify it with
disallow_signal().  Add the new helper, kernel_sigaction(), and
reimplement allow_signal/disallow_signal as a trivial wrappers.

This saves one EXPORT_SYMBOL() and the new helper can have more users.

Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Al Viro <viro@ZenIV.linux.org.uk>
Cc: David Woodhouse <dwmw2@infradead.org>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Geert Uytterhoeven <geert@linux-m68k.org>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Cc: Richard Weinberger <richard@nod.at>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Tejun Heo <tj@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
include/linux/signal.h
kernel/signal.c

index ac83c593f4b96b88a5fd797d0abbc697625103ee..c9e65360c49a7ccf7ffea8195017102f27e1cd7c 100644 (file)
@@ -284,8 +284,22 @@ extern int get_signal_to_deliver(siginfo_t *info, struct k_sigaction *return_ka,
 extern void signal_setup_done(int failed, struct ksignal *ksig, int stepping);
 extern void signal_delivered(int sig, siginfo_t *info, struct k_sigaction *ka, struct pt_regs *regs, int stepping);
 extern void exit_signals(struct task_struct *tsk);
-extern void allow_signal(int);
-extern void disallow_signal(int);
+extern void kernel_sigaction(int, __sighandler_t);
+
+static inline void allow_signal(int sig)
+{
+       /*
+        * Kernel threads handle their own signals. Let the signal code
+        * know it'll be handled, so that they don't get converted to
+        * SIGKILL or just silently dropped.
+        */
+       kernel_sigaction(sig, (__force __sighandler_t)2);
+}
+
+static inline void disallow_signal(int sig)
+{
+       kernel_sigaction(sig, SIG_IGN);
+}
 
 /*
  * Eventually that'll replace get_signal_to_deliver(); macro for now,
index 3ec405132c791678726f0fa3508c387455cfe81f..a4077e90f19fcba4776af7f62a9ed2d4ddb9de03 100644 (file)
@@ -3067,37 +3067,25 @@ COMPAT_SYSCALL_DEFINE4(rt_tgsigqueueinfo,
 #endif
 
 /*
- * Let kernel threads use this to say that they allow a certain signal.
- * Must not be used if kthread was cloned with CLONE_SIGHAND.
+ * For kthreads only, must not be used if cloned with CLONE_SIGHAND
  */
-void allow_signal(int sig)
+void kernel_sigaction(int sig, __sighandler_t action)
 {
-       /*
-        * Kernel threads handle their own signals. Let the signal code
-        * know it'll be handled, so that they don't get converted to
-        * SIGKILL or just silently dropped.
-        */
        spin_lock_irq(&current->sighand->siglock);
-       current->sighand->action[(sig)-1].sa.sa_handler = (void __user *)2;
-       spin_unlock_irq(&current->sighand->siglock);
-}
-EXPORT_SYMBOL(allow_signal);
+       current->sighand->action[sig - 1].sa.sa_handler = action;
+       if (action == SIG_IGN) {
+               sigset_t mask;
 
-void disallow_signal(int sig)
-{
-       sigset_t mask;
+               sigemptyset(&mask);
+               sigaddset(&mask, sig);
 
-       sigemptyset(&mask);
-       sigaddset(&mask, sig);
-
-       spin_lock_irq(&current->sighand->siglock);
-       current->sighand->action[(sig)-1].sa.sa_handler = SIG_IGN;
-       flush_sigqueue_mask(&mask, &current->signal->shared_pending);
-       flush_sigqueue_mask(&mask, &current->pending);
-       recalc_sigpending();
+               flush_sigqueue_mask(&mask, &current->signal->shared_pending);
+               flush_sigqueue_mask(&mask, &current->pending);
+               recalc_sigpending();
+       }
        spin_unlock_irq(&current->sighand->siglock);
 }
-EXPORT_SYMBOL(disallow_signal);
+EXPORT_SYMBOL(kernel_sigaction);
 
 int do_sigaction(int sig, struct k_sigaction *act, struct k_sigaction *oact)
 {