lkml.org 
[lkml]   [2009]   [Jun]   [16]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[patch 2/2] mm: remove task assumptions from swap token
    Date
    From: Hugh Dickins <hugh.dickins@tiscali.co.uk>

    grab_swap_token() should not make any assumptions about the running
    process as the swap token is an attribute of the address space and the
    faulting mm is not necessarily current->mm.

    This fixes get_user_pages() from kernel threads which would blow up
    when encountering a swapped out page and grab_swap_token()
    dereferencing the unset for kernel threads current->mm.

    Signed-off-by: Hugh Dickins <hugh.dickins@tiscali.co.uk>
    Signed-off-by: Johannes Weiner <hannes@cmpxchg.org>
    ---
    include/linux/swap.h | 4 ++--
    mm/memory.c | 2 +-
    mm/thrash.c | 31 +++++++++++++++----------------
    3 files changed, 18 insertions(+), 19 deletions(-)

    diff --git a/include/linux/swap.h b/include/linux/swap.h
    index 3c6e856..e73ea8a 100644
    --- a/include/linux/swap.h
    +++ b/include/linux/swap.h
    @@ -315,7 +315,7 @@ struct backing_dev_info;

    /* linux/mm/thrash.c */
    extern struct mm_struct * swap_token_mm;
    -extern void grab_swap_token(void);
    +extern void grab_swap_token(struct mm_struct *);
    extern void __put_swap_token(struct mm_struct *);

    static inline int has_swap_token(struct mm_struct *mm)
    @@ -430,7 +430,7 @@ static inline void put_swap_token(struct mm_struct *mm)
    {
    }

    -static inline void grab_swap_token(void)
    +static inline void grab_swap_token(struct mm_struct *mm)
    {
    }

    diff --git a/mm/memory.c b/mm/memory.c
    index 4126dd1..862e120 100644
    --- a/mm/memory.c
    +++ b/mm/memory.c
    @@ -2466,7 +2466,7 @@ static int do_swap_page(struct mm_struct *mm, struct vm_area_struct *vma,
    delayacct_set_flag(DELAYACCT_PF_SWAPIN);
    page = lookup_swap_cache(entry);
    if (!page) {
    - grab_swap_token(); /* Contend for token _before_ read-in */
    + grab_swap_token(mm); /* Contend for token _before_ read-in */
    page = swapin_readahead(entry,
    GFP_HIGHUSER_MOVABLE, vma, address);
    if (!page) {
    diff --git a/mm/thrash.c b/mm/thrash.c
    index c4c5205..8b864ae 100644
    --- a/mm/thrash.c
    +++ b/mm/thrash.c
    @@ -26,47 +26,46 @@ static DEFINE_SPINLOCK(swap_token_lock);
    struct mm_struct *swap_token_mm;
    static unsigned int global_faults;

    -void grab_swap_token(void)
    +void grab_swap_token(struct mm_struct *mm)
    {
    int current_interval;

    global_faults++;

    - current_interval = global_faults - current->mm->faultstamp;
    + current_interval = global_faults - mm->faultstamp;

    if (!spin_trylock(&swap_token_lock))
    return;

    /* First come first served */
    if (swap_token_mm == NULL) {
    - current->mm->token_priority = current->mm->token_priority + 2;
    - swap_token_mm = current->mm;
    + mm->token_priority = mm->token_priority + 2;
    + swap_token_mm = mm;
    goto out;
    }

    - if (current->mm != swap_token_mm) {
    - if (current_interval < current->mm->last_interval)
    - current->mm->token_priority++;
    + if (mm != swap_token_mm) {
    + if (current_interval < mm->last_interval)
    + mm->token_priority++;
    else {
    - if (likely(current->mm->token_priority > 0))
    - current->mm->token_priority--;
    + if (likely(mm->token_priority > 0))
    + mm->token_priority--;
    }
    /* Check if we deserve the token */
    - if (current->mm->token_priority >
    + if (mm->token_priority >
    swap_token_mm->token_priority) {
    - current->mm->token_priority += 2;
    - swap_token_mm = current->mm;
    + mm->token_priority += 2;
    + swap_token_mm = mm;
    }
    } else {
    /* Token holder came in again! */
    - current->mm->token_priority += 2;
    + mm->token_priority += 2;
    }

    out:
    - current->mm->faultstamp = global_faults;
    - current->mm->last_interval = current_interval;
    + mm->faultstamp = global_faults;
    + mm->last_interval = current_interval;
    spin_unlock(&swap_token_lock);
    -return;
    }

    /* Called on process exit. */
    --
    1.6.3


    \
     
     \ /
      Last update: 2009-06-16 23:57    [W:0.027 / U:1.080 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site