aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/exit.c
diff options
context:
space:
mode:
authorPierre Ossman <drzeus@drzeus.cx>2008-12-31 13:56:05 -0500
committerPierre Ossman <drzeus@drzeus.cx>2008-12-31 13:56:05 -0500
commit418f19ea17a99421b22a64e101e14b6a16bed66d (patch)
tree7c21fcc368c63f1f9907deac6d16b30bd371792d /kernel/exit.c
parent98444d3dd975653a4a970ecc0dfc30918da92f60 (diff)
parentf6e10b865c3ea56bdaa8c6ecfee313b997900dbb (diff)
Merge branch 'master' of ../mmc
Diffstat (limited to 'kernel/exit.c')
-rw-r--r--kernel/exit.c32
1 files changed, 19 insertions, 13 deletions
diff --git a/kernel/exit.c b/kernel/exit.c
index 2d8be7ebb0f7..c9e5a1c14e08 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -46,12 +46,18 @@
46#include <linux/blkdev.h> 46#include <linux/blkdev.h>
47#include <linux/task_io_accounting_ops.h> 47#include <linux/task_io_accounting_ops.h>
48#include <linux/tracehook.h> 48#include <linux/tracehook.h>
49#include <linux/init_task.h>
49#include <trace/sched.h> 50#include <trace/sched.h>
50 51
51#include <asm/uaccess.h> 52#include <asm/uaccess.h>
52#include <asm/unistd.h> 53#include <asm/unistd.h>
53#include <asm/pgtable.h> 54#include <asm/pgtable.h>
54#include <asm/mmu_context.h> 55#include <asm/mmu_context.h>
56#include "cred-internals.h"
57
58DEFINE_TRACE(sched_process_free);
59DEFINE_TRACE(sched_process_exit);
60DEFINE_TRACE(sched_process_wait);
55 61
56static void exit_mm(struct task_struct * tsk); 62static void exit_mm(struct task_struct * tsk);
57 63
@@ -164,7 +170,10 @@ void release_task(struct task_struct * p)
164 int zap_leader; 170 int zap_leader;
165repeat: 171repeat:
166 tracehook_prepare_release_task(p); 172 tracehook_prepare_release_task(p);
167 atomic_dec(&p->user->processes); 173 /* don't need to get the RCU readlock here - the process is dead and
174 * can't be modifying its own credentials */
175 atomic_dec(&__task_cred(p)->user->processes);
176
168 proc_flush_task(p); 177 proc_flush_task(p);
169 write_lock_irq(&tasklist_lock); 178 write_lock_irq(&tasklist_lock);
170 tracehook_finish_release_task(p); 179 tracehook_finish_release_task(p);
@@ -339,12 +348,12 @@ static void reparent_to_kthreadd(void)
339 /* cpus_allowed? */ 348 /* cpus_allowed? */
340 /* rt_priority? */ 349 /* rt_priority? */
341 /* signals? */ 350 /* signals? */
342 security_task_reparent_to_init(current);
343 memcpy(current->signal->rlim, init_task.signal->rlim, 351 memcpy(current->signal->rlim, init_task.signal->rlim,
344 sizeof(current->signal->rlim)); 352 sizeof(current->signal->rlim));
345 atomic_inc(&(INIT_USER->__count)); 353
354 atomic_inc(&init_cred.usage);
355 commit_creds(&init_cred);
346 write_unlock_irq(&tasklist_lock); 356 write_unlock_irq(&tasklist_lock);
347 switch_uid(INIT_USER);
348} 357}
349 358
350void __set_special_pids(struct pid *pid) 359void __set_special_pids(struct pid *pid)
@@ -1028,8 +1037,6 @@ NORET_TYPE void do_exit(long code)
1028 * task into the wait for ever nirwana as well. 1037 * task into the wait for ever nirwana as well.
1029 */ 1038 */
1030 tsk->flags |= PF_EXITPIDONE; 1039 tsk->flags |= PF_EXITPIDONE;
1031 if (tsk->io_context)
1032 exit_io_context();
1033 set_current_state(TASK_UNINTERRUPTIBLE); 1040 set_current_state(TASK_UNINTERRUPTIBLE);
1034 schedule(); 1041 schedule();
1035 } 1042 }
@@ -1078,7 +1085,6 @@ NORET_TYPE void do_exit(long code)
1078 check_stack_usage(); 1085 check_stack_usage();
1079 exit_thread(); 1086 exit_thread();
1080 cgroup_exit(tsk, 1); 1087 cgroup_exit(tsk, 1);
1081 exit_keys(tsk);
1082 1088
1083 if (group_dead && tsk->signal->leader) 1089 if (group_dead && tsk->signal->leader)
1084 disassociate_ctty(1); 1090 disassociate_ctty(1);
@@ -1123,7 +1129,6 @@ NORET_TYPE void do_exit(long code)
1123 preempt_disable(); 1129 preempt_disable();
1124 /* causes final put_task_struct in finish_task_switch(). */ 1130 /* causes final put_task_struct in finish_task_switch(). */
1125 tsk->state = TASK_DEAD; 1131 tsk->state = TASK_DEAD;
1126
1127 schedule(); 1132 schedule();
1128 BUG(); 1133 BUG();
1129 /* Avoid "noreturn function does return". */ 1134 /* Avoid "noreturn function does return". */
@@ -1263,12 +1268,12 @@ static int wait_task_zombie(struct task_struct *p, int options,
1263 unsigned long state; 1268 unsigned long state;
1264 int retval, status, traced; 1269 int retval, status, traced;
1265 pid_t pid = task_pid_vnr(p); 1270 pid_t pid = task_pid_vnr(p);
1271 uid_t uid = __task_cred(p)->uid;
1266 1272
1267 if (!likely(options & WEXITED)) 1273 if (!likely(options & WEXITED))
1268 return 0; 1274 return 0;
1269 1275
1270 if (unlikely(options & WNOWAIT)) { 1276 if (unlikely(options & WNOWAIT)) {
1271 uid_t uid = p->uid;
1272 int exit_code = p->exit_code; 1277 int exit_code = p->exit_code;
1273 int why, status; 1278 int why, status;
1274 1279
@@ -1321,10 +1326,10 @@ static int wait_task_zombie(struct task_struct *p, int options,
1321 * group, which consolidates times for all threads in the 1326 * group, which consolidates times for all threads in the
1322 * group including the group leader. 1327 * group including the group leader.
1323 */ 1328 */
1329 thread_group_cputime(p, &cputime);
1324 spin_lock_irq(&p->parent->sighand->siglock); 1330 spin_lock_irq(&p->parent->sighand->siglock);
1325 psig = p->parent->signal; 1331 psig = p->parent->signal;
1326 sig = p->signal; 1332 sig = p->signal;
1327 thread_group_cputime(p, &cputime);
1328 psig->cutime = 1333 psig->cutime =
1329 cputime_add(psig->cutime, 1334 cputime_add(psig->cutime,
1330 cputime_add(cputime.utime, 1335 cputime_add(cputime.utime,
@@ -1389,7 +1394,7 @@ static int wait_task_zombie(struct task_struct *p, int options,
1389 if (!retval && infop) 1394 if (!retval && infop)
1390 retval = put_user(pid, &infop->si_pid); 1395 retval = put_user(pid, &infop->si_pid);
1391 if (!retval && infop) 1396 if (!retval && infop)
1392 retval = put_user(p->uid, &infop->si_uid); 1397 retval = put_user(uid, &infop->si_uid);
1393 if (!retval) 1398 if (!retval)
1394 retval = pid; 1399 retval = pid;
1395 1400
@@ -1454,7 +1459,8 @@ static int wait_task_stopped(int ptrace, struct task_struct *p,
1454 if (!unlikely(options & WNOWAIT)) 1459 if (!unlikely(options & WNOWAIT))
1455 p->exit_code = 0; 1460 p->exit_code = 0;
1456 1461
1457 uid = p->uid; 1462 /* don't need the RCU readlock here as we're holding a spinlock */
1463 uid = __task_cred(p)->uid;
1458unlock_sig: 1464unlock_sig:
1459 spin_unlock_irq(&p->sighand->siglock); 1465 spin_unlock_irq(&p->sighand->siglock);
1460 if (!exit_code) 1466 if (!exit_code)
@@ -1528,10 +1534,10 @@ static int wait_task_continued(struct task_struct *p, int options,
1528 } 1534 }
1529 if (!unlikely(options & WNOWAIT)) 1535 if (!unlikely(options & WNOWAIT))
1530 p->signal->flags &= ~SIGNAL_STOP_CONTINUED; 1536 p->signal->flags &= ~SIGNAL_STOP_CONTINUED;
1537 uid = __task_cred(p)->uid;
1531 spin_unlock_irq(&p->sighand->siglock); 1538 spin_unlock_irq(&p->sighand->siglock);
1532 1539
1533 pid = task_pid_vnr(p); 1540 pid = task_pid_vnr(p);
1534 uid = p->uid;
1535 get_task_struct(p); 1541 get_task_struct(p);
1536 read_unlock(&tasklist_lock); 1542 read_unlock(&tasklist_lock);
1537 1543