lkml.org 
[lkml]   [1999]   [Jul]   [21]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    SubjectRe: [2.3.11=pre6]: No OOPS, but mount segfaults remounting "/"?


    On 21 Jul 1999, Linus Torvalds wrote:

    > I'm working on a pre-8 right now, but in the meantime pre-7 is the way
    > to go (I bet that the problem in pre-7 is basically impossible to
    > trigger unless you really design for it). There may be problems we don't
    > even know about, so testing is good.

    There are. Coredumps are b0rken - we should check for presense of other
    non-lazy owners instead of the total counter.

    I did the counter separation. The differences (aside of the stuff we
    discussed yesterday):
    * destroy_context() went to mmput()
    * I don't see the need to switch to init_mm upon exit_mm() - what
    for? Old context will serve us equally fine and the next schedule will
    bury it. We should do exit_mmap(), indeed, but that's it.
    * -pre7 has a race in exec() for lazy threads. ->active_mm may
    change while we are allocating new mm and pgd.
    * in assorted places we should use different counters (coredumps
    being an example).

    Patch follows:

    diff -urN linux-2.3.11-pre7/arch/i386/kernel/ldt.c linux-bird.lazy-TLB/arch/i386/kernel/ldt.c
    --- linux-2.3.11-pre7/arch/i386/kernel/ldt.c Wed Jul 21 02:31:43 1999
    +++ linux-bird.lazy-TLB/arch/i386/kernel/ldt.c Wed Jul 21 14:19:15 1999
    @@ -94,7 +94,7 @@
    if (!mm->segments)
    goto out_unlock;

    - if (atomic_read(&mm->count) > 1)
    + if (atomic_read(&mm->mm_count) > 1)
    printk(KERN_WARNING "LDT allocated for cloned task!\n");
    /*
    * Possibly do an SMP cross-call to other CPUs to reload
    diff -urN linux-2.3.11-pre7/arch/sparc/mm/srmmu.c linux-bird.lazy-TLB/arch/sparc/mm/srmmu.c
    --- linux-2.3.11-pre7/arch/sparc/mm/srmmu.c Tue Jul 6 04:31:10 1999
    +++ linux-bird.lazy-TLB/arch/sparc/mm/srmmu.c Wed Jul 21 12:10:41 1999
    @@ -2042,7 +2042,7 @@

    static void srmmu_destroy_context(struct mm_struct *mm)
    {
    - if(mm->context != NO_CONTEXT && atomic_read(&mm->count) == 1) {
    + if(mm->context != NO_CONTEXT) {
    /* XXX This could be drastically improved.
    * XXX We are only called from __exit_mm and it just did
    * XXX cache/tlb mm flush and right after this will (re-)
    @@ -2127,7 +2127,7 @@

    static void hypersparc_destroy_context(struct mm_struct *mm)
    {
    - if(mm->context != NO_CONTEXT && atomic_read(&mm->count) == 1) {
    + if(mm->context != NO_CONTEXT) {
    ctxd_t *ctxp;

    /* HyperSparc is copy-back, any data for this
    diff -urN linux-2.3.11-pre7/arch/sparc/mm/sun4c.c linux-bird.lazy-TLB/arch/sparc/mm/sun4c.c
    --- linux-2.3.11-pre7/arch/sparc/mm/sun4c.c Tue Jul 6 04:31:10 1999
    +++ linux-bird.lazy-TLB/arch/sparc/mm/sun4c.c Wed Jul 21 12:10:49 1999
    @@ -2147,7 +2147,7 @@
    {
    struct ctx_list *ctx_old;

    - if(mm->context != NO_CONTEXT && atomic_read(&mm->count) == 1) {
    + if(mm->context != NO_CONTEXT) {
    sun4c_demap_context_hw(&sun4c_context_ring[mm->context], mm->context);
    ctx_old = ctx_list_pool + mm->context;
    remove_from_ctx_list(ctx_old);
    @@ -2210,7 +2210,7 @@
    {
    struct ctx_list *ctx_old;

    - if(mm->context != NO_CONTEXT && atomic_read(&mm->count) == 1) {
    + if(mm->context != NO_CONTEXT) {
    sun4c_demap_context_sw(&sun4c_context_ring[mm->context], mm->context);
    ctx_old = ctx_list_pool + mm->context;
    remove_from_ctx_list(ctx_old);
    diff -urN linux-2.3.11-pre7/fs/binfmt_aout.c linux-bird.lazy-TLB/fs/binfmt_aout.c
    --- linux-2.3.11-pre7/fs/binfmt_aout.c Fri Jul 2 21:20:24 1999
    +++ linux-bird.lazy-TLB/fs/binfmt_aout.c Wed Jul 21 13:51:34 1999
    @@ -106,7 +106,7 @@
    # define START_STACK(u) (u.start_stack)
    #endif

    - if (!current->dumpable || atomic_read(&current->mm->count) != 1)
    + if (!current->dumpable || atomic_read(&current->mm->mm_users) != 1)
    return 0;
    current->dumpable = 0;

    diff -urN linux-2.3.11-pre7/fs/binfmt_elf.c linux-bird.lazy-TLB/fs/binfmt_elf.c
    --- linux-2.3.11-pre7/fs/binfmt_elf.c Tue Jul 6 04:33:47 1999
    +++ linux-bird.lazy-TLB/fs/binfmt_elf.c Wed Jul 21 13:51:50 1999
    @@ -1060,7 +1060,7 @@

    if (!current->dumpable ||
    limit < ELF_EXEC_PAGESIZE ||
    - atomic_read(&current->mm->count) != 1)
    + atomic_read(&current->mm->mm_users) != 1)
    return 0;
    current->dumpable = 0;

    diff -urN linux-2.3.11-pre7/fs/exec.c linux-bird.lazy-TLB/fs/exec.c
    --- linux-2.3.11-pre7/fs/exec.c Wed Jul 21 02:31:53 1999
    +++ linux-bird.lazy-TLB/fs/exec.c Wed Jul 21 14:06:52 1999
    @@ -374,8 +374,11 @@
    * lazy mm, so we can turn it into a real mm.
    */
    old_mm = current->active_mm;
    - if (atomic_read(&old_mm->count) == 1) {
    - current->mm = old_mm;
    + if (atomic_read(&old_mm->mm_count) == 1) {
    + if (!current->mm) {
    + atomic_inc(&old_mm->mm_users);
    + current->mm = old_mm;
    + }
    flush_cache_mm(old_mm);
    mm_release();
    release_segments(old_mm);
    @@ -395,11 +398,15 @@
    if (!mm->pgd)
    goto fail_free;

    + old_mm = current->active_mm; /* we might sleep */
    current->mm = mm;
    current->active_mm = mm;
    SET_PAGE_DIR(current, mm->pgd);
    activate_context(current);
    mm_release();
    + if (atomic_dec_and_test(&old_mm->mm_users)) {
    + exit_mmap(old_mm);
    + }
    mmput(old_mm);
    return 0;

    diff -urN linux-2.3.11-pre7/fs/proc/array.c linux-bird.lazy-TLB/fs/proc/array.c
    --- linux-2.3.11-pre7/fs/proc/array.c Wed Jul 21 02:31:54 1999
    +++ linux-bird.lazy-TLB/fs/proc/array.c Wed Jul 21 14:04:17 1999
    @@ -1115,7 +1115,7 @@
    goto getlen_out;

    /* Check whether the mmaps could change if we sleep */
    - volatile_task = (p != current || atomic_read(&p->mm->count) > 1);
    + volatile_task = (p != current || atomic_read(&p->mm->mm_users) > 1);

    /* decode f_pos */
    lineno = *ppos >> MAPS_LINE_SHIFT;
    diff -urN linux-2.3.11-pre7/include/asm-sparc64/mmu_context.h linux-bird.lazy-TLB/include/asm-sparc64/mmu_context.h
    --- linux-2.3.11-pre7/include/asm-sparc64/mmu_context.h Mon Jun 21 13:17:39 1999
    +++ linux-bird.lazy-TLB/include/asm-sparc64/mmu_context.h Wed Jul 21 12:12:00 1999
    @@ -35,8 +35,7 @@
    * the final reference to the address space.
    */
    #define destroy_context(__mm) do { \
    - if ((__mm)->context != NO_CONTEXT && \
    - atomic_read(&(__mm)->count) == 1) { \
    + if ((__mm)->context != NO_CONTEXT ) { \
    if (!(((__mm)->context ^ tlb_context_cache) & CTX_VERSION_MASK))\
    clear_bit((__mm)->context & ~(CTX_VERSION_MASK), \
    mmu_context_bmap); \
    diff -urN linux-2.3.11-pre7/include/linux/sched.h linux-bird.lazy-TLB/include/linux/sched.h
    --- linux-2.3.11-pre7/include/linux/sched.h Wed Jul 21 02:31:57 1999
    +++ linux-bird.lazy-TLB/include/linux/sched.h Wed Jul 21 13:46:53 1999
    @@ -170,7 +170,8 @@
    struct vm_area_struct * mmap_avl; /* tree of VMAs */
    struct vm_area_struct * mmap_cache; /* last find_vma result */
    pgd_t * pgd;
    - atomic_t count;
    + atomic_t mm_count;
    + atomic_t mm_users;
    int map_count; /* number of VMAs */
    struct semaphore mmap_sem;
    spinlock_t page_table_lock;
    @@ -193,7 +194,7 @@
    #define INIT_MM(name) { \
    &init_mmap, NULL, NULL, \
    swapper_pg_dir, \
    - ATOMIC_INIT(2), 1, \
    + ATOMIC_INIT(2), ATOMIC_INIT(0), 1, \
    __MUTEX_INITIALIZER(name.mmap_sem), \
    SPIN_LOCK_UNLOCKED, \
    0, \
    @@ -593,7 +594,7 @@
    extern struct mm_struct * mm_alloc(void);
    static inline void mmget(struct mm_struct * mm)
    {
    - atomic_inc(&mm->count);
    + atomic_inc(&mm->mm_count);
    }
    extern void mmput(struct mm_struct *);
    /* Remove the current tasks stale references to the old mm_struct */
    diff -urN linux-2.3.11-pre7/kernel/exit.c linux-bird.lazy-TLB/kernel/exit.c
    --- linux-2.3.11-pre7/kernel/exit.c Wed Jul 21 02:31:58 1999
    +++ linux-bird.lazy-TLB/kernel/exit.c Wed Jul 21 13:37:12 1999
    @@ -234,26 +234,20 @@
    struct mm_struct * mm = tsk->mm;

    /* Lazy TLB process? */
    - if (!mm) {
    - mm = tsk->active_mm;
    - goto drop_mm;
    - }
    + if (!mm)
    + return;

    /* Set us up to use the kernel mm state */
    flush_cache_mm(mm);
    flush_tlb_mm(mm);
    - destroy_context(mm);
    mm_release();

    /* This turns us into a task with no MM */
    tsk->mm = NULL;

    -drop_mm:
    - mmget(&init_mm);
    - tsk->active_mm = &init_mm;
    tsk->swappable = 0;
    - SET_PAGE_DIR(tsk, swapper_pg_dir);
    - mmput(mm);
    + if (atomic_dec_and_test(&mm->mm_users))
    + exit_mmap(mm);
    }

    void exit_mm(struct task_struct *tsk)
    diff -urN linux-2.3.11-pre7/kernel/fork.c linux-bird.lazy-TLB/kernel/fork.c
    --- linux-2.3.11-pre7/kernel/fork.c Wed Jul 21 02:31:58 1999
    +++ linux-bird.lazy-TLB/kernel/fork.c Wed Jul 21 13:50:20 1999
    @@ -301,7 +301,8 @@
    if (mm) {
    memset(mm, 0, sizeof(*mm));
    init_new_context(mm);
    - atomic_set(&mm->count, 1);
    + atomic_set(&mm->mm_count, 1);
    + atomic_set(&mm->mm_users, 1);
    init_MUTEX(&mm->mmap_sem);
    mm->page_table_lock = SPIN_LOCK_UNLOCKED;
    }
    @@ -337,10 +338,10 @@
    */
    void mmput(struct mm_struct *mm)
    {
    - if (atomic_dec_and_test(&mm->count)) {
    + if (atomic_dec_and_test(&mm->mm_count)) {
    if (mm == &init_mm) BUG();
    + destroy_context(mm);
    release_segments(mm);
    - exit_mmap(mm);
    free_page_tables(mm);
    kmem_cache_free(mm_cachep, mm);
    }
    @@ -368,6 +369,7 @@
    return 0;

    if (clone_flags & CLONE_VM) {
    + atomic_inc(&mm->mm_users);
    mmget(mm);
    goto good_mm;
    }
    @@ -401,11 +403,12 @@
    SET_PAGE_DIR(tsk, mm->pgd);
    return 0;

    +free_pt:
    + release_segments(mm);
    + exit_mmap(mm);
    + free_page_tables(mm);
    free_mm:
    kmem_cache_free(mm_cachep, mm);
    - return retval;
    -free_pt:
    - mmput(mm);
    fail_nomem:
    return retval;
    }

    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.rutgers.edu
    Please read the FAQ at http://www.tux.org/lkml/

    \
     
     \ /
      Last update: 2005-03-22 13:53    [W:0.048 / U:32.260 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site