Skip to contentSkip to conversation

thread groups bug?

DISCUSSION David Howells 3 participants 3 messages Mar 1, 2002 1 message not in the archive

Subsystems (2)
lore
Share & tools
lore

A message that is not in the archive (sent off-list or not yet received): [email protected]

#1 lore raw

Hi Linus,

I've attached a patch to kill all subsidiary threads in a thread group when the main thread exits. I've made it against 2.5.6-pre1 since -pre2 fails to compile in the IDE code somewhere.

I've tested it, and it appears to work.

Note that it sends the subsidiary threads SIGKILL with SI_DETHREAD.

Note also that subsidiary threads doing an execve() just leave the thread group (rather than forcing the master thread to do an execve() which would be more POSIX like).

David

fs/exec.c +40 -13
diff -uNr linux-2.5.6-pre1/fs/exec.c linux-execve-256p1/fs/exec.c
@@ -513,23 +513,49 @@
 
 /*
  * An execve() will automatically "de-thread" the process.
- * Note: we don't have to hold the tasklist_lock to test
- * whether we migth need to do this. If we're not part of
- * a thread group, there is no way we can become one
- * dynamically. And if we are, we only need to protect the
- * unlink - even if we race with the last other thread exit,
- * at worst the list_del_init() might end up being a no-op.
+ * - if a master thread (PID==TGID) is doing this, then all subsidiary threads
+ *   will be killed (otherwise there will end up being two independent thread
+ *   groups with the same TGID).
+ * - if a subsidary thread is doing this, then it just leaves the thread group
  */
-static inline void de_thread(struct task_struct *tsk)
+static void de_thread(struct task_struct *tsk)
 {
-	if (!list_empty(&tsk->thread_group)) {
-		write_lock_irq(&tasklist_lock);
+	struct task_struct *sub;
+	struct list_head *head, *ptr;
+	struct siginfo info;
+	int pause;
+
+	write_lock_irq(&tasklist_lock);
+
+	if (tsk->tgid != tsk->pid) {
+		/* subsidiary thread - just escapes the group */
+		list_del_init(&tsk->thread_group);
+		tsk->tgid = tsk->pid;
+		pause = 0;
+	}
+	else {
+		/* master thread - kill all subsidiary threads */
+		info.si_signo = SIGKILL;
+		info.si_errno = 0;
+		info.si_code = SI_DETHREAD;
+		info.si_pid = current->pid;
+		info.si_uid = current->uid;
+
+		head = tsk->thread_group.next;
 		list_del_init(&tsk->thread_group);
-		write_unlock_irq(&tasklist_lock);
+
+		list_for_each(ptr,head) {
+			sub = list_entry(ptr,struct task_struct,thread_group);
+			send_sig_info(SIGKILL,&info,sub);
+		}
+
+		pause = 1;
 	}
 
-	/* Minor oddity: this might stay the same. */
-	tsk->tgid = tsk->pid;
+	write_unlock_irq(&tasklist_lock);
+
+	/* give the subsidiary threads a chance to clean themselves up */
+	if (pause) yield();
 }
 
 int flush_old_exec(struct linux_binprm * bprm)
@@ -570,7 +596,8 @@
 
 	flush_thread();
 
-	de_thread(current);
+	if (!list_empty(&current->thread_group))
+		de_thread(current);
 
 	if (bprm->e_uid != current->euid || bprm->e_gid != current->egid || 
 	    permission(bprm->file->f_dentry->d_inode,MAY_READ))
include/asm-i386/siginfo.h +1 -0
diff -uNr linux-2.5.6-pre1/include/asm-i386/siginfo.h linux-execve-256p1/include/asm-i386/siginfo.h
@@ -108,6 +108,7 @@
 #define SI_ASYNCIO	-4		/* sent by AIO completion */
 #define SI_SIGIO	-5		/* sent by queued SIGIO */
 #define SI_TKILL	-6		/* sent by tkill system call */
+#define SI_DETHREAD	-7		/* sent by execve() killing subsidiary threads */
 
 #define SI_FROMUSER(siptr)	((siptr)->si_code <= 0)
 #define SI_FROMKERNEL(siptr)	((siptr)->si_code > 0)
#2 lore raw
Quoted 5 lines · David Howells

Hi Linus,

I've attached a patch to kill all subsidiary threads in a thread group when the main thread exits. I've made it against 2.5.6-pre1 since -pre2 fails to compile in the IDE code somewhere.

Just please enable support for IDE chipset tuning and it should at least compile.

#3 lore raw
In reply to David Howells

--On Friday, March 01, 2002 16:38:11 +0000 David Howells

Quoted 3 lines · <[email protected]> wrote:

I've attached a patch to kill all subsidiary threads in a thread group when the main thread exits. I've made it against 2.5.6-pre1 since -pre2 fails to compile in the IDE code somewhere.

You beat me to it. Nice work.

Dave McCracken

======================================================================
Dave McCracken IBM Linux Base Kernel Team 1-512-838-3059
[email protected] T/L 678-3059