All of lore.kernel.org
 help / color / mirror / Atom feed
From: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
To: LKML <linux-kernel@vger.kernel.org>
Cc: oleg@tv-sign.ru, mingo@elte.hu, akpm@linux-foundation.org
Subject: [PATCH] fix handling of SIGCHILD from reaped child
Date: Tue, 20 Feb 2007 18:32:20 +0900	[thread overview]
Message-ID: <20070220183220.41b3f1ca.kamezawa.hiroyu@jp.fujitsu.com> (raw)

SUSv3 says
==
if SIGCHLD is blocked, if wait() or waitpid() return because the status of a
child process is available, any pending SIGCHLD signal shall be cleared unless
the status of another child process is available.
==

This patch tries to implement above functionality (clear SIGCHLD from reaped 
process.)
please review...

works well on 2.6.20/ia64/NUMA environment and passed my easy test.

Signed-Off-By: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>

Index: linux-2.6.20-devel/kernel/signal.c
===================================================================
--- linux-2.6.20-devel.orig/kernel/signal.c
+++ linux-2.6.20-devel/kernel/signal.c
@@ -382,7 +382,7 @@ unblock_all_signals(void)
 	spin_unlock_irqrestore(&current->sighand->siglock, flags);
 }
 
-static int collect_signal(int sig, struct sigpending *list, siginfo_t *info)
+static int collect_signal(int sig, struct sigpending *list, siginfo_t *info, pid_t checkpid)
 {
 	struct sigqueue *q, *first = NULL;
 	int still_pending = 0;
@@ -394,13 +394,24 @@ static int collect_signal(int sig, struc
 	 * Collect the siginfo appropriate to this signal.  Check if
 	 * there is another siginfo for the same signal.
 	*/
-	list_for_each_entry(q, &list->list, list) {
-		if (q->info.si_signo == sig) {
-			if (first) {
-				still_pending = 1;
-				break;
+	if (unlikely(checkpid)) {
+		list_for_each_entry(q, &list->list, list) {
+			if (q->info.si_signo == sig) {
+			    if (q->info.si_pid == checkpid)
+					first = q;
+				else
+					still_pending = 1;
+			}
+		}
+	} else {
+		list_for_each_entry(q, &list->list, list) {
+			if (q->info.si_signo == sig) {
+				if (first) {
+					still_pending = 1;
+					break;
+				}
+				first = q;
 			}
-			first = q;
 		}
 	}
 	if (first) {
@@ -415,7 +426,8 @@ static int collect_signal(int sig, struc
 		   a fast-pathed signal or we must have been
 		   out of queue space.  So zero out the info.
 		 */
-		sigdelset(&list->signal, sig);
+		if (!still_pending)
+			sigdelset(&list->signal, sig);
 		info->si_signo = sig;
 		info->si_errno = 0;
 		info->si_code = 0;
@@ -440,7 +452,7 @@ static int __dequeue_signal(struct sigpe
 			}
 		}
 
-		if (!collect_signal(sig, pending, info))
+		if (!collect_signal(sig, pending, info, 0))
 			sig = 0;
 	}
 
@@ -493,6 +505,24 @@ int dequeue_signal(struct task_struct *t
 }
 
 /*
+ * only called by do_wait() when it reaps its child.
+ * This function clears pending SIGCHLD from the reaped child.
+ * rerely does real job...
+ * Becasue we only check SIGCHLD, just checks shared_pending.
+ */
+void clear_stale_sigchild(struct task_struct *tsk, pid_t child_id)
+{
+	siginfo_t info;
+	unsigned long flags;
+	spin_lock_irqsave(&tsk->sighand->siglock, flags);
+	collect_signal(SIGCHLD, &tsk->signal->shared_pending,  &info, child_id);
+	spin_unlock_irqrestore(&tsk->sighand->siglock, flags);
+	return;
+}
+
+
+
+/*
  * Tell a process that it has a new active signal..
  *
  * NOTE! we rely on the previous spin_lock to
Index: linux-2.6.20-devel/kernel/exit.c
===================================================================
--- linux-2.6.20-devel.orig/kernel/exit.c
+++ linux-2.6.20-devel/kernel/exit.c
@@ -1252,8 +1252,12 @@ static int wait_task_zombie(struct task_
 		}
 		write_unlock_irq(&tasklist_lock);
 	}
-	if (p != NULL)
+	if (p != NULL) {
 		release_task(p);
+		/* if we received sigchild from "p" and p is released,
+		   we remove sigchild from it. */
+		clear_stale_sigchild(current, retval);
+	}
 	BUG_ON(!retval);
 	return retval;
 }


             reply	other threads:[~2007-02-20  9:33 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-02-20  9:32 KAMEZAWA Hiroyuki [this message]
2007-02-20 14:22 ` [PATCH] fix handling of SIGCHILD from reaped child Oleg Nesterov
2007-02-20 15:25   ` KAMEZAWA Hiroyuki
2007-02-20 17:20     ` Oleg Nesterov
2007-02-20 23:10       ` Roland McGrath
2007-02-21  0:51         ` KAMEZAWA Hiroyuki
2007-02-21  0:42       ` KAMEZAWA Hiroyuki

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20070220183220.41b3f1ca.kamezawa.hiroyu@jp.fujitsu.com \
    --to=kamezawa.hiroyu@jp.fujitsu.com \
    --cc=akpm@linux-foundation.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@elte.hu \
    --cc=oleg@tv-sign.ru \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.