From patchwork Fri May 3 18:27:09 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Stultz X-Patchwork-Id: 16699 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-ve0-f198.google.com (mail-ve0-f198.google.com [209.85.128.198]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 1084925DFE for ; Fri, 3 May 2013 18:27:41 +0000 (UTC) Received: by mail-ve0-f198.google.com with SMTP id 15sf3418747vea.1 for ; Fri, 03 May 2013 11:27:30 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-received:mime-version:x-beenthere:x-received:received-spf :x-received:x-forwarded-to:x-forwarded-for:delivered-to:x-received :received-spf:x-received:from:to:cc:subject:date:message-id:x-mailer :in-reply-to:references:x-gm-message-state:x-original-sender :x-original-authentication-results:precedence:mailing-list:list-id :x-google-group-id:list-post:list-help:list-archive:list-unsubscribe; bh=sUJh6Bv2YNrEaaytQZYKLtaDhhwOneAZ1Jx/R8Pc0qU=; b=NoGltqFCIhDxcVsI6O4YzgUriU6sFuOEOIbYeieHOTs3kWQf1gXmRYHpgQsCHfZ6Ns GwGECMjJKNDpdVuHznQmGqZCOea0lP8Idrw/ZaYtVRUGKR9DSmyRO0i4bDRt1TbZR70w ffdZXHyPNsuU7vda36YLS7SptctUJhOz9hKHbYD06AaXDfsqGUQKZLZpNpQmHzkdeOKW Y/FnWTLP712+h1l47jdsn+7cVRAiGGK+o2KiwLS7cfMfMFJ7V6lyAGUK/ZcYwXRO2Gxr brUHahuwCxEktVCDPkWZg+618C9DjBgeHdKPv/FaCUywjQTIgyDTQlUfN4StQGWlUUn1 9Y0A== X-Received: by 10.236.128.207 with SMTP id f55mr9222292yhi.28.1367605650750; Fri, 03 May 2013 11:27:30 -0700 (PDT) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.49.127.230 with SMTP id nj6ls1995569qeb.87.gmail; Fri, 03 May 2013 11:27:30 -0700 (PDT) X-Received: by 10.52.169.231 with SMTP id ah7mr3364668vdc.110.1367605650448; Fri, 03 May 2013 11:27:30 -0700 (PDT) Received: from mail-ve0-x22c.google.com (mail-ve0-x22c.google.com [2607:f8b0:400c:c01::22c]) by mx.google.com with ESMTPS id cy6si5527008vcb.86.2013.05.03.11.27.30 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Fri, 03 May 2013 11:27:30 -0700 (PDT) Received-SPF: neutral (google.com: 2607:f8b0:400c:c01::22c is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) client-ip=2607:f8b0:400c:c01::22c; Received: by mail-ve0-f172.google.com with SMTP id da11so1818735veb.3 for ; Fri, 03 May 2013 11:27:30 -0700 (PDT) X-Received: by 10.220.89.198 with SMTP id f6mr4086876vcm.45.1367605650307; Fri, 03 May 2013 11:27:30 -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.58.127.98 with SMTP id nf2csp34381veb; Fri, 3 May 2013 11:27:29 -0700 (PDT) X-Received: by 10.68.138.7 with SMTP id qm7mr15410748pbb.169.1367605649355; Fri, 03 May 2013 11:27:29 -0700 (PDT) Received: from mail-pb0-x230.google.com (mail-pb0-x230.google.com [2607:f8b0:400e:c01::230]) by mx.google.com with ESMTPS id tk6si8031707pbc.346.2013.05.03.11.27.28 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Fri, 03 May 2013 11:27:29 -0700 (PDT) Received-SPF: neutral (google.com: 2607:f8b0:400e:c01::230 is neither permitted nor denied by best guess record for domain of john.stultz@linaro.org) client-ip=2607:f8b0:400e:c01::230; Received: by mail-pb0-f48.google.com with SMTP id ma3so1023516pbc.7 for ; Fri, 03 May 2013 11:27:28 -0700 (PDT) X-Received: by 10.66.253.132 with SMTP id aa4mr15766598pad.131.1367605648834; Fri, 03 May 2013 11:27:28 -0700 (PDT) Received: from localhost.localdomain (c-24-21-54-107.hsd1.or.comcast.net. [24.21.54.107]) by mx.google.com with ESMTPSA id qh4sm13792406pac.8.2013.05.03.11.27.27 for (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Fri, 03 May 2013 11:27:28 -0700 (PDT) From: John Stultz To: Minchan Kim Cc: John Stultz Subject: [PATCH 05/12] vrange: Support file based shared volatile ranges Date: Fri, 3 May 2013 11:27:09 -0700 Message-Id: <1367605636-18284-6-git-send-email-john.stultz@linaro.org> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1367605636-18284-1-git-send-email-john.stultz@linaro.org> References: <1367605636-18284-1-git-send-email-john.stultz@linaro.org> X-Gm-Message-State: ALoCoQm7+ytc+UndAkFycF0DyJsbUYQx/FJ/jr8jx0dG25QxhyfoUguyam55i2BQ6Ql6erQjk4ym X-Original-Sender: john.stultz@linaro.org X-Original-Authentication-Results: mx.google.com; spf=neutral (google.com: 2607:f8b0:400c:c01::22c is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) 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: , Extend vrange syscall to properly support VRANGE_MODE_SHARED behavior on file pages. Signed-off-by: John Stultz --- fs/file_table.c | 5 ++ fs/inode.c | 2 + include/linux/fs.h | 2 + include/linux/vrange.h | 1 + include/uapi/asm-generic/mman-common.h | 2 + mm/vrange.c | 92 ++++++++++++++++++++++++++++++++-- 6 files changed, 99 insertions(+), 5 deletions(-) diff --git a/fs/file_table.c b/fs/file_table.c index cd4d87a..94e2cd3 100644 --- a/fs/file_table.c +++ b/fs/file_table.c @@ -26,6 +26,7 @@ #include #include #include +#include #include @@ -244,6 +245,10 @@ static void __fput(struct file *file) file->f_op->fasync(-1, file, 0); } ima_file_free(file); + + /* drop all vranges on last close */ + vrange_root_cleanup(&inode->i_mapping->vroot); + if (file->f_op && file->f_op->release) file->f_op->release(inode, file); security_file_free(file); diff --git a/fs/inode.c b/fs/inode.c index a898b3d..7171313 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -17,6 +17,7 @@ #include #include /* for inode_has_buffers */ #include +#include #include "internal.h" /* @@ -350,6 +351,7 @@ void address_space_init_once(struct address_space *mapping) spin_lock_init(&mapping->private_lock); mapping->i_mmap = RB_ROOT; INIT_LIST_HEAD(&mapping->i_mmap_nonlinear); + vrange_root_init(&mapping->vroot, VRANGE_FILE); } EXPORT_SYMBOL(address_space_init_once); diff --git a/include/linux/fs.h b/include/linux/fs.h index 2c28271..6f86c7c 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -411,6 +412,7 @@ struct address_space { struct rb_root i_mmap; /* tree of private and shared mappings */ struct list_head i_mmap_nonlinear;/*list VM_NONLINEAR mappings */ struct mutex i_mmap_mutex; /* protect tree, count, list */ + struct vrange_root vroot; /* Protected by tree_lock together with the radix tree */ unsigned long nrpages; /* number of total pages */ pgoff_t writeback_index;/* writeback starts here */ diff --git a/include/linux/vrange.h b/include/linux/vrange.h index 4424b8d..38ca5d4 100644 --- a/include/linux/vrange.h +++ b/include/linux/vrange.h @@ -3,6 +3,7 @@ #include #include +#include #define vrange_entry(ptr) \ container_of(ptr, struct vrange, node.rb) diff --git a/include/uapi/asm-generic/mman-common.h b/include/uapi/asm-generic/mman-common.h index 9be120b..60cc65b 100644 --- a/include/uapi/asm-generic/mman-common.h +++ b/include/uapi/asm-generic/mman-common.h @@ -69,4 +69,6 @@ #define VRANGE_VOLATILE 0 /* unpin pages so VM can discard them */ #define VRANGE_NONVOLATILE 1 /* pin pages so VM can't discard them */ +#define VRANGE_MODE_SHARED 0x1 /* Volatility is shared on files */ + #endif /* __ASM_GENERIC_MMAN_COMMON_H */ diff --git a/mm/vrange.c b/mm/vrange.c index 4949152..800287d 100644 --- a/mm/vrange.c +++ b/mm/vrange.c @@ -6,6 +6,7 @@ #include #include #include +#include static struct kmem_cache *vrange_cachep; @@ -235,6 +236,75 @@ static int vrange_private(struct mm_struct *mm, return end-start; } +static int vrange_shared(struct mm_struct *mm, + unsigned long start, unsigned long end, + int mode, int *purged) +{ + struct vm_area_struct *vma; + int count = 0, ret = 0, orig_start = start; + + down_write(&mm->mmap_sem); + + vma = find_vma(mm, start); + for (;;) { + struct vrange_root *vroot; + unsigned long tmp, vstart, vend; + + if (!vma) + goto out; + + /* make sure start is at the front of the current vma*/ + if (start < vma->vm_start) { + start = vma->vm_start; + if (start >= end) + goto out; + } + + /* bound tmp to closer of vm_end & end */ + tmp = vma->vm_end; + if (end < tmp) + tmp = end; + + if (vma->vm_file) { + /* Convert to file relative offsets */ + vroot = &vma->vm_file->f_mapping->vroot; + vstart = vma->vm_pgoff + start - vma->vm_start; + vend = vma->vm_pgoff + tmp - vma->vm_start; + } else { + vroot = &mm->vroot; + vstart = start; + vend = tmp; + } + + /* mark or unmark */ + if (mode == VRANGE_VOLATILE) + ret = vrange_add(vroot, vstart, vend - 1); + else if (mode == VRANGE_NONVOLATILE) + ret = vrange_remove(vroot, vstart, vend - 1, purged); + + if (ret) + goto out; + + /* update count to distance covered so far*/ + count = tmp - orig_start; + + /* move start up to the end of the vma*/ + start = vma->vm_end; + if (start >= end) + goto out; + /* move to the next vma */ + vma = vma->vm_next; + } +out: + up_write(&mm->mmap_sem); + + /* report bytes successfully marked, even if we're exiting on error */ + if (count) + return count; + + return ret; +} + /* * The vrange(2) system call. * @@ -250,7 +320,15 @@ static int vrange_private(struct mm_struct *mm, * VRANGE_NONVOLATILE - Removes any volatile hints previous specified in that * range. * - * behavior values (bitflags): None yet supported. + * behavior values (bitflags): + * VRANGE_MODE_SHARED - By default, all volatile ranges are private to the + * process. Thus no pages will be purged unless all processes + * that have that page mapped agree that it is volatile. + * The VRANGE_MODE_SHARED flag allows the volatility to be shared + * with any other process mapping those files in a shared fasion + * Thus if any process marks a page as volatile, it can be purged + * from any other process that maps that file (similar to the + * MAP_SHARED semantics for mmap). * * purged ptr: * Returns 1 if any page in the range being marked nonvolatile has been purged. @@ -269,8 +347,8 @@ SYSCALL_DEFINE5(vrange, unsigned long, start, struct mm_struct *mm = current->mm; int ret = -EINVAL; - /* We don't yet support any behavior modes */ - if (behavior) + /* We only support SHARED behavior mode */ + if (behavior & ~VRANGE_MODE_SHARED) return -ENOTSUPP; if (start & ~PAGE_MASK) @@ -287,8 +365,12 @@ SYSCALL_DEFINE5(vrange, unsigned long, start, if (start >= TASK_SIZE) goto out; - ret = vrange_private(mm, start, end, mode, purged); - + if (behavior & VRANGE_MODE_SHARED) + ret = vrange_shared(mm, start, end, mode, purged); + else + ret = vrange_private(mm, start, end, mode, purged); out: return ret; } + +