-
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