diff options
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/cpuset.c | 35 | ||||
-rw-r--r-- | kernel/fork.c | 9 | ||||
-rw-r--r-- | kernel/power/snapshot.c | 4 | ||||
-rw-r--r-- | kernel/ptrace.c | 25 | ||||
-rw-r--r-- | kernel/sysctl.c | 2 |
5 files changed, 54 insertions, 21 deletions
diff --git a/kernel/cpuset.c b/kernel/cpuset.c index ba42b0a76961..12815d3f1a05 100644 --- a/kernel/cpuset.c +++ b/kernel/cpuset.c | |||
@@ -1977,6 +1977,39 @@ void cpuset_fork(struct task_struct *child) | |||
1977 | * We don't need to task_lock() this reference to tsk->cpuset, | 1977 | * We don't need to task_lock() this reference to tsk->cpuset, |
1978 | * because tsk is already marked PF_EXITING, so attach_task() won't | 1978 | * because tsk is already marked PF_EXITING, so attach_task() won't |
1979 | * mess with it, or task is a failed fork, never visible to attach_task. | 1979 | * mess with it, or task is a failed fork, never visible to attach_task. |
1980 | * | ||
1981 | * Hack: | ||
1982 | * | ||
1983 | * Set the exiting tasks cpuset to the root cpuset (top_cpuset). | ||
1984 | * | ||
1985 | * Don't leave a task unable to allocate memory, as that is an | ||
1986 | * accident waiting to happen should someone add a callout in | ||
1987 | * do_exit() after the cpuset_exit() call that might allocate. | ||
1988 | * If a task tries to allocate memory with an invalid cpuset, | ||
1989 | * it will oops in cpuset_update_task_memory_state(). | ||
1990 | * | ||
1991 | * We call cpuset_exit() while the task is still competent to | ||
1992 | * handle notify_on_release(), then leave the task attached to | ||
1993 | * the root cpuset (top_cpuset) for the remainder of its exit. | ||
1994 | * | ||
1995 | * To do this properly, we would increment the reference count on | ||
1996 | * top_cpuset, and near the very end of the kernel/exit.c do_exit() | ||
1997 | * code we would add a second cpuset function call, to drop that | ||
1998 | * reference. This would just create an unnecessary hot spot on | ||
1999 | * the top_cpuset reference count, to no avail. | ||
2000 | * | ||
2001 | * Normally, holding a reference to a cpuset without bumping its | ||
2002 | * count is unsafe. The cpuset could go away, or someone could | ||
2003 | * attach us to a different cpuset, decrementing the count on | ||
2004 | * the first cpuset that we never incremented. But in this case, | ||
2005 | * top_cpuset isn't going away, and either task has PF_EXITING set, | ||
2006 | * which wards off any attach_task() attempts, or task is a failed | ||
2007 | * fork, never visible to attach_task. | ||
2008 | * | ||
2009 | * Another way to do this would be to set the cpuset pointer | ||
2010 | * to NULL here, and check in cpuset_update_task_memory_state() | ||
2011 | * for a NULL pointer. This hack avoids that NULL check, for no | ||
2012 | * cost (other than this way too long comment ;). | ||
1980 | **/ | 2013 | **/ |
1981 | 2014 | ||
1982 | void cpuset_exit(struct task_struct *tsk) | 2015 | void cpuset_exit(struct task_struct *tsk) |
@@ -1984,7 +2017,7 @@ void cpuset_exit(struct task_struct *tsk) | |||
1984 | struct cpuset *cs; | 2017 | struct cpuset *cs; |
1985 | 2018 | ||
1986 | cs = tsk->cpuset; | 2019 | cs = tsk->cpuset; |
1987 | tsk->cpuset = NULL; | 2020 | tsk->cpuset = &top_cpuset; /* Hack - see comment above */ |
1988 | 2021 | ||
1989 | if (notify_on_release(cs)) { | 2022 | if (notify_on_release(cs)) { |
1990 | char *pathbuf = NULL; | 2023 | char *pathbuf = NULL; |
diff --git a/kernel/fork.c b/kernel/fork.c index 8e88b374cee9..fbea12d7a943 100644 --- a/kernel/fork.c +++ b/kernel/fork.c | |||
@@ -1123,8 +1123,8 @@ static task_t *copy_process(unsigned long clone_flags, | |||
1123 | p->real_parent = current; | 1123 | p->real_parent = current; |
1124 | p->parent = p->real_parent; | 1124 | p->parent = p->real_parent; |
1125 | 1125 | ||
1126 | spin_lock(¤t->sighand->siglock); | ||
1126 | if (clone_flags & CLONE_THREAD) { | 1127 | if (clone_flags & CLONE_THREAD) { |
1127 | spin_lock(¤t->sighand->siglock); | ||
1128 | /* | 1128 | /* |
1129 | * Important: if an exit-all has been started then | 1129 | * Important: if an exit-all has been started then |
1130 | * do not create this new thread - the whole thread | 1130 | * do not create this new thread - the whole thread |
@@ -1162,8 +1162,6 @@ static task_t *copy_process(unsigned long clone_flags, | |||
1162 | */ | 1162 | */ |
1163 | p->it_prof_expires = jiffies_to_cputime(1); | 1163 | p->it_prof_expires = jiffies_to_cputime(1); |
1164 | } | 1164 | } |
1165 | |||
1166 | spin_unlock(¤t->sighand->siglock); | ||
1167 | } | 1165 | } |
1168 | 1166 | ||
1169 | /* | 1167 | /* |
@@ -1175,8 +1173,6 @@ static task_t *copy_process(unsigned long clone_flags, | |||
1175 | if (unlikely(p->ptrace & PT_PTRACED)) | 1173 | if (unlikely(p->ptrace & PT_PTRACED)) |
1176 | __ptrace_link(p, current->parent); | 1174 | __ptrace_link(p, current->parent); |
1177 | 1175 | ||
1178 | attach_pid(p, PIDTYPE_PID, p->pid); | ||
1179 | attach_pid(p, PIDTYPE_TGID, p->tgid); | ||
1180 | if (thread_group_leader(p)) { | 1176 | if (thread_group_leader(p)) { |
1181 | p->signal->tty = current->signal->tty; | 1177 | p->signal->tty = current->signal->tty; |
1182 | p->signal->pgrp = process_group(current); | 1178 | p->signal->pgrp = process_group(current); |
@@ -1186,9 +1182,12 @@ static task_t *copy_process(unsigned long clone_flags, | |||
1186 | if (p->pid) | 1182 | if (p->pid) |
1187 | __get_cpu_var(process_counts)++; | 1183 | __get_cpu_var(process_counts)++; |
1188 | } | 1184 | } |
1185 | attach_pid(p, PIDTYPE_TGID, p->tgid); | ||
1186 | attach_pid(p, PIDTYPE_PID, p->pid); | ||
1189 | 1187 | ||
1190 | nr_threads++; | 1188 | nr_threads++; |
1191 | total_forks++; | 1189 | total_forks++; |
1190 | spin_unlock(¤t->sighand->siglock); | ||
1192 | write_unlock_irq(&tasklist_lock); | 1191 | write_unlock_irq(&tasklist_lock); |
1193 | proc_fork_connector(p); | 1192 | proc_fork_connector(p); |
1194 | return p; | 1193 | return p; |
diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c index 41f66365f0d8..8d5a5986d621 100644 --- a/kernel/power/snapshot.c +++ b/kernel/power/snapshot.c | |||
@@ -91,10 +91,8 @@ static int save_highmem_zone(struct zone *zone) | |||
91 | * corrected eventually when the cases giving rise to this | 91 | * corrected eventually when the cases giving rise to this |
92 | * are better understood. | 92 | * are better understood. |
93 | */ | 93 | */ |
94 | if (PageReserved(page)) { | 94 | if (PageReserved(page)) |
95 | printk("highmem reserved page?!\n"); | ||
96 | continue; | 95 | continue; |
97 | } | ||
98 | BUG_ON(PageNosave(page)); | 96 | BUG_ON(PageNosave(page)); |
99 | if (PageNosaveFree(page)) | 97 | if (PageNosaveFree(page)) |
100 | continue; | 98 | continue; |
diff --git a/kernel/ptrace.c b/kernel/ptrace.c index d2cf144d0af5..d95a72c9279d 100644 --- a/kernel/ptrace.c +++ b/kernel/ptrace.c | |||
@@ -72,8 +72,8 @@ void ptrace_untrace(task_t *child) | |||
72 | */ | 72 | */ |
73 | void __ptrace_unlink(task_t *child) | 73 | void __ptrace_unlink(task_t *child) |
74 | { | 74 | { |
75 | if (!child->ptrace) | 75 | BUG_ON(!child->ptrace); |
76 | BUG(); | 76 | |
77 | child->ptrace = 0; | 77 | child->ptrace = 0; |
78 | if (!list_empty(&child->ptrace_list)) { | 78 | if (!list_empty(&child->ptrace_list)) { |
79 | list_del_init(&child->ptrace_list); | 79 | list_del_init(&child->ptrace_list); |
@@ -184,22 +184,27 @@ bad: | |||
184 | return retval; | 184 | return retval; |
185 | } | 185 | } |
186 | 186 | ||
187 | void __ptrace_detach(struct task_struct *child, unsigned int data) | ||
188 | { | ||
189 | child->exit_code = data; | ||
190 | /* .. re-parent .. */ | ||
191 | __ptrace_unlink(child); | ||
192 | /* .. and wake it up. */ | ||
193 | if (child->exit_state != EXIT_ZOMBIE) | ||
194 | wake_up_process(child); | ||
195 | } | ||
196 | |||
187 | int ptrace_detach(struct task_struct *child, unsigned int data) | 197 | int ptrace_detach(struct task_struct *child, unsigned int data) |
188 | { | 198 | { |
189 | if (!valid_signal(data)) | 199 | if (!valid_signal(data)) |
190 | return -EIO; | 200 | return -EIO; |
191 | 201 | ||
192 | /* Architecture-specific hardware disable .. */ | 202 | /* Architecture-specific hardware disable .. */ |
193 | ptrace_disable(child); | 203 | ptrace_disable(child); |
194 | 204 | ||
195 | /* .. re-parent .. */ | ||
196 | child->exit_code = data; | ||
197 | |||
198 | write_lock_irq(&tasklist_lock); | 205 | write_lock_irq(&tasklist_lock); |
199 | __ptrace_unlink(child); | 206 | if (child->ptrace) |
200 | /* .. and wake it up. */ | 207 | __ptrace_detach(child, data); |
201 | if (child->exit_state != EXIT_ZOMBIE) | ||
202 | wake_up_process(child); | ||
203 | write_unlock_irq(&tasklist_lock); | 208 | write_unlock_irq(&tasklist_lock); |
204 | 209 | ||
205 | return 0; | 210 | return 0; |
diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 71dd6f62efec..7654d55c47f5 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c | |||
@@ -126,8 +126,6 @@ extern int sysctl_hz_timer; | |||
126 | extern int acct_parm[]; | 126 | extern int acct_parm[]; |
127 | #endif | 127 | #endif |
128 | 128 | ||
129 | int randomize_va_space = 1; | ||
130 | |||
131 | static int parse_table(int __user *, int, void __user *, size_t __user *, void __user *, size_t, | 129 | static int parse_table(int __user *, int, void __user *, size_t __user *, void __user *, size_t, |
132 | ctl_table *, void **); | 130 | ctl_table *, void **); |
133 | static int proc_doutsstring(ctl_table *table, int write, struct file *filp, | 131 | static int proc_doutsstring(ctl_table *table, int write, struct file *filp, |