]> git.hungrycats.org Git - linux/commitdiff
[PATCH] uml: eliminate signal order delivery dependency
authorJeff Dike <jdike@addtoit.com>
Fri, 17 Sep 2004 05:12:07 +0000 (22:12 -0700)
committerLinus Torvalds <torvalds@ppc970.osdl.org>
Fri, 17 Sep 2004 05:12:07 +0000 (22:12 -0700)
On 2.4 hosts signals are delivered in numeric order when there are multiple
pending at a given time.  UML developed a subtle dependency on this
ordering, which broke on 2.6 hosts and the separate process and thread
signal queues.

This patch eliminates that dependency.

Signed-off-by: Jeff Dike <jdike@addtoit.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
arch/um/kernel/process.c
arch/um/kernel/tt/exec_kern.c
arch/um/kernel/tt/process_kern.c
arch/um/kernel/tt/trap_user.c
arch/um/os-Linux/process.c

index 41c66d4b0877b88a81e8a19f042d4579369a360c..4468f244091c90864c9e0d0fc360b5e4943d16a5 100644 (file)
@@ -70,7 +70,7 @@ void init_new_thread_signals(int altstack)
        set_handler(SIGWINCH, (__sighandler_t) sig_handler, flags, 
                    SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
        set_handler(SIGUSR2, (__sighandler_t) sig_handler, 
-                   SA_NOMASK | flags, -1);
+                   flags, SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
        signal(SIGHUP, SIG_IGN);
 
        init_irq_signals(altstack);
index 257b341f82b356fc1222fe90ec88a548881c58a4..065b504a653b1d9cbe87998e92cf7f85486427fe 100644 (file)
@@ -14,6 +14,7 @@
 #include "kern_util.h"
 #include "irq_user.h"
 #include "time_user.h"
+#include "signal_user.h"
 #include "mem_user.h"
 #include "os.h"
 #include "tlb.h"
@@ -53,7 +54,9 @@ void flush_thread_tt(void)
        current->thread.request.u.exec.pid = new_pid;
        unprotect_stack((unsigned long) current_thread);
        os_usr1_process(os_getpid());
+       change_sig(SIGUSR1, 1);
 
+       change_sig(SIGUSR1, 0);
        enable_timer();
        free_page(stack);
        protect_memory(uml_reserved, high_physmem - uml_reserved, 1, 1, 0, 1);
index e4e8cbf2a9e94041e2c1b5b12d8038ff2a348d16..6224afcd84d7e51e803d7a14c14ae57fd9e9db22 100644 (file)
@@ -201,6 +201,7 @@ static int new_thread_proc(void *stack)
        local_irq_disable();
        init_new_thread_stack(stack, new_thread_handler);
        os_usr1_process(os_getpid());
+       change_sig(SIGUSR1, 1);
        return(0);
 }
 
@@ -244,6 +245,7 @@ int fork_tramp(void *stack)
        init_new_thread_stack(stack, finish_fork_handler);
 
        os_usr1_process(os_getpid());
+       change_sig(SIGUSR1, 1);
        return(0);
 }
 
@@ -295,19 +297,30 @@ int copy_thread_tt(int nr, unsigned long clone_flags, unsigned long sp,
        current->thread.request.op = OP_FORK;
        current->thread.request.u.fork.pid = new_pid;
        os_usr1_process(os_getpid());
-       return(0);
+
+       /* Enable the signal and then disable it to ensure that it is handled
+        * here, and nowhere else.
+        */
+       change_sig(SIGUSR1, 1);
+
+       change_sig(SIGUSR1, 0);
+       err = 0;
+ out:
+       return(err);
 }
 
 void reboot_tt(void)
 {
        current->thread.request.op = OP_REBOOT;
        os_usr1_process(os_getpid());
+       change_sig(SIGUSR1, 1);
 }
 
 void halt_tt(void)
 {
        current->thread.request.op = OP_HALT;
        os_usr1_process(os_getpid());
+       change_sig(SIGUSR1, 1);
 }
 
 void kill_off_processes_tt(void)
@@ -334,6 +347,9 @@ void initial_thread_cb_tt(void (*proc)(void *), void *arg)
                current->thread.request.u.cb.proc = proc;
                current->thread.request.u.cb.arg = arg;
                os_usr1_process(os_getpid());
+               change_sig(SIGUSR1, 1);
+
+               change_sig(SIGUSR1, 0);
        }
 }
 
index 693f506633e64f8b7f9be1ac480679c0fe3e2653..00bacacfcc35294f7a0a3f079796f55fd5598af2 100644 (file)
@@ -37,7 +37,6 @@ void sig_handler_common_tt(int sig, void *sc_ptr)
        if(sig != SIGUSR2) 
                r->syscall = -1;
 
-       change_sig(SIGUSR1, 1);
        info = &sig_info[sig];
        if(!info->is_irq) unblock_signals();
 
@@ -46,7 +45,6 @@ void sig_handler_common_tt(int sig, void *sc_ptr)
        if(is_user){
                interrupt_end();
                block_signals();
-               change_sig(SIGUSR1, 0);
                set_user_mode(NULL);
        }
        *r = save_regs;
index 57deb70ac26edf5e1a9dbc5b44f03b2c0079a279..ec4617b42886d056e4688017eea7385c1aa0b067 100644 (file)
@@ -96,11 +96,7 @@ void os_kill_process(int pid, int reap_child)
 
 void os_usr1_process(int pid)
 {
-#ifdef __NR_tkill
-       syscall(__NR_tkill, pid, SIGUSR1);
-#else
        kill(pid, SIGUSR1);
-#endif
 }
 
 int os_getpid(void)