diff options
| author | Linus Torvalds <torvalds@home.transmeta.com> | 2003-02-20 04:33:56 -0800 |
|---|---|---|
| committer | Linus Torvalds <torvalds@home.transmeta.com> | 2003-02-20 04:33:56 -0800 |
| commit | e58d8e309fb22889a11a257cd8d01b04d0fc8373 (patch) | |
| tree | ce97fd0252c049bb08e79087765efb11d433e51c /kernel | |
| parent | 91e2be4638503d6a3d08cc2cc9e6a9eac9b37df9 (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.c | 7 | ||||
| -rw-r--r-- | kernel/sched.c | 4 |
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(); |
