Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754096AbZIXAgT (ORCPT ); Wed, 23 Sep 2009 20:36:19 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1753226AbZIXAgR (ORCPT ); Wed, 23 Sep 2009 20:36:17 -0400 Received: from smtp231.iad.emailsrvr.com ([207.97.245.231]:39153 "EHLO smtp231.iad.emailsrvr.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753463AbZIXA3y (ORCPT ); Wed, 23 Sep 2009 20:29:54 -0400 From: Oren Laadan To: Andrew Morton Cc: Linus Torvalds , containers@lists.linux-foundation.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org, linux-api@vger.kernel.org, Serge Hallyn , Ingo Molnar , Pavel Emelyanov , Oren Laadan , Oren Laadan Subject: [PATCH v18 27/80] c/r: introduce PF_RESTARTING, and skip notification on exit Date: Wed, 23 Sep 2009 19:51:07 -0400 Message-Id: <1253749920-18673-28-git-send-email-orenl@librato.com> X-Mailer: git-send-email 1.6.0.4 In-Reply-To: <1253749920-18673-1-git-send-email-orenl@librato.com> References: <1253749920-18673-1-git-send-email-orenl@librato.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 3582 Lines: 94 To restore zombie's we will create the a task, that, on its turn to run, calls do_exit(). Unlike normal tasks that exit, we need to prevent notification side effects that send signals to other processes, e.g. parent (SIGCHLD) or child tasks (per child's request). There are three main cases for such notifications: 1) do_notify_parent(): parent of a process is notified about a change in status (e.g. become zombie, reparent, etc). If parent ignores, then mark child for immediate release (skip zombie). 2) kill_orphan_pgrp(): a process group that becomes orphaned will signal stopped jobs (HUP then CONT). 3) reparent_thread(): children of a process are signaled (per request) with p->pdeath_signal Remember that restoring signal state (for any restarting task) must complete _before_ it is allowed to resume execution, and not during the resume. Otherwise, a running task may send a signal to another task that hasn't restored yet, so the new signal will be lost soon-after. I considered two possible way to address this: 1. Add another sync point to restart: all tasks will first restore their state without signals (all signals blocked), and zombies call do_exit(). A sync point then will ensure that all zombies are gone and their effects done. Then all tasks restore their signal state (and mask), and sync (new point) again. Only then they may resume execution. The main disadvantage is the added complexity and inefficiency, for no good reason. 2. Introduce PF_RESTARTING: mark all restarting tasks with a new flag, and teach the above three notifications to skip sending the signal if theis flag is set. The main advantage is simplicity and completeness. Also, such a flag may to be useful later on. This the method implemented. Signed-off-by: Oren Laadan --- kernel/exit.c | 7 ++++++- kernel/signal.c | 4 ++++ 2 files changed, 10 insertions(+), 1 deletions(-) diff --git a/kernel/exit.c b/kernel/exit.c index 912b1fa..41ac4cf 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -299,6 +299,10 @@ kill_orphaned_pgrp(struct task_struct *tsk, struct task_struct *parent) struct pid *pgrp = task_pgrp(tsk); struct task_struct *ignored_task = tsk; + /* restarting zombie doesn't trigger signals */ + if (tsk->flags & PF_RESTARTING) + return; + if (!parent) /* exit: our father is in a different pgrp than * we are and we were the only connection outside. @@ -739,7 +743,8 @@ static struct task_struct *find_new_reaper(struct task_struct *father) static void reparent_thread(struct task_struct *father, struct task_struct *p, struct list_head *dead) { - if (p->pdeath_signal) + /* restarting zombie doesn't trigger signals */ + if (p->pdeath_signal && !(p->flags & PF_RESTARTING)) group_send_sig_info(p->pdeath_signal, SEND_SIG_NOINFO, p); list_move_tail(&p->sibling, &p->real_parent->children); diff --git a/kernel/signal.c b/kernel/signal.c index 64c5dee..ea217b0 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -1413,6 +1413,10 @@ int do_notify_parent(struct task_struct *tsk, int sig) BUG_ON(!task_ptrace(tsk) && (tsk->group_leader != tsk || !thread_group_empty(tsk))); + /* restarting zombie doesn't notify parent */ + if (tsk->flags & PF_RESTARTING) + return ret; + info.si_signo = sig; info.si_errno = 0; /* -- 1.6.0.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/