• Ingo Molnar's avatar
    [PATCH] signal latency fixes · 79e4dd94
    Ingo Molnar authored
    This fixes an SMP window where the kernel could miss to handle a signal,
    and increase signal delivery latency up to 200 msecs.  Sun has reported
    to Ulrich that their JVM sees occasional unexpected signal delays under
    Linux.  The more CPUs, the more delays.
    
    The cause of the problem is that the current signal wakeup
    implementation is racy in kernel/signal.c:signal_wake_up():
    
            if (t->state == TASK_RUNNING)
                    kick_if_running(t);
    	...
            if (t->state & mask) {
                    wake_up_process(t);
                    return;
            }
    
    If thread (or process) 't' is woken up on another CPU right after the
    TASK_RUNNING check, and thread starts to run, then the wake_up_process()
    here will do nothing, and the signal stays pending up until the thread
    will call into the kernel next time - which can be up to 200 msecs
    later.
    
    The solution is to do the 'kicking' of a running thread on a remote CPU
    atomically with the wakeup.  For this i've added wake_up_process_kick().
    There is no slowdown for the other wakeup codepaths, the new flag to
    try_to_wake_up() is compiled off for them.  Some other subsystems might
    want to use this wakeup facility as well in the future (eg.  AIO).
    
    In fact this race triggers quite often under Volanomark rusg, with this
    change added, Volanomark performance is up from 500-800 to 2000-3000, on
    a 4-way x86 box.
    79e4dd94
signal.c 57 KB