All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] notify_parent cleanup
@ 2004-08-18  0:40 Roland McGrath
  2004-08-18  6:44 ` Andrew Morton
  2004-08-19  4:26 ` [PATCH] notify_parent cleanup OGAWA Hirofumi
  0 siblings, 2 replies; 18+ messages in thread
From: Roland McGrath @ 2004-08-18  0:40 UTC (permalink / raw)
  To: Andrew Morton, Linus Torvalds; +Cc: Linux Kernel Mailing List

All extant uses of `notify_parent' are for ptrace stops, unless it is used
by external modules that I have not seen.  This patch tightens up some of
the signal code by making notify_parent only work for the stopped case.
That means that do_notify_parent is exclusively used for the dead case and
doesn't need to check for the stopped case.  The only outward effect of
this is to make ptrace stops (i.e. notify_parent calls) obey the
SA_NOCLDSTOP behavior instead of incorrectly checking SA_NOCLDWAIT.  I'm
sure no ptrace user actually sets SA_NOCLDSTOP, so it won't be noticed in
reality at all.  

I don't know why notify_parent is an exported symbol at all.  My
inclination would be to remove it as an exported symbol, and then probably
remove it entirely by cleaning up the callers to use ptrace_notify and
change the ptrace_notify calling convention so that works well.
Also, why is ptrace_notify exported?

This patch is relative to 2.6.8.1 + the waitid patches in -mm1.


Thanks,
Roland

Signed-off-by: Roland McGrath <roland@redhat.com>

--- linux-2.6.8.1-waitid/kernel/signal.c.~1~	2004-08-16 04:24:36.000000000 -0700
+++ linux-2.6.8.1-waitid/kernel/signal.c	2004-08-17 17:19:07.012301380 -0700
@@ -1441,19 +1441,22 @@ static void __wake_up_parent(struct task
 }
 
 /*
- * Let a parent know about a status change of a child.
+ * Let a parent know about the death of a child.
+ * For a stopped/continued status change, use do_notify_parent_cldstop instead.
  */
 
 void do_notify_parent(struct task_struct *tsk, int sig)
 {
 	struct siginfo info;
 	unsigned long flags;
-	int why, status;
 	struct sighand_struct *psig;
 
 	if (sig == -1)
 		BUG();
 
+	/* do_notify_parent_cldstop should have been called instead.  */
+	BUG_ON(tsk->state == TASK_STOPPED);
+
 	BUG_ON(tsk->group_leader != tsk && tsk->group_leader->state != TASK_ZOMBIE && !tsk->ptrace);
 	BUG_ON(tsk->group_leader == tsk && !thread_group_empty(tsk) && !tsk->ptrace);
 
@@ -1467,34 +1470,19 @@ void do_notify_parent(struct task_struct
 	info.si_stime = tsk->stime;
 	k_getrusage(tsk, RUSAGE_BOTH, &info.si_rusage);
 
-	status = tsk->exit_code & 0x7f;
-	why = SI_KERNEL;	/* shouldn't happen */
-	switch (tsk->state) {
-	case TASK_STOPPED:
-		/* FIXME -- can we deduce CLD_TRAPPED or CLD_CONTINUED? */
-		if (tsk->ptrace & PT_PTRACED)
-			why = CLD_TRAPPED;
-		else
-			why = CLD_STOPPED;
-		break;
-
-	default:
-		if (tsk->exit_code & 0x80)
-			why = CLD_DUMPED;
-		else if (tsk->exit_code & 0x7f)
-			why = CLD_KILLED;
-		else {
-			why = CLD_EXITED;
-			status = tsk->exit_code >> 8;
-		}
-		break;
+	info.si_status = tsk->exit_code & 0x7f;
+	if (tsk->exit_code & 0x80)
+		info.si_code = CLD_DUMPED;
+	else if (tsk->exit_code & 0x7f)
+		info.si_code = CLD_KILLED;
+	else {
+		info.si_code = CLD_EXITED;
+		info.si_status = tsk->exit_code >> 8;
 	}
-	info.si_code = why;
-	info.si_status = status;
 
 	psig = tsk->parent->sighand;
 	spin_lock_irqsave(&psig->siglock, flags);
-	if (sig == SIGCHLD && tsk->state != TASK_STOPPED &&
+	if (sig == SIGCHLD &&
 	    (psig->action[SIGCHLD-1].sa.sa_handler == SIG_IGN ||
 	     (psig->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDWAIT))) {
 		/*
@@ -1525,19 +1513,20 @@ void do_notify_parent(struct task_struct
 
 /*
  * We need the tasklist lock because it's the only
- * thing that protects out "parent" pointer.
+ * thing that protects our "parent" pointer.
  *
- * exit.c calls "do_notify_parent()" directly, because
- * it already has the tasklist lock.
+ * This entrypoint was once used in other ways, but now it is
+ * only ever called as "notify_parent(current, SIGCHLD)" after
+ * entering TASK_STOPPED state.
  */
 void
 notify_parent(struct task_struct *tsk, int sig)
 {
-	if (sig != -1) {
-		read_lock(&tasklist_lock);
-		do_notify_parent(tsk, sig);
-		read_unlock(&tasklist_lock);
-	}
+	BUG_ON(sig != SIGCHLD);
+	BUG_ON(tsk->state != TASK_STOPPED);
+	read_lock(&tasklist_lock);
+	do_notify_parent_cldstop(tsk, tsk->parent);
+	read_unlock(&tasklist_lock);
 }
 
 static void
@@ -1562,6 +1551,8 @@ do_notify_parent_cldstop(struct task_str
 	if (info.si_status == 0) {
 		info.si_status = SIGCONT;
 		info.si_code = CLD_CONTINUED;
+	} else if (tsk->ptrace & PT_PTRACED) {
+		info.si_code = CLD_TRAPPED;
 	} else {
 		info.si_code = CLD_STOPPED;
 	}

^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2004-08-25 21:50 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-08-18  0:40 [PATCH] notify_parent cleanup Roland McGrath
2004-08-18  6:44 ` Andrew Morton
2004-08-21  1:09   ` [PATCH] notify_parent and ptrace cleanup Roland McGrath
2004-08-21 11:47     ` OGAWA Hirofumi
2004-08-25  2:43       ` Roland McGrath
2004-08-25 17:51         ` OGAWA Hirofumi
2004-08-25 18:08           ` Roland McGrath
2004-08-25 19:48             ` OGAWA Hirofumi
2004-08-25 19:54               ` Linus Torvalds
2004-08-25 20:20                 ` Roland McGrath
2004-08-25 20:53                   ` OGAWA Hirofumi
2004-08-25 21:02                     ` Linus Torvalds
2004-08-25 21:07                       ` Roland McGrath
2004-08-25 21:45                         ` OGAWA Hirofumi
2004-08-19  4:26 ` [PATCH] notify_parent cleanup OGAWA Hirofumi
2004-08-19 20:59   ` Roland McGrath
2004-08-19 22:01     ` OGAWA Hirofumi
2004-08-19 22:04       ` Roland McGrath

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.