From patchwork Tue Apr 29 21:21:22 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Stultz X-Patchwork-Id: 29377 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-yh0-f69.google.com (mail-yh0-f69.google.com [209.85.213.69]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 5BBB5202DD for ; Tue, 29 Apr 2014 21:21:48 +0000 (UTC) Received: by mail-yh0-f69.google.com with SMTP id b6sf2926712yha.0 for ; Tue, 29 Apr 2014 14:21:48 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:delivered-to:from:to:cc:subject :date:message-id:in-reply-to:references:x-original-sender :x-original-authentication-results:precedence:mailing-list:list-id :list-post:list-help:list-archive:list-unsubscribe; bh=uiRUs4El8lsYdvNQKoldgxt3fiL/1J2Zq5mgVy5HIHk=; b=C5GWtoyzi3a5yXh3HvB1qNvuZaPST8F7sxNsNsScz0pt1zP/GDvZkrq6lDBRzh+gTY hzL3XCJxxM4yH+toeiLbhNRKuTu6tG0jQEeKu25RRaktCt85M1cyvQeFgVvU+viz4FDX rYzFpQ4Gv1GhUGBnYF/2jMZVvKA9GL20b6v7TcsxoRqowGcQqxScQZuTt0e9zGqspTQz 9iFK5/oIJAOw0qDaKrJuvybU1DD9ZrmiH/afynsJO+/bz1q/qiYgwCqtsc2870BizH76 ju4XTrFV2pi71w+G+HiYPNWrFBDTU+XrTF8EwKmHtF05JJ4pm5UiRyx+kxbar7eTwc92 r+Vg== X-Gm-Message-State: ALoCoQlKkOV1iGXW2vg+aT6OcgnO/YR2ji5MWsqjb/JR/Kgeyr6GC24E+qoTTrmOXKH465kxnkuh X-Received: by 10.236.134.235 with SMTP id s71mr27640yhi.55.1398806508107; Tue, 29 Apr 2014 14:21:48 -0700 (PDT) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.140.29.130 with SMTP id b2ls275571qgb.99.gmail; Tue, 29 Apr 2014 14:21:47 -0700 (PDT) X-Received: by 10.52.126.107 with SMTP id mx11mr88789vdb.41.1398806507940; Tue, 29 Apr 2014 14:21:47 -0700 (PDT) Received: from mail-ve0-f169.google.com (mail-ve0-f169.google.com [209.85.128.169]) by mx.google.com with ESMTPS id bf4si4843285vec.154.2014.04.29.14.21.47 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Tue, 29 Apr 2014 14:21:47 -0700 (PDT) Received-SPF: none (google.com: patch+caf_=patchwork-forward=linaro.org@linaro.org does not designate permitted sender hosts) client-ip=209.85.128.169; Received: by mail-ve0-f169.google.com with SMTP id jx11so1037858veb.14 for ; Tue, 29 Apr 2014 14:21:47 -0700 (PDT) X-Received: by 10.220.191.134 with SMTP id dm6mr193571vcb.16.1398806507853; Tue, 29 Apr 2014 14:21:47 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patches@linaro.org Received: by 10.220.221.72 with SMTP id ib8csp228819vcb; Tue, 29 Apr 2014 14:21:40 -0700 (PDT) X-Received: by 10.67.14.98 with SMTP id ff2mr331121pad.101.1398806500666; Tue, 29 Apr 2014 14:21:40 -0700 (PDT) Received: from mail-pa0-f54.google.com (mail-pa0-f54.google.com [209.85.220.54]) by mx.google.com with ESMTPS id tm7si14318780pab.193.2014.04.29.14.21.40 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Tue, 29 Apr 2014 14:21:40 -0700 (PDT) Received-SPF: none (google.com: john.stultz@linaro.org does not designate permitted sender hosts) client-ip=209.85.220.54; Received: by mail-pa0-f54.google.com with SMTP id lf10so838430pab.27 for ; Tue, 29 Apr 2014 14:21:40 -0700 (PDT) X-Received: by 10.66.141.144 with SMTP id ro16mr279297pab.131.1398806500128; Tue, 29 Apr 2014 14:21:40 -0700 (PDT) Received: from localhost.localdomain (c-67-170-153-23.hsd1.or.comcast.net. [67.170.153.23]) by mx.google.com with ESMTPSA id yv7sm118814095pac.33.2014.04.29.14.21.38 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 29 Apr 2014 14:21:39 -0700 (PDT) From: John Stultz To: LKML Cc: John Stultz , Andrew Morton , Android Kernel Team , Johannes Weiner , Robert Love , Mel Gorman , Hugh Dickins , Dave Hansen , Rik van Riel , Dmitry Adamushko , Neil Brown , Andrea Arcangeli , Mike Hommey , Taras Glek , Jan Kara , KOSAKI Motohiro , Michel Lespinasse , Minchan Kim , Keith Packard , "linux-mm@kvack.org" Subject: [PATCH 3/4] MADV_VOLATILE: Add purged page detection on setting memory non-volatile Date: Tue, 29 Apr 2014 14:21:22 -0700 Message-Id: <1398806483-19122-4-git-send-email-john.stultz@linaro.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1398806483-19122-1-git-send-email-john.stultz@linaro.org> References: <1398806483-19122-1-git-send-email-john.stultz@linaro.org> X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: john.stultz@linaro.org X-Original-Authentication-Results: mx.google.com; spf=neutral (google.com: patch+caf_=patchwork-forward=linaro.org@linaro.org does not designate permitted sender hosts) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Precedence: list Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org List-ID: X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , Users of volatile ranges will need to know if memory was discarded. This patch adds the purged state tracking required to inform userland when it marks memory as non-volatile that some memory in that range was purged and needs to be regenerated. This simplified implementation which uses some of the logic from Minchan's earlier efforts, so credit to Minchan for his work. Cc: Andrew Morton Cc: Android Kernel Team Cc: Johannes Weiner Cc: Robert Love Cc: Mel Gorman Cc: Hugh Dickins Cc: Dave Hansen Cc: Rik van Riel Cc: Dmitry Adamushko Cc: Neil Brown Cc: Andrea Arcangeli Cc: Mike Hommey Cc: Taras Glek Cc: Jan Kara Cc: KOSAKI Motohiro Cc: Michel Lespinasse Cc: Minchan Kim Cc: Keith Packard Cc: linux-mm@kvack.org Acked-by: Jan Kara Signed-off-by: John Stultz --- include/linux/swap.h | 5 +++ include/linux/swapops.h | 10 ++++++ mm/mvolatile.c | 87 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 102 insertions(+) diff --git a/include/linux/swap.h b/include/linux/swap.h index a32c3da..3abc977 100644 --- a/include/linux/swap.h +++ b/include/linux/swap.h @@ -55,6 +55,7 @@ enum { * 1< #include #include +#include +#include #include "internal.h" +struct mvolatile_walker { + struct vm_area_struct *vma; + int page_was_purged; +}; + + +/** + * mvolatile_check_purged_pte - Checks ptes for purged pages + * @pmd: pmd to walk + * @addr: starting address + * @end: end address + * @walk: mm_walk ptr (contains ptr to mvolatile_walker) + * + * Iterates over the ptes in the pmd checking if they have + * purged swap entries. + * + * Sets the mvolatile_walker.page_was_purged to 1 if any were purged, + * and clears the purged pte swp entries (since the pages are no + * longer volatile, we don't want future accesses to SIGBUS). + */ +static int mvolatile_check_purged_pte(pmd_t *pmd, unsigned long addr, + unsigned long end, struct mm_walk *walk) +{ + struct mvolatile_walker *vw = walk->private; + pte_t *pte; + spinlock_t *ptl; + + if (pmd_trans_huge(*pmd)) + return 0; + if (pmd_trans_unstable(pmd)) + return 0; + + pte = pte_offset_map_lock(walk->mm, pmd, addr, &ptl); + for (; addr != end; pte++, addr += PAGE_SIZE) { + if (!pte_present(*pte)) { + swp_entry_t mvolatile_entry = pte_to_swp_entry(*pte); + + if (unlikely(is_purged_entry(mvolatile_entry))) { + + vw->page_was_purged = 1; + + /* clear the pte swp entry */ + flush_cache_page(vw->vma, addr, pte_pfn(*pte)); + ptep_clear_flush(vw->vma, addr, pte); + } + } + } + pte_unmap_unlock(pte - 1, ptl); + cond_resched(); + + return 0; +} + + +/** + * mvolatile_check_purged - Sets up a mm_walk to check for purged pages + * @vma: ptr to vma we're starting with + * @start: start address to walk + * @end: end address of walk + * + * Sets up and calls wa_page_range() to check for purge pages. + * + * Returns 1 if pages in the range were purged, 0 otherwise. + */ +static int mvolatile_check_purged(struct vm_area_struct *vma, + unsigned long start, + unsigned long end) +{ + struct mvolatile_walker vw; + struct mm_walk mvolatile_walk = { + .pmd_entry = mvolatile_check_purged_pte, + .mm = vma->vm_mm, + .private = &vw, + }; + vw.page_was_purged = 0; + vw.vma = vma; + + walk_page_range(start, end, &mvolatile_walk); + + return vw.page_was_purged; +} + /** * madvise_volatile - Marks or clears VMAs in the range (start-end) as VM_VOLATILE @@ -140,6 +224,9 @@ int madvise_volatile(int mode, unsigned long start, unsigned long end) break; vma = vma->vm_next; } + + if (!ret && (mode == MADV_NONVOLATILE)) + ret = mvolatile_check_purged(vma, orig_start, end); out: up_write(&mm->mmap_sem);