aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/signal.c
Commit message (Collapse)AuthorAge
* signals: fix sigqueue_free() vs __exit_signal() raceOleg Nesterov2008-05-24
| | | | | | | | | | | | | | | | | | | | __exit_signal() does flush_sigqueue(tsk->pending) outside of ->siglock. This can race with another thread doing sigqueue_free(), we can free the same SIGQUEUE_PREALLOC sigqueue twice or corrupt the pending->list. Note that even sys_exit_group() can trigger this race, not only sys_timer_delete(). Move the callsite of flush_sigqueue(tsk->pending) under ->siglock. This patch doesn't touch flush_sigqueue(->shared_pending) below, it is called when there are no other threads which can play with signals, and sigqueue_free() can't be used outside of our thread group. Signed-off-by: Oleg Nesterov <oleg@tv-sign.ru> Acked-by: Roland McGrath <roland@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
* signals: add set_restore_sigmaskRoland McGrath2008-04-30
| | | | | | | | | | | | | | | | This adds the set_restore_sigmask() inline in <linux/thread_info.h> and replaces every set_thread_flag(TIF_RESTORE_SIGMASK) with a call to it. No change, but abstracts the details of the flag protocol from all the calls. Signed-off-by: Roland McGrath <roland@redhat.com> Cc: Oleg Nesterov <oleg@tv-sign.ru> Cc: Ingo Molnar <mingo@elte.hu> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Martin Schwidefsky <schwidefsky@de.ibm.com> Cc: Heiko Carstens <heiko.carstens@de.ibm.com> Cc: "Luck, Tony" <tony.luck@intel.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
* signals: allow the kernel to actually kill /sbin/initOleg Nesterov2008-04-30
| | | | | | | | | | | | | | | | | Currently the buggy /sbin/init hangs if SIGSEGV/etc happens. The kernel sends the signal, init dequeues it and ignores, returns from the exception, repeats the faulting instruction, and so on forever. Imho, such a behaviour is not good. I think that the explicit loud death of the buggy /sbin/init is better than the silent hang. Change force_sig_info() to clear SIGNAL_UNKILLABLE when the task should be really killed. Signed-off-by: Oleg Nesterov <oleg@tv-sign.ru> Cc: Roland McGrath <roland@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
* signals: fix /sbin/init protection from unwanted signalsOleg Nesterov2008-04-30
| | | | | | | | | | | | | | | | | | | | | | | | | | | | The global init has a lot of long standing problems with the unhandled fatal signals. - The "is_global_init(current)" check in get_signal_to_deliver() protects only the main thread. Sub-thread can dequee the fatal signal and shutdown the whole thread group except the main thread. If it dequeues SIGSTOP /sbin/init will be stopped, this is not right too. Note that we can't use is_global_init(->group_leader), this breaks exec and this can't solve other problems we have. - Even if afterwards ignored, the fatal signals sets SIGNAL_GROUP_EXIT on delivery. This breaks exec, has other bad implications, and this is just wrong. Introduce the new SIGNAL_UNKILLABLE flag to fix these problems. It also helps to solve some other problems addressed by the subsequent patches. Currently we use this flag for the global init only, but it could also be used by kthreads and (perhaps) by the sub-namespace inits. Signed-off-by: Oleg Nesterov <oleg@tv-sign.ru> Acked-by: "Eric W. Biederman" <ebiederm@xmission.com> Cc: Roland McGrath <roland@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
* signals: check_kill_permission: remove tasklist_lockOleg Nesterov2008-04-30
| | | | | | | | | | Now that task_session() can't return a false NULL, check_kill_permission() doesn't need tasklist_lock. Signed-off-by: Oleg Nesterov <oleg@tv-sign.ru> Cc: Roland McGrath <roland@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
* signals: check_kill_permission: check session under tasklist_lockOleg Nesterov2008-04-30
| | | | | | | | | | | | | | | | | | | | | | | This wasn't documented, but as Atsushi Tsuji pointed out check_kill_permission() needs tasklist_lock for task_session_nr(). I missed this fact when removed tasklist from the callers. Change check_kill_permission() to take tasklist_lock for the SIGCONT case. Re-order security checks so that we take tasklist_lock only if/when it is actually needed. This is a minimal fix for now, tasklist will be removed later. Also change the code to use task_session() instead of task_session_nr(). Also, remove the SIGCONT check from cap_task_kill(), it is bogus (and the whole function is bogus. Serge, Eric, why it is still alive?). Signed-off-by: Oleg Nesterov <oleg@tv-sign.ru> Acked-by: Atsushi Tsuji <a-tsuji@bk.jp.nec.com> Cc: Roland McGrath <roland@redhat.com> Cc: Serge Hallyn <serue@us.ibm.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
* signals: send_signal: be paranoid about signalfd_notify()Oleg Nesterov2008-04-30
| | | | | | | | | | | | | | send_signal() shouldn't call signalfd_notify() if it then fails with -EAGAIN. Harmless, just a paranoid cleanup. Also remove the comment. It is obsolete, signalfd_notify() was simplified and does a simple wakeup. Signed-off-by: Oleg Nesterov <oleg@tv-sign.ru> Acked-by: Davide Libenzi <davidel@xmailserver.org> Cc: Roland McGrath <roland@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
* signals: document CLD_CONTINUED notification mechanicsOleg Nesterov2008-04-30
| | | | | | | | | A couple of small comments about how CLD_CONTINUED notification works. Signed-off-by: Oleg Nesterov <oleg@tv-sign.ru> Cc: Roland McGrath <roland@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
* signals: fold sig_ignored() into handle_stop_signal()Oleg Nesterov2008-04-30
| | | | | | | | | | | | | | | Rename handle_stop_signal() to prepare_signal(), make it return a boolean, and move the callsites of sig_ignored() into it. No functional changes for now. But it would be nice to factor out the "should we drop this signal" checks as much as possible, before we try to fix the bugs with the sub-namespace init's signals (actually the global /sbin/init has some problems with signals too). Signed-off-by: Oleg Nesterov <oleg@tv-sign.ru> Cc: Roland McGrath <roland@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
* signals: cleanup the usage of print_fatal_signal()Oleg Nesterov2008-04-30
| | | | | | | | | | | | | | Move the callsite of print_fatal_signal() down, under "if (sig_kernel_coredump(signr))", so we don't need to check signr != SIGKILL. We are only interested in the sig_kernel_coredump() signals anyway, and due to the previous changes we almost never can see other fatal signals here except SIGKILL. Signed-off-by: Oleg Nesterov <oleg@tv-sign.ru> Cc: Roland McGrath <roland@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
* signals: handle_stop_signal: don't worry about SIGKILLOleg Nesterov2008-04-30
| | | | | | | | | | | | | | | | | | | | | | | handle_stop_signal() clears SIGNAL_STOP_DEQUEUED when sig == SIGKILL. Remove this nasty special case. It was needed to prevent the race with group stop and exit caused by thread-specific SIGKILL. Now that we use complete_signal() for private signals too this is not needed, complete_signal() will notice SIGKILL and abort the soon-to-begin group stop. Except: the target thread is dead (has PF_EXITING). But in that case we should not just clear SIGNAL_STOP_DEQUEUED and nothing more. We should either kill the whole thread group, or silently ignore the signal. I suspect we are not right wrt zombie leaders, but this is another issue which and should be fixed separately. Note that this check can't abort the group stop if it was already started/finished, this check only adds a subtle side effect if we race with the thread which has already dequeued sig_kernel_stop() signal and temporary released ->siglock. Signed-off-by: Oleg Nesterov <oleg@tv-sign.ru> Cc: Roland McGrath <roland@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
* signals: join send_sigqueue() with send_group_sigqueue()Oleg Nesterov2008-04-30
| | | | | | | | | | | | | | We export send_sigqueue() and send_group_sigqueue() for the only user, posix_timer_event(). This is a bit silly, because both are just trivial helpers on top of do_send_sigqueue() and because the we pass the unused .si_signo parameter. Kill them both, rename do_send_sigqueue() to send_sigqueue(), and export it. Signed-off-by: Oleg Nesterov <oleg@tv-sign.ru> Cc: Roland McGrath <roland@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
* signals: unify send_sigqueue/send_group_sigqueue completelyOleg Nesterov2008-04-30
| | | | | | | | | | | | | | | | Suggested by Pavel Emelyanov. send_sigqueue/send_group_sigqueue are only differ in how they lock ->siglock. Unify them. send_group_sigqueue() uses spin_lock() because it knows the task can't exit, but in that case lock_task_sighand() can't fail and doesn't hurt. Note that the "sig" argument is ignored, it is always equal to ->si_signo. Signed-off-by: Pavel Emelyanov <xemul@openvz.org> Signed-off-by: Oleg Nesterov <oleg@tv-sign.ru> Cc: Roland McGrath <roland@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
* signals: fold complete_signal() into send_signal/do_send_sigqueuePavel Emelyanov2008-04-30
| | | | | | | | | | | Factor out complete_signal() callsites. This change completely unifies the helpers sending the specific/group signals. Signed-off-by: Pavel Emelyanov <xemul@openvz.org> Signed-off-by: Oleg Nesterov <oleg@tv-sign.ru> Cc: Roland McGrath <roland@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
* signals: use __group_complete_signal() for the specific signals tooOleg Nesterov2008-04-30
| | | | | | | | | | | | | | | | | | | | | | | | | | Based on Pavel Emelyanov's suggestion. Rename __group_complete_signal() to complete_signal() and use it to process the specific signals too. To do this we simply add the "int group" argument. This allows us to greatly simply the signal-sending code and adds a useful behaviour change. We can avoid the unneeded wakeups for the private signals because wants_signal() is more clever than sigismember(blocked), but more importantly we now take into account the fatal specific signals too. The latter allows us to kill some subtle checks in handle_stop_signal() and makes the specific/group signal's behaviour more consistent. For example, currently sigtimedwait(FATAL_SIGNAL) behaves differently depending on was the signal sent by kill() or tkill() if the signal was not blocked. And. This allows us to tweak/fix the behaviour when the specific signal is sent to the dying/dead ->group_leader. Signed-off-by: Pavel Emelyanov <xemul@openvz.org> Signed-off-by: Oleg Nesterov <oleg@tv-sign.ru> Cc: Roland McGrath <roland@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
* signals: change send_signal/do_send_sigqueue to take "boolean group" parameterOleg Nesterov2008-04-30
| | | | | | | | | | send_signal() is used either with ->pending or with ->signal->shared_pending. Change it to take "int group" instead, this argument will be re-used later. Signed-off-by: Oleg Nesterov <oleg@tv-sign.ru> Cc: Roland McGrath <roland@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
* signals: move the definition of __group_complete_signal() upOleg Nesterov2008-04-30
| | | | | | | | | | Move the unchanged definition of __group_complete_signal() so that send_signal can see it. To simplify the reading of the next patches. Signed-off-by: Oleg Nesterov <oleg@tv-sign.ru> Cc: Roland McGrath <roland@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
* signals: microoptimize the usage of ->curr_targetOleg Nesterov2008-04-30
| | | | | | | | | | | | Suggested by Roland McGrath. Initialize signal->curr_target in copy_signal(). This way ->curr_target is never == NULL, we can kill the check in __group_complete_signal's hot path. Signed-off-by: Oleg Nesterov <oleg@tv-sign.ru> Cc: Roland McGrath <roland@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
* signals: send_sig_info: don't take tasklist_lockOleg Nesterov2008-04-30
| | | | | | | | | | | | | | | | | | | The comment in send_sig_info() is wrong, tasklist_lock can't help. The caller must ensure the task can't go away, otherwise ->sighand can be NULL even before we take the lock. p->sighand could be changed by exec(), but I can't imagine how it is possible to prevent exit(), but not exec(). Since the things seem to work, I assume all callers are correct. However, drm_vbl_send_signals() looks broken. block_all_signals() which is solely used by drm is definitely broken. Signed-off-by: Oleg Nesterov <oleg@tv-sign.ru> Cc: Roland McGrath <roland@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
* signals: do_tkill: don't use tasklist_lockOleg Nesterov2008-04-30
| | | | | | | | | | | | | | Convert do_tkill() to use rcu_read_lock() + lock_task_sighand() to avoid taking tasklist lock. Note that we don't return an error if lock_task_sighand() fails, we pretend the task dies after receiving the signal. Otherwise, we should fight with the nasty races with mt-exec without having any advantage. Signed-off-by: Oleg Nesterov <oleg@tv-sign.ru> Cc: Roland McGrath <roland@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
* signals: move handle_stop_signal() into send_signal()Oleg Nesterov2008-04-30
| | | | | | | | | | | | | | | | | | | Move handle_stop_signal() into send_signal(). This factors out a couple of callsites and allows us to do further unifications. Also, with this change specific_send_sig_info() does handle_stop_signal(). Not that this is really important, we never send STOP/CONT via send_sig() and friends, but still this looks more consistent. The only (afaics) special case is get_signal_to_deliver(). If the traced task dequeues SIGCONT, it can re-send it to itself after ptrace_stop() if the signal was blocked by debugger. In that case handle_stop_signal() is unnecessary, but hopefully not a problem. Signed-off-by: Oleg Nesterov <oleg@tv-sign.ru> Cc: Roland McGrath <roland@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
* signals: send_group_sigqueue: don't take tasklist_lockOleg Nesterov2008-04-30
| | | | | | | | | | handle_stop_signal() was changed, now send_group_sigqueue() doesn't need tasklist_lock. Signed-off-by: Oleg Nesterov <oleg@tv-sign.ru> Cc: Roland McGrath <roland@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
* signals: __group_complete_signal: cache the value of p->signalOleg Nesterov2008-04-30
| | | | | | | | | Cosmetic, cache p->signal to make the code a bit more readable. Signed-off-by: Oleg Nesterov <oleg@tv-sign.ru> Cc: Roland McGrath <roland@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
* signals: send_sigqueue: don't forget about handle_stop_signal()Oleg Nesterov2008-04-30
| | | | | | | | | | | | | send_group_sigqueue() calls handle_stop_signal(), send_sigqueue() doesn't. This is not consistent and in fact I'd say this is (minor) bug. Move handle_stop_signal() from send_group_sigqueue() to do_send_sigqueue(), the latter is called by send_sigqueue() too. Signed-off-by: Oleg Nesterov <oleg@tv-sign.ru> Cc: Roland McGrath <roland@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
* signals: send_sigqueue: don't take rcu lockOleg Nesterov2008-04-30
| | | | | | | | | | lock_task_sighand() was changed, send_sigqueue() doesn't need rcu_read_lock() any longer. Signed-off-by: Oleg Nesterov <oleg@tv-sign.ru> Cc: Roland McGrath <roland@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
* get_signal_to_deliver: use the cached ->signal/sighand valuesOleg Nesterov2008-04-30
| | | | | | | | | | | | Cache the values of current->signal/sighand. Shrinks .text a bit and makes the code more readable. Also, remove "sigset_t *mask", it is pointless because in fact we save the constant offset. Signed-off-by: Oleg Nesterov <oleg@tv-sign.ru> Cc: Roland McGrath <roland@redhat.com> Cc: Jiri Kosina <jkosina@suse.cz> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
* handle_stop_signal: use the cached p->signal valueOleg Nesterov2008-04-30
| | | | | | | | | | | Cache the value of p->signal, and change the code to use while_each_thread() helper. Signed-off-by: Oleg Nesterov <oleg@tv-sign.ru> Cc: Roland McGrath <roland@redhat.com> Cc: Jiri Kosina <jkosina@suse.cz> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
* handle_stop_signal: unify partial/full stop handlingOleg Nesterov2008-04-30
| | | | | | | | | | | | | | Now that handle_stop_signal() doesn't drop ->siglock, we can't see both ->group_stop_count && SIGNAL_STOP_STOPPED. Merge two "if" branches. As Roland pointed out, we never actually needed 2 do_notify_parent_cldstop() calls. Signed-off-by: Oleg Nesterov <oleg@tv-sign.ru> Cc: Roland McGrath <roland@redhat.com> Cc: Jiri Kosina <jkosina@suse.cz> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
* kill_pid_info: don't take now unneeded tasklist_lockOleg Nesterov2008-04-30
| | | | | | | | | | | | Previously handle_stop_signal(SIGCONT) could drop ->siglock. That is why kill_pid_info(SIGCONT) takes tasklist_lock to make sure the target task can't go away after unlock. Not needed now. Signed-off-by: Oleg Nesterov <oleg@tv-sign.ru> Cc: Roland McGrath <roland@redhat.com> Cc: Jiri Kosina <jkosina@suse.cz> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
* signals: re-assign CLD_CONTINUED notification from the sender to recieverOleg Nesterov2008-04-30
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Based on discussion with Jiri and Roland. In short: currently handle_stop_signal(SIGCONT, p) sends the notification to p->parent, with this patch p itself notifies its parent when it becomes running. handle_stop_signal(SIGCONT) has to drop ->siglock temporary in order to notify the parent with do_notify_parent_cldstop(). This leads to multiple problems: - as Jiri Kosina pointed out, the stopped task can resume without actually seeing SIGCONT which may have a handler. - we race with another sig_kernel_stop() signal which may come in that window. - we race with sig_fatal() signals which may set SIGNAL_GROUP_EXIT in that window. - we can't avoid taking tasklist_lock() while sending SIGCONT. With this patch handle_stop_signal() just sets the new SIGNAL_CLD_CONTINUED flag in p->signal->flags and returns. The notification is sent by the first task which returns from finish_stop() (there should be at least one) or any other signalled thread from get_signal_to_deliver(). This is a user-visible change. Say, currently kill(SIGCONT, stopped_child) can't return without seeing SIGCHLD, with this patch SIGCHLD can be delayed unpredictably. Another difference is that if the child is ptraced by another process, CLD_CONTINUED may be delivered to ->real_parent after ptrace_detach() while currently it always goes to the tracer which doesn't actually need this notification. Hopefully not a problem. The patch asks for the futher obvious cleanups, I'll send them separately. Signed-off-by: Oleg Nesterov <oleg@tv-sign.ru> Cc: Roland McGrath <roland@redhat.com> Cc: Jiri Kosina <jkosina@suse.cz> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
* signals: cleanup security_task_kill() usage/implementationOleg Nesterov2008-04-30
| | | | | | | | | | | | | | | | | | | | | | | | | | Every implementation of ->task_kill() does nothing when the signal comes from the kernel. This is correct, but means that check_kill_permission() should call security_task_kill() only for SI_FROMUSER() case, and we can remove the same check from ->task_kill() implementations. (sadly, check_kill_permission() is the last user of signal->session/__session but we can't s/task_session_nr/task_session/ here). NOTE: Eric W. Biederman pointed out cap_task_kill() should die, and I think he is very right. Signed-off-by: Oleg Nesterov <oleg@tv-sign.ru> Cc: "Eric W. Biederman" <ebiederm@xmission.com> Cc: Serge Hallyn <serue@us.ibm.com> Cc: Roland McGrath <roland@redhat.com> Cc: Casey Schaufler <casey@schaufler-ca.com> Cc: David Quigley <dpquigl@tycho.nsa.gov> Cc: Eric Paris <eparis@redhat.com> Cc: Harald Welte <laforge@gnumonks.org> Cc: Pavel Emelyanov <xemul@openvz.org> Cc: Stephen Smalley <sds@tycho.nsa.gov> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
* signals: consolidate send_sigqueue and send_group_sigqueuePavel Emelyanov2008-04-30
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Both functions do the same thing after proper locking, but with different sigpending structs, so move the common code into a helper. After this we have 4 places that look very similar: send_sigqueue: calls do_send_sigqueue and signal_wakeup send_group_sigqueue: calls do_send_sigqueue and __group_complete_signal __group_send_sig_info: calls send_signal and __group_complete_signal specific_send_sig_info: calls send_signal and signal_wakeup Besides, send_signal performs actions similar to do_send_sigqueue's and __group_complete_signal - to signal_wakeup. It looks like they can be consolidated gracefully. Oleg said: Personally, I think this change is very good. But send_sigqueue() and send_group_sigqueue() have a very subtle difference which I was never able to understand. Let's suppose that sigqueue is already queued, and the signal is ignored (the latter means we should re-schedule cpu timer or handle overrruns). In that case send_sigqueue() returns 0, but send_group_sigqueue() returns 1. I think this is not the problem (in fact, I think this patch makes the behaviour more correct), but I hope Thomas can take a look and confirm. Signed-off-by: Pavel Emelyanov <xemul@openvz.org> Cc: Oleg Nesterov <oleg@tv-sign.ru> Cc: Roland McGrath <roland@redhat.com> Cc: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
* signals: clean dequeue_signal from excess checks and assignmentsPavel Emelyanov2008-04-30
| | | | | | | | | | | | | | | | | The signr variable may be declared without initialization - it is set ro the return value from __dequeue_signal() right at the function beginning. Besides, after recalc_sigpending() two checks for signr to be not 0 may be merged into one. Both if-s become easier to read. Thanks to Oleg for pointing out mistakes in the first version of this patch. Signed-off-by: Pavel Emelyanov <xemul@openvz.org> Cc: Oleg Nesterov <oleg@tv-sign.ru> Cc: Roland McGrath <roland@redhat.com> Cc: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
* signals: consolidate checks for whether or not to ignore a signalPavel Emelyanov2008-04-30
| | | | | | | | | | | | | | | | | Both sig_ignored() and do_sigaction() check for signr to be explicitly or implicitly ignored. Introduce a helper for them. This patch is aimed to help handling signals by pid namespace's init, and was derived from one of Oleg's patches https://lists.linux-foundation.org/pipermail/containers/2007-December/009308.html so, if he doesn't mind, he should be considered as an author. Signed-off-by: Pavel Emelyanov <xemul@openvz.org> Cc: Oleg Nesterov <oleg@tv-sign.ru> Cc: Roland McGrath <roland@redhat.com> Cc: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
* lock_task_sighand: add rcu lock/unlockOleg Nesterov2008-04-30
| | | | | | | | | | | | | Most of the callers of lock_task_sighand() doesn't actually need rcu_lock(). lock_task_sighand() needs it only to safely play with tsk->sighand, it can take the lock itself. Signed-off-by: Oleg Nesterov <oleg@tv-sign.ru> Cc: "Eric W. Biederman" <ebiederm@xmission.com> Cc: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com> Cc: Roland McGrath <roland@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
* signals: do_signal_stop(): use signal_group_exit()Oleg Nesterov2008-04-30
| | | | | | | | | | | | do_signal_stop() needs signal_group_exit() but checks sig->group_exit_task. This (optimization) is correct, SIGNAL_STOP_DEQUEUED and SIGNAL_GROUP_EXIT are mutually exclusive, but looks confusing. Use signal_group_exit(), this is not fastpath, the code clarity is more important. Signed-off-by: Oleg Nesterov <oleg@tv-sign.ru> Cc: Roland McGrath <roland@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
* signals: consolidate checking for ignored/legacy signalsPavel Emelyanov2008-04-30
| | | | | | | | | | | | | | | | | Two callers for send_signal() - the specific_send_sig_info and the __group_send_sig_info - both check for sig to be ignored or already queued. Move these checks into send_signal() and make it return 1 to indicate that the signal is dropped, but there's no error in this. Besides, merge comments and spell-check them. [oleg@tv-sign.ru: simplifications] Signed-off-by: Pavel Emelyanov <xemul@openvz.org> Cc: Roland McGrath <roland@redhat.com> Signed-off-by: Oleg Nesterov <oleg@tv-sign.ru> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
* signals: turn LEGACY_QUEUE macro into static inline functionPavel Emelyanov2008-04-30
| | | | | | | | | | | | | This makes the code more readable, due to less brackets and small letters in name. I also move it above the send_signal() as a preparation for the 3rd patch. Signed-off-by: Pavel Emelyanov <xemul@openvz.org> Cc: Roland McGrath <roland@redhat.com> Cc: Oleg Nesterov <oleg@tv-sign.ru> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
* signals: remove unused variable from send_signal()Pavel Emelyanov2008-04-30
| | | | | | | | | | | This function doesn't change the ret's value and thus always returns 0, with a single exception of returning -EAGAIN explicitly. Signed-off-by: Pavel Emelyanov <xemul@openvz.org> Cc: Roland McGrath <roland@redhat.com> Cc: Oleg Nesterov <oleg@tv-sign.ru> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
* trivial: small cleanupsPavel Machek2008-04-21
| | | | | | | | | | These are small cleanups all over the tree. Trivial style and comment changes to fs/select.c, kernel/signal.c, kernel/stop_machine.c & mm/pdflush.c Signed-off-by: Pavel Machek <pavel@suse.cz> Signed-off-by: Jesper Juhl <jesper.juhl@gmail.com>
* ptrace_signal subroutineRoland McGrath2008-04-18
| | | | | | | | | | | | | This breaks out the ptrace handling from get_signal_to_deliver into a new subroutine. The actual code there doesn't change, and it gets inlined into nearly identical compiled code. This makes the function substantially shorter and thus easier to read, and it nicely isolates the ptrace magic. Signed-off-by: Roland McGrath <roland@redhat.com> Acked-by: Kyle McMartin <kyle@mcmartin.ca> Cc: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
* freezer vs stopped or tracedRoland McGrath2008-03-04
| | | | | | | | | | | | | | | | | | | | | | | | This changes the "freezer" code used by suspend/hibernate in its treatment of tasks in TASK_STOPPED (job control stop) and TASK_TRACED (ptrace) states. As I understand it, the intent of the "freezer" is to hold all tasks from doing anything significant. For this purpose, TASK_STOPPED and TASK_TRACED are "frozen enough". It's possible the tasks might resume from ptrace calls (if the tracer were unfrozen) or from signals (including ones that could come via timer interrupts, etc). But this doesn't matter as long as they quickly block again while "freezing" is in effect. Some minor adjustments to the signal.c code make sure that try_to_freeze() very shortly follows all wakeups from both kinds of stop. This lets the freezer code safely leave stopped tasks unmolested. Changing this fixes the longstanding bug of seeing after resuming from suspend/hibernate your shell report "[1] Stopped" and the like for all your jobs stopped by ^Z et al, as if you had freshly fg'd and ^Z'd them. It also removes from the freezer the arcane special case treatment for ptrace'd tasks, which relied on intimate knowledge of ptrace internals. Signed-off-by: Roland McGrath <roland@redhat.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
* remove final fastcall usersHarvey Harrison2008-02-13
| | | | | | | | fastcall always expands to empty, remove it. Signed-off-by: Harvey Harrison <harvey.harrison@gmail.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
* Get rid of the kill_pgrp_info() functionPavel Emelyanov2008-02-08
| | | | | | | | | | There's only one caller left - the kill_pgrp one - so merge these two functions and forget the kill_pgrp_info one. Signed-off-by: Pavel Emelyanov <xemul@openvz.org> Reviewed-by: Oleg Nesterov <oleg@tv-sign.ru> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
* Clean up the kill_something_infoPavel Emelyanov2008-02-08
| | | | | | | | | | | | | | | | | | This is the first step (of two) in removing the kill_pgrp_info. All the users of this function are in kernel/signal.c, but all they need is to call __kill_pgrp_info() with the tasklist_lock read-locked. Fortunately, one of its users is the kill_something_info(), which already needs this lock in one of its branches, so clean these branches up and call the __kill_pgrp_info() directly. Based on Oleg's view of how this function should look. Signed-off-by: Oleg Nesterov <oleg@tv-sign.ru> Signed-off-by: Pavel Emelyanov <xemul@openvz.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
* ITIMER_REAL: convert to use struct pidOleg Nesterov2008-02-08
| | | | | | | | | | | | | | | | | | signal_struct->tsk points to the ->group_leader and thus we have the nasty code in de_thread() which has to change it and restart ->real_timer if the leader is changed. Use "struct pid *leader_pid" instead. This also allows us to kill now unneeded send_group_sig_info(). Signed-off-by: Oleg Nesterov <oleg@tv-sign.ru> Acked-by: "Eric W. Biederman" <ebiederm@xmission.com> Cc: Davide Libenzi <davidel@xmailserver.org> Cc: Pavel Emelyanov <xemul@openvz.org> Acked-by: Roland McGrath <roland@redhat.com> Acked-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
* uglify kill_pid_info() to fix kill() vs exec() raceOleg Nesterov2008-02-08
| | | | | | | | | | | | | | | | | | kill_pid_info()->pid_task() could be the old leader of the execing process. In that case it is possible that the leader will be released before we take siglock. This means that kill_pid_info() (and thus sys_kill()) can return a false -ESRCH. Change the code to retry when lock_task_sighand() fails. The endless loop is not possible, __exit_signal() both clears ->sighand and does detach_pid(). Signed-off-by: Oleg Nesterov <oleg@tv-sign.ru> Cc: "Eric W. Biederman" <ebiederm@xmission.com> Cc: Davide Libenzi <davidel@xmailserver.org> Cc: Pavel Emelyanov <xemul@openvz.org> Cc: Roland McGrath <roland@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
* move the related code from exit_notify() to exit_signals()Oleg Nesterov2008-02-08
| | | | | | | | | | | | | | | | | | | | | | The previous bugfix was not optimal, we shouldn't care about group stop when we are the only thread or the group stop is in progress. In that case nothing special is needed, just set PF_EXITING and return. Also, take the related "TIF_SIGPENDING re-targeting" code from exit_notify(). So, from the performance POV the only difference is that we don't trust !signal_pending() until we take ->siglock. But this in fact fixes another ___pure___ theoretical minor race. __group_complete_signal() finds the task without PF_EXITING and chooses it as the target for signal_wake_up(). But nothing prevents this task from exiting in between without noticing the pending signal and thus unpredictably delaying the actual delivery. Signed-off-by: Oleg Nesterov <oleg@tv-sign.ru> Cc: Davide Libenzi <davidel@xmailserver.org> Cc: Ingo Molnar <mingo@elte.hu> Cc: Roland McGrath <roland@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
* fix group stop with exit raceOleg Nesterov2008-02-08
| | | | | | | | | | | | | | | | | | | | | do_signal_stop() counts all sub-thread and sets ->group_stop_count accordingly. Every thread should decrement ->group_stop_count and stop, the last one should notify the parent. However a sub-thread can exit before it notices the signal_pending(), or it may be somewhere in do_exit() already. In that case the group stop never finishes properly. Note: this is a minimal fix, we can add some optimizations later. Say we can return quickly if thread_group_empty(). Also, we can move some signal related code from exit_notify() to exit_signals(). Signed-off-by: Oleg Nesterov <oleg@tv-sign.ru> Acked-by: Davide Libenzi <davidel@xmailserver.org> Cc: Ingo Molnar <mingo@elte.hu> Cc: Roland McGrath <roland@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
* ptrace_stop: fix racy nonstop_code settingOleg Nesterov2008-02-08
| | | | | | | | | | | | | | | | | | | | If the tracer is gone and we are not going to stop, ptrace_stop() sets ->exit_code = nostop_code. However, the tracer could actually clear the exit code before detaching. In that case get_signal_to_deliver() "resends" the signal which was cancelled by the debugger. For example, it is possible that a quick PTRACE_ATTACH + PTRACE_DETACH can leave the tracee in STOPPED state. Change the behaviour of ptrace_stop(). If the caller is ptrace notify(), we should always clear ->exit_code. If the caller is get_signal_to_deliver(), we should not touch it at all. To do so, change the nonstop_code parameter to "bool clear_code" and change the callers accordingly. Signed-off-by: Oleg Nesterov <oleg@tv-sign.ru> Acked-by: Roland McGrath <roland@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>