projects
/
powerpc.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
[POWERPC] Enable PURR sysfs entry correctly
[powerpc.git]
/
kernel
/
exit.c
diff --git
a/kernel/exit.c
b/kernel/exit.c
index
e06d0c1
..
dba194a
100644
(file)
--- a/
kernel/exit.c
+++ b/
kernel/exit.c
@@
-4,7
+4,6
@@
* Copyright (C) 1991, 1992 Linus Torvalds
*/
* Copyright (C) 1991, 1992 Linus Torvalds
*/
-#include <linux/config.h>
#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
@@
-26,6
+25,8
@@
#include <linux/mount.h>
#include <linux/proc_fs.h>
#include <linux/mempolicy.h>
#include <linux/mount.h>
#include <linux/proc_fs.h>
#include <linux/mempolicy.h>
+#include <linux/taskstats_kern.h>
+#include <linux/delayacct.h>
#include <linux/cpuset.h>
#include <linux/syscalls.h>
#include <linux/signal.h>
#include <linux/cpuset.h>
#include <linux/syscalls.h>
#include <linux/signal.h>
@@
-36,6
+37,7
@@
#include <linux/compat.h>
#include <linux/pipe_fs_i.h>
#include <linux/audit.h> /* for audit_free() */
#include <linux/compat.h>
#include <linux/pipe_fs_i.h>
#include <linux/audit.h> /* for audit_free() */
+#include <linux/resource.h>
#include <asm/uaccess.h>
#include <asm/unistd.h>
#include <asm/uaccess.h>
#include <asm/unistd.h>
@@
-45,8
+47,6
@@
extern void sem_exit (void);
extern struct task_struct *child_reaper;
extern void sem_exit (void);
extern struct task_struct *child_reaper;
-int getrusage(struct task_struct *, int, struct rusage __user *);
-
static void exit_mm(struct task_struct * tsk);
static void __unhash_process(struct task_struct *p)
static void exit_mm(struct task_struct * tsk);
static void __unhash_process(struct task_struct *p)
@@
-136,14
+136,10
@@
static void delayed_put_task_struct(struct rcu_head *rhp)
void release_task(struct task_struct * p)
{
void release_task(struct task_struct * p)
{
+ struct task_struct *leader;
int zap_leader;
int zap_leader;
- task_t *leader;
- struct dentry *proc_dentry;
-
repeat:
atomic_dec(&p->user->processes);
repeat:
atomic_dec(&p->user->processes);
- spin_lock(&p->proc_lock);
- proc_dentry = proc_pid_unhash(p);
write_lock_irq(&tasklist_lock);
ptrace_unlink(p);
BUG_ON(!list_empty(&p->ptrace_list) || !list_empty(&p->ptrace_children));
write_lock_irq(&tasklist_lock);
ptrace_unlink(p);
BUG_ON(!list_empty(&p->ptrace_list) || !list_empty(&p->ptrace_children));
@@
-172,8
+168,7
@@
repeat:
sched_exit(p);
write_unlock_irq(&tasklist_lock);
sched_exit(p);
write_unlock_irq(&tasklist_lock);
- spin_unlock(&p->proc_lock);
- proc_pid_flush(proc_dentry);
+ proc_flush_task(p);
release_thread(p);
call_rcu(&p->rcu, delayed_put_task_struct);
release_thread(p);
call_rcu(&p->rcu, delayed_put_task_struct);
@@
-216,7
+211,7
@@
out:
*
* "I ask you, have you ever known what it is to be an orphan?"
*/
*
* "I ask you, have you ever known what it is to be an orphan?"
*/
-static int will_become_orphaned_pgrp(int pgrp,
task_
t *ignored_task)
+static int will_become_orphaned_pgrp(int pgrp,
struct task_struc
t *ignored_task)
{
struct task_struct *p;
int ret = 1;
{
struct task_struct *p;
int ret = 1;
@@
-579,7
+574,7
@@
static void exit_mm(struct task_struct * tsk)
down_read(&mm->mmap_sem);
}
atomic_inc(&mm->mm_count);
down_read(&mm->mmap_sem);
}
atomic_inc(&mm->mm_count);
-
if (mm != tsk->active_mm) BUG(
);
+
BUG_ON(mm != tsk->active_mm
);
/* more a memory barrier than a real lock */
task_lock(tsk);
tsk->mm = NULL;
/* more a memory barrier than a real lock */
task_lock(tsk);
tsk->mm = NULL;
@@
-589,7
+584,8
@@
static void exit_mm(struct task_struct * tsk)
mmput(mm);
}
mmput(mm);
}
-static inline void choose_new_parent(task_t *p, task_t *reaper)
+static inline void
+choose_new_parent(struct task_struct *p, struct task_struct *reaper)
{
/*
* Make sure we're not reparenting to ourselves and that
{
/*
* Make sure we're not reparenting to ourselves and that
@@
-599,7
+595,8
@@
static inline void choose_new_parent(task_t *p, task_t *reaper)
p->real_parent = reaper;
}
p->real_parent = reaper;
}
-static void reparent_thread(task_t *p, task_t *father, int traced)
+static void
+reparent_thread(struct task_struct *p, struct task_struct *father, int traced)
{
/* We don't want people slaying init. */
if (p->exit_signal != -1)
{
/* We don't want people slaying init. */
if (p->exit_signal != -1)
@@
-663,8
+660,8
@@
static void reparent_thread(task_t *p, task_t *father, int traced)
* group, and if no such member exists, give it to
* the global child reaper process (ie "init")
*/
* group, and if no such member exists, give it to
* the global child reaper process (ie "init")
*/
-static void
forget_original_parent(struct task_struct * father,
-
struct list_head *to_release)
+static void
+
forget_original_parent(struct task_struct *father,
struct list_head *to_release)
{
struct task_struct *p, *reaper = father;
struct list_head *_p, *_n;
{
struct task_struct *p, *reaper = father;
struct list_head *_p, *_n;
@@
-687,7
+684,7
@@
static void forget_original_parent(struct task_struct * father,
*/
list_for_each_safe(_p, _n, &father->children) {
int ptrace;
*/
list_for_each_safe(_p, _n, &father->children) {
int ptrace;
- p = list_entry(_p,
struct task_struct,
sibling);
+ p = list_entry(_p,
struct task_struct,
sibling);
ptrace = p->ptrace;
ptrace = p->ptrace;
@@
-716,7
+713,7
@@
static void forget_original_parent(struct task_struct * father,
list_add(&p->ptrace_list, to_release);
}
list_for_each_safe(_p, _n, &father->ptrace_children) {
list_add(&p->ptrace_list, to_release);
}
list_for_each_safe(_p, _n, &father->ptrace_children) {
- p = list_entry(_p,
struct task_struct,
ptrace_list);
+ p = list_entry(_p,
struct task_struct,
ptrace_list);
choose_new_parent(p, reaper);
reparent_thread(p, father, 1);
}
choose_new_parent(p, reaper);
reparent_thread(p, father, 1);
}
@@
-836,7
+833,7
@@
static void exit_notify(struct task_struct *tsk)
list_for_each_safe(_p, _n, &ptrace_dead) {
list_del_init(_p);
list_for_each_safe(_p, _n, &ptrace_dead) {
list_del_init(_p);
- t = list_entry(_p,
struct task_struct,
ptrace_list);
+ t = list_entry(_p,
struct task_struct,
ptrace_list);
release_task(t);
}
release_task(t);
}
@@
-848,7
+845,9
@@
static void exit_notify(struct task_struct *tsk)
fastcall NORET_TYPE void do_exit(long code)
{
struct task_struct *tsk = current;
fastcall NORET_TYPE void do_exit(long code)
{
struct task_struct *tsk = current;
+ struct taskstats *tidstats;
int group_dead;
int group_dead;
+ unsigned int mycpu;
profile_task_exit(tsk);
profile_task_exit(tsk);
@@
-886,6
+885,8
@@
fastcall NORET_TYPE void do_exit(long code)
current->comm, current->pid,
preempt_count());
current->comm, current->pid,
preempt_count());
+ taskstats_exit_alloc(&tidstats, &mycpu);
+
acct_update_integrals(tsk);
if (tsk->mm) {
update_hiwater_rss(tsk->mm);
acct_update_integrals(tsk);
if (tsk->mm) {
update_hiwater_rss(tsk->mm);
@@
-895,18
+896,24
@@
fastcall NORET_TYPE void do_exit(long code)
if (group_dead) {
hrtimer_cancel(&tsk->signal->real_timer);
exit_itimers(tsk->signal);
if (group_dead) {
hrtimer_cancel(&tsk->signal->real_timer);
exit_itimers(tsk->signal);
- acct_process(code);
}
}
+ acct_collect(code, group_dead);
if (unlikely(tsk->robust_list))
exit_robust_list(tsk);
if (unlikely(tsk->robust_list))
exit_robust_list(tsk);
-#if
def CONFIG_COMPAT
+#if
defined(CONFIG_FUTEX) && defined(CONFIG_COMPAT)
if (unlikely(tsk->compat_robust_list))
compat_exit_robust_list(tsk);
#endif
if (unlikely(tsk->audit_context))
audit_free(tsk);
if (unlikely(tsk->compat_robust_list))
compat_exit_robust_list(tsk);
#endif
if (unlikely(tsk->audit_context))
audit_free(tsk);
+ taskstats_exit_send(tsk, tidstats, group_dead, mycpu);
+ taskstats_exit_free(tidstats);
+ delayacct_tsk_exit(tsk);
+
exit_mm(tsk);
exit_mm(tsk);
+ if (group_dead)
+ acct_process();
exit_sem(tsk);
__exit_files(tsk);
__exit_fs(tsk);
exit_sem(tsk);
__exit_files(tsk);
__exit_fs(tsk);
@@
-930,9
+937,17
@@
fastcall NORET_TYPE void do_exit(long code)
tsk->mempolicy = NULL;
#endif
/*
tsk->mempolicy = NULL;
#endif
/*
- * If DEBUG_MUTEXES is on, make sure we are holding no locks:
+ * This must happen late, after the PID is not
+ * hashed anymore:
*/
*/
- mutex_debug_check_no_locks_held(tsk);
+ if (unlikely(!list_empty(&tsk->pi_state_list)))
+ exit_pi_state_list(tsk);
+ if (unlikely(current->pi_state_cache))
+ kfree(current->pi_state_cache);
+ /*
+ * Make sure we are holding no locks:
+ */
+ debug_check_no_locks_held(tsk);
if (tsk->io_context)
exit_io_context();
if (tsk->io_context)
exit_io_context();
@@
-1007,7
+1022,7
@@
asmlinkage void sys_exit_group(int error_code)
do_group_exit((error_code & 0xff) << 8);
}
do_group_exit((error_code & 0xff) << 8);
}
-static int eligible_child(pid_t pid, int options,
task_
t *p)
+static int eligible_child(pid_t pid, int options,
struct task_struc
t *p)
{
if (pid > 0) {
if (p->pid != pid)
{
if (pid > 0) {
if (p->pid != pid)
@@
-1048,12
+1063,13
@@
static int eligible_child(pid_t pid, int options, task_t *p)
return 1;
}
return 1;
}
-static int wait_noreap_copyout(
task_
t *p, pid_t pid, uid_t uid,
+static int wait_noreap_copyout(
struct task_struc
t *p, pid_t pid, uid_t uid,
int why, int status,
struct siginfo __user *infop,
struct rusage __user *rusagep)
{
int retval = rusagep ? getrusage(p, RUSAGE_BOTH, rusagep) : 0;
int why, int status,
struct siginfo __user *infop,
struct rusage __user *rusagep)
{
int retval = rusagep ? getrusage(p, RUSAGE_BOTH, rusagep) : 0;
+
put_task_struct(p);
if (!retval)
retval = put_user(SIGCHLD, &infop->si_signo);
put_task_struct(p);
if (!retval)
retval = put_user(SIGCHLD, &infop->si_signo);
@@
-1078,7
+1094,7
@@
static int wait_noreap_copyout(task_t *p, pid_t pid, uid_t uid,
* the lock and this task is uninteresting. If we return nonzero, we have
* released the lock and the system call should return.
*/
* the lock and this task is uninteresting. If we return nonzero, we have
* released the lock and the system call should return.
*/
-static int wait_task_zombie(
task_
t *p, int noreap,
+static int wait_task_zombie(
struct task_struc
t *p, int noreap,
struct siginfo __user *infop,
int __user *stat_addr, struct rusage __user *ru)
{
struct siginfo __user *infop,
int __user *stat_addr, struct rusage __user *ru)
{
@@
-1240,8
+1256,8
@@
static int wait_task_zombie(task_t *p, int noreap,
* the lock and this task is uninteresting. If we return nonzero, we have
* released the lock and the system call should return.
*/
* the lock and this task is uninteresting. If we return nonzero, we have
* released the lock and the system call should return.
*/
-static int wait_task_stopped(
task_t *p, int delayed_group_leader, int noreap
,
- struct siginfo __user *infop,
+static int wait_task_stopped(
struct task_struct *p, int delayed_group_leader
,
+
int noreap,
struct siginfo __user *infop,
int __user *stat_addr, struct rusage __user *ru)
{
int retval, exit_code;
int __user *stat_addr, struct rusage __user *ru)
{
int retval, exit_code;
@@
-1355,7
+1371,7
@@
bail_ref:
* the lock and this task is uninteresting. If we return nonzero, we have
* released the lock and the system call should return.
*/
* the lock and this task is uninteresting. If we return nonzero, we have
* released the lock and the system call should return.
*/
-static int wait_task_continued(
task_
t *p, int noreap,
+static int wait_task_continued(
struct task_struc
t *p, int noreap,
struct siginfo __user *infop,
int __user *stat_addr, struct rusage __user *ru)
{
struct siginfo __user *infop,
int __user *stat_addr, struct rusage __user *ru)
{
@@
-1441,7
+1457,7
@@
repeat:
int ret;
list_for_each(_p,&tsk->children) {
int ret;
list_for_each(_p,&tsk->children) {
- p = list_entry(_p,
struct task_struct,
sibling);
+ p = list_entry(_p,
struct task_struct,
sibling);
ret = eligible_child(pid, options, p);
if (!ret)
ret = eligible_child(pid, options, p);
if (!ret)
@@
-1530,8
+1546,7
@@
check_continued:
if (options & __WNOTHREAD)
break;
tsk = next_thread(tsk);
if (options & __WNOTHREAD)
break;
tsk = next_thread(tsk);
- if (tsk->signal != current->signal)
- BUG();
+ BUG_ON(tsk->signal != current->signal);
} while (tsk != current);
read_unlock(&tasklist_lock);
} while (tsk != current);
read_unlock(&tasklist_lock);