diff options
| author | Linus Torvalds <torvalds@athlon.transmeta.com> | 2002-02-04 18:03:57 -0800 |
|---|---|---|
| committer | Linus Torvalds <torvalds@athlon.transmeta.com> | 2002-02-04 18:03:57 -0800 |
| commit | cc80f8f99c1ba16d54b0af64cb3911cd0146259e (patch) | |
| tree | bc033080018817d4095c2891c76e9c19c68c83bd /fs/exec.c | |
| parent | 8565fe850b04acbfdc4c24cdcafeed359bb0f2b3 (diff) | |
v2.4.2.4 -> v2.4.2.5
- Rik van Riel and others: mm rw-semaphore (ps/top ok when swapping)
- IDE: 256 sectors at a time is legal, but apparently confuses some
drives. Max out at 255 sectors instead.
- Petko Manolov: USB pegasus driver update
- make the boottime memory map printout at least almost readable.
- USB driver updates
- pte_alloc()/pmd_alloc() need page_table_lock.
Diffstat (limited to 'fs/exec.c')
| -rw-r--r-- | fs/exec.c | 41 |
1 files changed, 21 insertions, 20 deletions
diff --git a/fs/exec.c b/fs/exec.c index 835d771363a8..08ea898ab285 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -262,27 +262,28 @@ void put_dirty_page(struct task_struct * tsk, struct page *page, unsigned long a if (page_count(page) != 1) printk("mem_map disagrees with %p at %08lx\n", page, address); pgd = pgd_offset(tsk->mm, address); - pmd = pmd_alloc(pgd, address); - if (!pmd) { - __free_page(page); - force_sig(SIGKILL, tsk); - return; - } - pte = pte_alloc(pmd, address); - if (!pte) { - __free_page(page); - force_sig(SIGKILL, tsk); - return; - } - if (!pte_none(*pte)) { - pte_ERROR(*pte); - __free_page(page); - return; - } + + spin_lock(&tsk->mm->page_table_lock); + pmd = pmd_alloc(tsk->mm, pgd, address); + if (!pmd) + goto out; + pte = pte_alloc(tsk->mm, pmd, address); + if (!pte) + goto out; + if (!pte_none(*pte)) + goto out; flush_dcache_page(page); flush_page_to_ram(page); set_pte(pte, pte_mkdirty(pte_mkwrite(mk_pte(page, PAGE_COPY)))); -/* no need for flush_tlb */ + spin_unlock(&tsk->mm->page_table_lock); + + /* no need for flush_tlb */ + return; +out: + spin_unlock(&tsk->mm->page_table_lock); + __free_page(page); + force_sig(SIGKILL, tsk); + return; } int setup_arg_pages(struct linux_binprm *bprm) @@ -302,7 +303,7 @@ int setup_arg_pages(struct linux_binprm *bprm) if (!mpnt) return -ENOMEM; - down(¤t->mm->mmap_sem); + down_write(¤t->mm->mmap_sem); { mpnt->vm_mm = current->mm; mpnt->vm_start = PAGE_MASK & (unsigned long) bprm->p; @@ -326,7 +327,7 @@ int setup_arg_pages(struct linux_binprm *bprm) } stack_base += PAGE_SIZE; } - up(¤t->mm->mmap_sem); + up_write(¤t->mm->mmap_sem); return 0; } |
