patch-2.1.23 linux/kernel/exit.c

Next file: linux/kernel/fork.c
Previous file: linux/kernel/exec_domain.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.1.22/linux/kernel/exit.c linux/kernel/exit.c
@@ -6,6 +6,7 @@
 
 #undef DEBUG_PROC_TREE
 
+#include <linux/config.h>
 #include <linux/wait.h>
 #include <linux/errno.h>
 #include <linux/signal.h>
@@ -16,6 +17,9 @@
 #include <linux/tty.h>
 #include <linux/malloc.h>
 #include <linux/interrupt.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/module.h>
 
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
@@ -69,7 +73,7 @@
 			wake_up_process(p);
 	}
 }
-		
+
 
 int send_sig(unsigned long sig,struct task_struct * p,int priv)
 {
@@ -131,7 +135,7 @@
 			current->cmin_flt += p->min_flt + p->cmin_flt;
 			current->cmaj_flt += p->maj_flt + p->cmaj_flt;
 			current->cnswap += p->nswap + p->cnswap;
-			kfree(p);
+			free_task_struct(p);
 			return;
 		}
 	panic("trying to release non-existent task");
@@ -153,14 +157,14 @@
 			return 0;
 	return 1;
 }
-	
+
 /*
  * This routine scans the pid tree and makes sure the rep invariant still
  * holds.  Used for debugging only, since it's very slow....
  *
  * It looks a lot scarier than it really is.... we're doing nothing more
- * than verifying the doubly-linked list found in p_ysptr and p_osptr, 
- * and checking it corresponds with the process tree defined by p_cptr and 
+ * than verifying the doubly-linked list found in p_ysptr and p_osptr,
+ * and checking it corresponds with the process tree defined by p_cptr and
  * p_pptr;
  */
 void audit_ptree(void)
@@ -320,8 +324,11 @@
 {
 	int err, retval = 0, count = 0;
 
-	if (!pid)
-		return(kill_pg(current->pgrp,sig,0));
+	lock_kernel();
+	if (!pid) {
+		err = kill_pg(current->pgrp,sig,0);
+		goto out;
+	}
 	if (pid == -1) {
 		struct task_struct * p;
 		for_each_task(p) {
@@ -331,20 +338,26 @@
 					retval = err;
 			}
 		}
-		return(count ? retval : -ESRCH);
+		err = count ? retval : -ESRCH;
+		goto out;
+	}
+	if (pid < 0) {
+		err = kill_pg(-pid,sig,0);
+		goto out;
 	}
-	if (pid < 0) 
-		return(kill_pg(-pid,sig,0));
 	/* Normal kill */
-	return(kill_proc(pid,sig,0));
+	err = kill_proc(pid,sig,0);
+out:
+	unlock_kernel();
+	return err;
 }
 
 /*
  * Determine if a process group is "orphaned", according to the POSIX
  * definition in 2.2.2.52.  Orphaned process groups are not to be affected
- * by terminal-generated stop signals.  Newly orphaned process groups are 
+ * by terminal-generated stop signals.  Newly orphaned process groups are
  * to receive a SIGHUP and a SIGCONT.
- * 
+ *
  * "I ask you, have you ever known what it is to be an orphan?"
  */
 static int will_become_orphaned_pgrp(int pgrp, struct task_struct * ignored_task)
@@ -352,7 +365,7 @@
 	struct task_struct *p;
 
 	for_each_task(p) {
-		if ((p == ignored_task) || (p->pgrp != pgrp) || 
+		if ((p == ignored_task) || (p->pgrp != pgrp) ||
 		    (p->state == TASK_ZOMBIE) ||
 		    (p->p_pptr->pid == 1))
 			continue;
@@ -495,7 +508,7 @@
 	__exit_mm(tsk);
 }
 
-/* 
+/*
  * Send signals to all our closest relatives so that they know
  * to properly mourn us..
  */
@@ -504,7 +517,7 @@
 	struct task_struct * p;
 
 	forget_original_parent(current);
-	/* 
+	/*
 	 * Check to see if any process groups have become orphaned
 	 * as a result of our exiting, and if they have any stopped
 	 * jobs, send them a SIGHUP and then a SIGCONT.  (POSIX 3.2.2.2)
@@ -522,10 +535,10 @@
 	}
 	/* Let father know we died */
 	notify_parent(current);
-	
+
 	/*
 	 * This loop does two things:
-	 * 
+	 *
   	 * A.  Make init inherit all the child processes
 	 * B.  Check to see if any process groups have become orphaned
 	 *	as a result of our exiting, and if they have any stopped
@@ -546,7 +559,7 @@
 			notify_parent(p);
 		/*
 		 * process group orphan check
-		 * Case ii: Our child is in a different pgrp 
+		 * Case ii: Our child is in a different pgrp
 		 * than we are, and it was the only connection
 		 * outside, so the child pgrp is now orphaned.
 		 */
@@ -575,6 +588,9 @@
 	sem_exit();
 	kerneld_exit();
 	__exit_mm(current);
+#if CONFIG_AP1000
+	exit_msc(current);
+#endif
 	__exit_files(current);
 	__exit_fs(current);
 	__exit_sighand(current);
@@ -585,10 +601,10 @@
 #ifdef DEBUG_PROC_TREE
 	audit_ptree();
 #endif
-	if (current->exec_domain && current->exec_domain->use_count)
-		(*current->exec_domain->use_count)--;
-	if (current->binfmt && current->binfmt->use_count)
-		(*current->binfmt->use_count)--;
+	if (current->exec_domain && current->exec_domain->module)
+		__MOD_DEC_USE_COUNT(current->exec_domain->module);
+	if (current->binfmt && current->binfmt->module)
+		__MOD_DEC_USE_COUNT(current->binfmt->module);
 	schedule();
 /*
  * In order to get rid of the "volatile function does return" message
@@ -608,7 +624,9 @@
 
 asmlinkage int sys_exit(int error_code)
 {
+	lock_kernel();
 	do_exit((error_code&0xff)<<8);
+	unlock_kernel();
 }
 
 asmlinkage int sys_wait4(pid_t pid,unsigned int * stat_addr, int options, struct rusage * ru)
@@ -617,18 +635,20 @@
 	struct wait_queue wait = { current, NULL };
 	struct task_struct *p;
 
+	lock_kernel();
 	if (stat_addr) {
-		flag = verify_area(VERIFY_WRITE, stat_addr, sizeof(*stat_addr));
-		if (flag)
-			return flag;
+		retval = verify_area(VERIFY_WRITE, stat_addr, sizeof(*stat_addr));
+		if (retval)
+			goto out;
 	}
 	if (ru) {
-		flag = verify_area(VERIFY_WRITE, ru, sizeof(*ru));
-		if (flag)
-			return flag;
+		retval = verify_area(VERIFY_WRITE, ru, sizeof(*ru));
+		if (retval)
+			goto out;
 	}
+	retval = -EINVAL;
 	if (options & ~(WNOHANG|WUNTRACED|__WCLONE))
-	    return -EINVAL;
+	    goto out;
 
 	add_wait_queue(&current->wait_chldexit,&wait);
 repeat:
@@ -699,6 +719,8 @@
 	retval = -ECHILD;
 end_wait4:
 	remove_wait_queue(&current->wait_chldexit,&wait);
+out:
+	unlock_kernel();
 	return retval;
 }
 
@@ -710,7 +732,12 @@
  */
 asmlinkage int sys_waitpid(pid_t pid,unsigned int * stat_addr, int options)
 {
-	return sys_wait4(pid, stat_addr, options, NULL);
+	int ret;
+
+	lock_kernel();
+	ret = sys_wait4(pid, stat_addr, options, NULL);
+	unlock_kernel();
+	return ret;
 }
 
 #endif

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov