diff options
Diffstat (limited to 'kernel/exit.c')
-rw-r--r-- | kernel/exit.c | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/kernel/exit.c b/kernel/exit.c index ca6a11b73023..e8af8d0c2483 100644 --- a/kernel/exit.c +++ b/kernel/exit.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/mempolicy.h> | 31 | #include <linux/mempolicy.h> |
32 | #include <linux/taskstats_kern.h> | 32 | #include <linux/taskstats_kern.h> |
33 | #include <linux/delayacct.h> | 33 | #include <linux/delayacct.h> |
34 | #include <linux/freezer.h> | ||
34 | #include <linux/cpuset.h> | 35 | #include <linux/cpuset.h> |
35 | #include <linux/syscalls.h> | 36 | #include <linux/syscalls.h> |
36 | #include <linux/signal.h> | 37 | #include <linux/signal.h> |
@@ -387,6 +388,11 @@ void daemonize(const char *name, ...) | |||
387 | * they would be locked into memory. | 388 | * they would be locked into memory. |
388 | */ | 389 | */ |
389 | exit_mm(current); | 390 | exit_mm(current); |
391 | /* | ||
392 | * We don't want to have TIF_FREEZE set if the system-wide hibernation | ||
393 | * or suspend transition begins right now. | ||
394 | */ | ||
395 | current->flags |= PF_NOFREEZE; | ||
390 | 396 | ||
391 | set_special_pids(1, 1); | 397 | set_special_pids(1, 1); |
392 | proc_clear_tty(current); | 398 | proc_clear_tty(current); |
@@ -858,6 +864,34 @@ static void exit_notify(struct task_struct *tsk) | |||
858 | release_task(tsk); | 864 | release_task(tsk); |
859 | } | 865 | } |
860 | 866 | ||
867 | #ifdef CONFIG_DEBUG_STACK_USAGE | ||
868 | static void check_stack_usage(void) | ||
869 | { | ||
870 | static DEFINE_SPINLOCK(low_water_lock); | ||
871 | static int lowest_to_date = THREAD_SIZE; | ||
872 | unsigned long *n = end_of_stack(current); | ||
873 | unsigned long free; | ||
874 | |||
875 | while (*n == 0) | ||
876 | n++; | ||
877 | free = (unsigned long)n - (unsigned long)end_of_stack(current); | ||
878 | |||
879 | if (free >= lowest_to_date) | ||
880 | return; | ||
881 | |||
882 | spin_lock(&low_water_lock); | ||
883 | if (free < lowest_to_date) { | ||
884 | printk(KERN_WARNING "%s used greatest stack depth: %lu bytes " | ||
885 | "left\n", | ||
886 | current->comm, free); | ||
887 | lowest_to_date = free; | ||
888 | } | ||
889 | spin_unlock(&low_water_lock); | ||
890 | } | ||
891 | #else | ||
892 | static inline void check_stack_usage(void) {} | ||
893 | #endif | ||
894 | |||
861 | fastcall NORET_TYPE void do_exit(long code) | 895 | fastcall NORET_TYPE void do_exit(long code) |
862 | { | 896 | { |
863 | struct task_struct *tsk = current; | 897 | struct task_struct *tsk = current; |
@@ -937,6 +971,8 @@ fastcall NORET_TYPE void do_exit(long code) | |||
937 | if (unlikely(tsk->compat_robust_list)) | 971 | if (unlikely(tsk->compat_robust_list)) |
938 | compat_exit_robust_list(tsk); | 972 | compat_exit_robust_list(tsk); |
939 | #endif | 973 | #endif |
974 | if (group_dead) | ||
975 | tty_audit_exit(); | ||
940 | if (unlikely(tsk->audit_context)) | 976 | if (unlikely(tsk->audit_context)) |
941 | audit_free(tsk); | 977 | audit_free(tsk); |
942 | 978 | ||
@@ -949,6 +985,7 @@ fastcall NORET_TYPE void do_exit(long code) | |||
949 | exit_sem(tsk); | 985 | exit_sem(tsk); |
950 | __exit_files(tsk); | 986 | __exit_files(tsk); |
951 | __exit_fs(tsk); | 987 | __exit_fs(tsk); |
988 | check_stack_usage(); | ||
952 | exit_thread(); | 989 | exit_thread(); |
953 | cpuset_exit(tsk); | 990 | cpuset_exit(tsk); |
954 | exit_keys(tsk); | 991 | exit_keys(tsk); |