• Hugh Dickins's avatar
    [PATCH] lighten mmlist_lock · 1b46884a
    Hugh Dickins authored
    Let's lighten the global spinlock mmlist_lock.
    
    What's it for?
    1. Its original role is to guard mmlist.
    2. It later got a second role, to prevent get_task_mm from raising
       mm_users from the dead, just after it went down to 0.
    
    Firstly consider the second: __exit_mm sets tsk->mm NULL while holding
    task_lock before calling mmput; so mmlist_lock only guards against the
    exceptional case, of get_task_mm on a kernel workthread which did AIO's
    use_mm (which transiently sets its tsk->mm without raising mm_users) on an
    mm now exiting.
    
    Well, I don't think get_task_mm should succeed at all on use_mm tasks.
    It's mainly used by /proc/pid and ptrace, seems at best confusing for those
    to present the kernel thread as having a user mm, which it won't have a
    moment later.  Define PF_BORROWED_MM, set in use_mm, clear in unuse_mm
    (though we could just leave it), get_task_mm give NULL if set.
    
    Secondly consider the first: and what's mmlist for?
    1. Its original role was for swap_out to scan: rmap ended that in 2.5.27.
    2. In 2.4.10 it got a second role, for try_to_unuse to scan for swapoff.
    
    So, make mmlist a list of mms which maybe have pages on swap: add mm to
    mmlist when first swap entry is assigned in try_to_unmap_one (pageout), or
    in copy_page_range (fork); and mmput remove it from mmlist as before,
    except usually list_empty and there's no need to lock.  drain_mmlist added
    to swapoff, to empty out the mmlist if no swap is then in use.
    
    mmput leave mm on mmlist until after its exit_mmap, so try_to_unmap_one can
    still add mm to mmlist without worrying about the mm_users 0 case; but
    try_to_unuse must avoid the mm_users 0 case (when an mm might be removed
    from mmlist, and freed, while it's down in unuse_process): use
    atomic_inc_return now all architectures support that.
    
    Some of the detailed comments in try_to_unuse have grown out of date:
    updated and trimmed some, but leave SWAP_MAP_MAX for another occasion.
    Signed-off-by: default avatarHugh Dickins <hugh@veritas.com>
    Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
    Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
    1b46884a
swapfile.c 42.2 KB