mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Linus Torvalds <torvalds@linux-foundation.org>
To: Hugh Dickins <hugh@veritas.com>
Cc: Lee Schermerhorn <Lee.Schermerhorn@hp.com>,
	Greg KH <gregkh@suse.de>,
	Maksim Yevmenkin <maksim.yevmenkin@gmail.com>,
	linux-kernel <linux-kernel@vger.kernel.org>,
	Nick Piggin <npiggin@suse.de>,
	Andrew Morton <akpm@linux-foundation.org>,
	will@crowder-design.com, Rik van Riel <riel@redhat.com>,
	KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>,
	KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>,
	Mikos Szeredi <miklos@szeredi.hu>
Subject: Re: [PATCH] Fix OOPS in mmap_region() when merging adjacent VM_LOCKED file segments
Date: Sat, 31 Jan 2009 10:34:30 -0800 (PST)	[thread overview]
Message-ID: <alpine.LFD.2.00.0901311010460.3150@localhost.localdomain> (raw)
In-Reply-To: <Pine.LNX.4.64.0901311216250.6763@blonde.anvils>



On Sat, 31 Jan 2009, Hugh Dickins wrote:
>
> We need a way to communicate not-MAP_NORESERVE to shmem.c, and we don't
> just need it in the explicit shmem_zero_setup() case, we also need it
> for the (probably rare nowadays) case when mmap() is working on file
> /dev/zero (drivers/char/mem.c mmap_zero()), rather than using MAP_ANON.

Heh. We already have that. Maybe you didn't realize. Look at VM_NORESERVE.

So shmem.c can just look at "!(vma->vm_flags & VM_NORESERVE)" if it wants 
to.

The only piece of information you don't have is that "accountable" flag, 
but that was why I was pointing out how totally _useless_ that flag 
actually is. We shouldn't pass it along, because it's always 1, except for 
one special case that we can always calculate (private hugepages).

But in fact, even leaving that untouched, we can trivially just change 
what 'VM_NORESERVE' means: we can just make it the end result of all that 
'accountable' logic, instead of having it just mirror MAP_NORESERVE 
blindly.

> Still haven't decided what's best to do about it (plenty of diversions):
> perhaps we just say my error was to overload VM_ACCOUNT, and define a
> new flag for the purpose, which can go into VM_MERGEABLE_FLAGS; but
> I'd prefer a neater solution if it crosses my mind.

How about this pretty trivial patch?

TOTALLY UNTESTED. As usual. But the concept is pretty simple, and it 
actually removes a fair chunk of hacky code.  The only reason the diffstat 
output says that it adds more lines than it deletes is that I added more 
comments and made that helper inline function rather than make a complex 
conditional.

Whaddaya think?

		Linus

---
 mm/mmap.c  |   48 +++++++++++++++++++++++++-----------------------
 mm/shmem.c |    2 +-
 2 files changed, 26 insertions(+), 24 deletions(-)

diff --git a/mm/mmap.c b/mm/mmap.c
index c581df1..5fcaec3 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -1090,6 +1090,15 @@ int vma_wants_writenotify(struct vm_area_struct *vma)
 		mapping_cap_account_dirty(vma->vm_file->f_mapping);
 }
 
+/*
+ * We account for memory if it's a private writeable mapping,
+ * and VM_NORESERVE wasn't set.
+ */
+static inline int private_accountable_mapping(unsigned int vm_flags)
+{
+	return (vm_flags & (VM_NORESERVE | VM_SHARED | VM_WRITE)) == VM_WRITE;
+}
+
 unsigned long mmap_region(struct file *file, unsigned long addr,
 			  unsigned long len, unsigned long flags,
 			  unsigned int vm_flags, unsigned long pgoff,
@@ -1117,23 +1126,24 @@ munmap_back:
 	if (!may_expand_vm(mm, len >> PAGE_SHIFT))
 		return -ENOMEM;
 
-	if (flags & MAP_NORESERVE)
+	/*
+	 * Set 'VM_NORESERVE' if we should not account for the
+	 * memory use of this mapping. We only honor MAP_NORESERVE
+	 * if we're allowed to overcommit memory.
+	 */
+	if ((flags & MAP_NORESERVE) && sysctl_overcommit_memory != OVERCOMMIT_NEVER)
+		vm_flags |= VM_NORESERVE;
+	if (!accountable)
 		vm_flags |= VM_NORESERVE;
 
-	if (accountable && (!(flags & MAP_NORESERVE) ||
-			    sysctl_overcommit_memory == OVERCOMMIT_NEVER)) {
-		if (vm_flags & VM_SHARED) {
-			/* Check memory availability in shmem_file_setup? */
-			vm_flags |= VM_ACCOUNT;
-		} else if (vm_flags & VM_WRITE) {
-			/*
-			 * Private writable mapping: check memory availability
-			 */
-			charged = len >> PAGE_SHIFT;
-			if (security_vm_enough_memory(charged))
-				return -ENOMEM;
-			vm_flags |= VM_ACCOUNT;
-		}
+	/*
+	 * Private writable mapping: check memory availability
+	 */
+	if (private_accountable_mapping(vm_flags)) {
+		charged = len >> PAGE_SHIFT;
+		if (security_vm_enough_memory(charged))
+			return -ENOMEM;
+		vm_flags |= VM_ACCOUNT;
 	}
 
 	/*
@@ -1184,14 +1194,6 @@ munmap_back:
 			goto free_vma;
 	}
 
-	/* We set VM_ACCOUNT in a shared mapping's vm_flags, to inform
-	 * shmem_zero_setup (perhaps called through /dev/zero's ->mmap)
-	 * that memory reservation must be checked; but that reservation
-	 * belongs to shared memory object, not to vma: so now clear it.
-	 */
-	if ((vm_flags & (VM_SHARED|VM_ACCOUNT)) == (VM_SHARED|VM_ACCOUNT))
-		vma->vm_flags &= ~VM_ACCOUNT;
-
 	/* Can addr have changed??
 	 *
 	 * Answer: Yes, several device drivers can do it in their
diff --git a/mm/shmem.c b/mm/shmem.c
index 5d0de96..19d566c 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -2628,7 +2628,7 @@ struct file *shmem_file_setup(char *name, loff_t size, unsigned long flags)
 		goto close_file;
 
 #ifdef CONFIG_SHMEM
-	SHMEM_I(inode)->flags = flags & VM_ACCOUNT;
+	SHMEM_I(inode)->flags = (flags & VM_NORESERVE) ? 0 : VM_ACCOUNT;
 #endif
 	d_instantiate(dentry, inode);
 	inode->i_size = size;

  reply	other threads:[~2009-01-31 18:35 UTC|newest]

Thread overview: 47+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <bb4a86c70901281151w4300605r3882461cd6e9774a@mail.gmail.com>
     [not found] ` <alpine.LFD.2.00.0901281316450.3123@localhost.localdomain>
2009-01-29 20:03   ` Lee Schermerhorn
2009-01-29 20:33     ` Linus Torvalds
2009-01-29 20:48       ` Linus Torvalds
2009-01-29 22:32         ` Hugh Dickins
2009-01-29 23:02           ` Linus Torvalds
2009-01-30  4:43             ` Lee Schermerhorn
2009-01-30  4:49               ` Linus Torvalds
2009-01-29 22:47         ` Maksim Yevmenkin
2009-01-29 22:48           ` Randy Dunlap
2009-01-29 23:31             ` Maksim Yevmenkin
2009-01-30  2:08           ` Linus Torvalds
2009-01-30  5:56             ` Greg KH
2009-01-30 16:36               ` Linus Torvalds
2009-01-30 17:40                 ` Hugh Dickins
2009-01-30 18:14                   ` Linus Torvalds
2009-01-30 18:30                     ` Hugh Dickins
2009-01-30 19:53                     ` Lee Schermerhorn
2009-01-30 20:31                       ` Linus Torvalds
2009-01-30 21:12                         ` Hugh Dickins
2009-01-30 21:25                           ` Linus Torvalds
2009-01-30 21:36                           ` Lee Schermerhorn
2009-01-30 22:27                             ` Linus Torvalds
2009-01-31 12:35                               ` Hugh Dickins
2009-01-31 18:34                                 ` Linus Torvalds [this message]
2009-02-02 11:59                                   ` KOSAKI Motohiro
2009-02-02 12:54                                     ` Hugh Dickins
2009-02-02 14:10                                       ` KOSAKI Motohiro
2009-02-02 18:58                                         ` Mel Gorman
2009-02-02 19:23                                           ` Linus Torvalds
2009-02-02 21:50                                             ` Mel Gorman
2009-02-02 22:12                                               ` Linus Torvalds
2009-02-02 22:35                                                 ` Mel Gorman
2009-02-02 18:33                                       ` Mel Gorman
2009-02-03 16:13                                 ` Lee Schermerhorn
2009-02-03 16:40                                   ` Linus Torvalds
2009-02-03 17:10                                   ` Hugh Dickins
2009-02-03 21:50                                     ` Lee Schermerhorn
2009-01-30 21:37                           ` Linus Torvalds
2009-01-31 12:16                             ` Hugh Dickins
2009-01-30 20:33                       ` Hugh Dickins
2009-01-30 20:53                       ` Randy Dunlap
2009-01-30 20:59                         ` Lee Schermerhorn
2009-01-30 21:11                           ` Will Crowder
2009-01-30 23:44                   ` Greg KH
2009-01-30  8:34         ` Peter Zijlstra
2009-01-30 16:45           ` Linus Torvalds
2009-01-30 16:49             ` Randy Dunlap

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=alpine.LFD.2.00.0901311010460.3150@localhost.localdomain \
    --to=torvalds@linux-foundation.org \
    --cc=Lee.Schermerhorn@hp.com \
    --cc=akpm@linux-foundation.org \
    --cc=gregkh@suse.de \
    --cc=hugh@veritas.com \
    --cc=kamezawa.hiroyu@jp.fujitsu.com \
    --cc=kosaki.motohiro@jp.fujitsu.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=maksim.yevmenkin@gmail.com \
    --cc=miklos@szeredi.hu \
    --cc=npiggin@suse.de \
    --cc=riel@redhat.com \
    --cc=will@crowder-design.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

Powered by JetHome