diff options
| author | Ingo Molnar <mingo@elte.hu> | 2002-07-23 22:17:36 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@penguin.transmeta.com> | 2002-07-23 22:17:36 -0700 |
| commit | 97db62cc99a0d92650fbf23b7fbc034107eb01f3 (patch) | |
| tree | a708e1efa64cb8020b108b949857358e0a1cf19b /kernel/fork.c | |
| parent | 9e7cec8858f964d3be10e2f703c841cf05871e09 (diff) | |
[PATCH] scheduler fixes
- introduce new type of context-switch locking, this is a must-have for
ia64 and sparc64.
- load_balance() bug noticed by Scott Rhine and myself: scan the
whole list to find imbalance number of tasks, not just the tail
of the list.
- sched_yield() fix: use current->array not rq->active.
Diffstat (limited to 'kernel/fork.c')
| -rw-r--r-- | kernel/fork.c | 16 |
1 files changed, 10 insertions, 6 deletions
diff --git a/kernel/fork.c b/kernel/fork.c index 8fbe794a5ece..020db0f0e5b9 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -611,7 +611,6 @@ struct task_struct *do_fork(unsigned long clone_flags, unsigned long stack_size) { int retval; - unsigned long flags; struct task_struct *p = NULL; struct completion vfork; @@ -675,6 +674,7 @@ struct task_struct *do_fork(unsigned long clone_flags, init_completion(&vfork); } spin_lock_init(&p->alloc_lock); + spin_lock_init(&p->switch_lock); clear_tsk_thread_flag(p,TIF_SIGPENDING); init_sigpending(&p->pending); @@ -740,8 +740,13 @@ struct task_struct *do_fork(unsigned long clone_flags, * total amount of pending timeslices in the system doesnt change, * resulting in more scheduling fairness. */ - local_irq_save(flags); - p->time_slice = (current->time_slice + 1) >> 1; + local_irq_disable(); + p->time_slice = (current->time_slice + 1) >> 1; + /* + * The remainder of the first timeslice might be recovered by + * the parent if the child exits early enough. + */ + p->first_time_slice = 1; current->time_slice >>= 1; p->sleep_timestamp = jiffies; if (!current->time_slice) { @@ -753,11 +758,10 @@ struct task_struct *do_fork(unsigned long clone_flags, current->time_slice = 1; preempt_disable(); scheduler_tick(0, 0); - local_irq_restore(flags); + local_irq_enable(); preempt_enable(); } else - local_irq_restore(flags); - + local_irq_enable(); /* * Ok, add it to the run-queues and make it * visible to the rest of the system. |
