summaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@home.transmeta.com>2003-02-20 04:33:56 -0800
committerLinus Torvalds <torvalds@home.transmeta.com>2003-02-20 04:33:56 -0800
commite58d8e309fb22889a11a257cd8d01b04d0fc8373 (patch)
treece97fd0252c049bb08e79087765efb11d433e51c /kernel
parent91e2be4638503d6a3d08cc2cc9e6a9eac9b37df9 (diff)
Fix x86 "switch_to()" to properly set the previous task information,
which is needed to keep track of process usage counts correctly and efficiently.
Diffstat (limited to 'kernel')
-rw-r--r--kernel/fork.c7
-rw-r--r--kernel/sched.c4
2 files changed, 9 insertions, 2 deletions
diff --git a/kernel/fork.c b/kernel/fork.c
index 6f137beea865..203fe93429de 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -74,6 +74,9 @@ int nr_processes(void)
void __put_task_struct(struct task_struct *tsk)
{
+ WARN_ON(!(tsk->state & (TASK_DEAD | TASK_ZOMBIE)));
+ WARN_ON(atomic_read(&tsk->usage));
+
if (tsk != current) {
free_thread_info(tsk->thread_info);
kmem_cache_free(task_struct_cachep,tsk);
@@ -217,7 +220,9 @@ static struct task_struct *dup_task_struct(struct task_struct *orig)
*tsk = *orig;
tsk->thread_info = ti;
ti->task = tsk;
- atomic_set(&tsk->usage,1);
+
+ /* One for us, one for whoever does the "release_task()" (usually parent) */
+ atomic_set(&tsk->usage,2);
return tsk;
}
diff --git a/kernel/sched.c b/kernel/sched.c
index fe4139562dca..ad1ac7be565a 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -581,6 +581,8 @@ static inline void finish_task_switch(task_t *prev)
finish_arch_switch(rq, prev);
if (mm)
mmdrop(mm);
+ if (prev->state & (TASK_DEAD | TASK_ZOMBIE))
+ put_task_struct(prev);
}
/**
@@ -1185,7 +1187,7 @@ asmlinkage void schedule(void)
* schedule() atomically, we ignore that path for now.
* Otherwise, whine if we are scheduling when we should not be.
*/
- if (likely(current->state != TASK_ZOMBIE)) {
+ if (likely(!(current->state & (TASK_DEAD | TASK_ZOMBIE)))) {
if (unlikely(in_atomic())) {
printk(KERN_ERR "bad: scheduling while atomic!\n");
dump_stack();