summaryrefslogtreecommitdiffstats
path: root/kernel/fork.c
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2000-08-25 05:30:00 +0000
committerRalf Baechle <ralf@linux-mips.org>2000-08-25 05:30:00 +0000
commitee355114ec6062d00c1376b184b886a39e74fd4e (patch)
treeda9330872894208b121ac18e2abbc801b67f1509 /kernel/fork.c
parentd1003cbd87479d4962fe017c0f913dde9c4d026a (diff)
Merge with Linux 2.4.0-test6-pre9.
Diffstat (limited to 'kernel/fork.c')
-rw-r--r--kernel/fork.c48
1 files changed, 35 insertions, 13 deletions
diff --git a/kernel/fork.c b/kernel/fork.c
index 594ee79f3..f77eaa4ee 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -128,10 +128,16 @@ static inline int dup_mmap(struct mm_struct * mm)
struct vm_area_struct * mpnt, *tmp, **pprev;
int retval;
- /* Kill me slowly. UGLY! FIXME! */
- memcpy(&mm->start_code, &current->mm->start_code, 15*sizeof(unsigned long));
-
flush_cache_mm(current->mm);
+ mm->locked_vm = 0;
+ mm->mmap = NULL;
+ mm->mmap_cache = NULL;
+ mm->map_count = 0;
+ mm->context = 0;
+ mm->cpu_vm_mask = 0;
+ mm->swap_cnt = 0;
+ mm->swap_address = 0;
+ mm->segments = NULL;
pprev = &mm->mmap;
for (mpnt = current->mm->mmap ; mpnt ; mpnt = mpnt->vm_next) {
struct file *file;
@@ -189,6 +195,22 @@ fail_nomem:
return retval;
}
+#define allocate_mm() (kmem_cache_alloc(mm_cachep, SLAB_KERNEL))
+
+static struct mm_struct * mm_init(struct mm_struct * mm)
+{
+ atomic_set(&mm->mm_users, 1);
+ atomic_set(&mm->mm_count, 1);
+ init_MUTEX(&mm->mmap_sem);
+ mm->page_table_lock = SPIN_LOCK_UNLOCKED;
+ mm->pgd = pgd_alloc();
+ if (mm->pgd)
+ return mm;
+ kmem_cache_free(mm_cachep, mm);
+ return NULL;
+}
+
+
/*
* Allocate and initialize an mm_struct.
*/
@@ -196,17 +218,10 @@ struct mm_struct * mm_alloc(void)
{
struct mm_struct * mm;
- mm = kmem_cache_alloc(mm_cachep, SLAB_KERNEL);
+ mm = allocate_mm();
if (mm) {
memset(mm, 0, sizeof(*mm));
- atomic_set(&mm->mm_users, 1);
- atomic_set(&mm->mm_count, 1);
- init_MUTEX(&mm->mmap_sem);
- mm->page_table_lock = SPIN_LOCK_UNLOCKED;
- mm->pgd = pgd_alloc();
- if (mm->pgd)
- return mm;
- kmem_cache_free(mm_cachep, mm);
+ return mm_init(mm);
}
return NULL;
}
@@ -287,9 +302,15 @@ static inline int copy_mm(unsigned long clone_flags, struct task_struct * tsk)
retval = -ENOMEM;
mm = mm_alloc();
+ mm = allocate_mm();
if (!mm)
goto fail_nomem;
+ /* Copy the current MM stuff.. */
+ memcpy(mm, current->mm, sizeof(*mm));
+ if (!mm_init(mm))
+ goto fail_nomem;
+
tsk->mm = mm;
tsk->active_mm = mm;
@@ -304,10 +325,11 @@ static inline int copy_mm(unsigned long clone_flags, struct task_struct * tsk)
if (retval)
goto free_pt;
+ init_new_context(tsk,mm);
+
good_mm:
tsk->mm = mm;
tsk->active_mm = mm;
- init_new_context(tsk,mm);
return 0;
free_pt: