lkml.org 
[lkml]   [2009]   [Dec]   [7]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[early RFC][PATCH 8/7] vmscan: Don't deactivate many touched page
    Date

    Andrea, Can you please try following patch on your workload?


    From a7758c66d36a136d5fbbcf0b042839445f0ca522 Mon Sep 17 00:00:00 2001
    From: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
    Date: Mon, 7 Dec 2009 18:37:20 +0900
    Subject: [PATCH] [RFC] vmscan: Don't deactivate many touched page

    Changelog
    o from andrea's original patch
    - Rebase topon my patches.
    - Use list_cut_position/list_splice_tail pair instead
    list_del/list_add to make pte scan fairness.
    - Only use max young threshold when soft_try is true.
    It avoid wrong OOM sideeffect.
    - Return SWAP_AGAIN instead successful result if max
    young threshold exceed. It prevent the pages without clear
    pte young bit will be deactivated wrongly.
    - Add to treat ksm page logic

    Many shared and frequently used page don't need deactivate and
    try_to_unamp(). It's pointless while VM pressure is low, the page
    might reactivate soon. it's only makes cpu wasting.

    Then, This patch makes to stop pte scan if wipe_page_reference()
    found lots young pte bit.

    Originally-Signed-off-by: Andrea Arcangeli <aarcange@redhat.com>
    Signed-off-by: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
    ---
    include/linux/rmap.h | 17 +++++++++++++++++
    mm/ksm.c | 4 ++++
    mm/rmap.c | 19 +++++++++++++++++++
    3 files changed, 40 insertions(+), 0 deletions(-)

    diff --git a/include/linux/rmap.h b/include/linux/rmap.h
    index 499972e..9ad69b5 100644
    --- a/include/linux/rmap.h
    +++ b/include/linux/rmap.h
    @@ -128,6 +128,23 @@ int wipe_page_reference_one(struct page *page,
    struct page_reference_context *refctx,
    struct vm_area_struct *vma, unsigned long address);

    +#define MAX_YOUNG_BIT_CLEARED 64
    +/*
    + * if VM pressure is low and the page have too many active mappings, there isn't
    + * any reason to continue clear young bit of other ptes. Otherwise,
    + * - Makes meaningless cpu wasting, many touched page sholdn't be reclaimed.
    + * - Makes lots IPI for pte change and it might cause another sadly lock
    + * contention.
    + */
    +static inline
    +int too_many_young_bit_found(struct page_reference_context *refctx)
    +{
    + if (refctx->soft_try &&
    + refctx->referenced >= MAX_YOUNG_BIT_CLEARED)
    + return 1;
    + return 0;
    +}
    +
    enum ttu_flags {
    TTU_UNMAP = 0, /* unmap mode */
    TTU_MIGRATION = 1, /* migration mode */
    diff --git a/mm/ksm.c b/mm/ksm.c
    index 3c121c8..46ea519 100644
    --- a/mm/ksm.c
    +++ b/mm/ksm.c
    @@ -1586,6 +1586,10 @@ again:
    rmap_item->address);
    if (ret != SWAP_SUCCESS)
    goto out;
    + if (too_many_young_bit_found(refctx)) {
    + ret = SWAP_AGAIN;
    + goto out;
    + }
    mapcount--;
    if (!search_new_forks || !mapcount)
    break;
    diff --git a/mm/rmap.c b/mm/rmap.c
    index cfda0a0..f4517f3 100644
    --- a/mm/rmap.c
    +++ b/mm/rmap.c
    @@ -473,6 +473,21 @@ static int wipe_page_reference_anon(struct page *page,
    ret = wipe_page_reference_one(page, refctx, vma, address);
    if (ret != SWAP_SUCCESS)
    break;
    + if (too_many_young_bit_found(refctx)) {
    + LIST_HEAD(tmp_list);
    +
    + /*
    + * The scanned ptes move to list tail. it help every ptes
    + * on this page will be tested by ptep_clear_young().
    + * Otherwise, this shortcut makes unfair thing.
    + */
    + list_cut_position(&tmp_list,
    + &vma->anon_vma_node,
    + &anon_vma->head);
    + list_splice_tail(&tmp_list, &vma->anon_vma_node);
    + ret = SWAP_AGAIN;
    + break;
    + }
    mapcount--;
    if (!mapcount || refctx->maybe_mlocked)
    break;
    @@ -543,6 +558,10 @@ static int wipe_page_reference_file(struct page *page,
    ret = wipe_page_reference_one(page, refctx, vma, address);
    if (ret != SWAP_SUCCESS)
    break;
    + if (too_many_young_bit_found(refctx)) {
    + ret = SWAP_AGAIN;
    + break;
    + }
    mapcount--;
    if (!mapcount || refctx->maybe_mlocked)
    break;
    --
    1.6.5.2




    \
     
     \ /
      Last update: 2009-12-07 12:39    [W:2.537 / U:0.056 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site